windows-nt/Source/XPSP1/NT/base/ntsetup/legacy/dll/event.c
2020-09-26 16:20:57 +08:00

258 lines
5.7 KiB
C

#include "precomp.h"
#pragma hdrstop
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
event.c
Abstract:
Routines related to event manipulation.
Author:
Sunil Pai (sunilp) 26-May-1992
Revision History:
--*/
extern BOOL FYield(VOID);
#define EVENT_SIGNALLED "EventSignalled"
#define EVENT_NOT_FOUND "EventNotFound"
#define EVENT_SET "EventSet"
#define EVENT_NOT_SET "EventNotSet"
#define EVENT_TIMEOUT "EventTimeout"
#define EVENT_FAILED "EventFailed"
#define EVENT_NO_FAIL "EventNoFailEvent"
#define EVENT_NAME_SETUP_FAILED "\\SETUP_FAILED"
HANDLE
FOpenOrCreateEvent(
IN LPSTR EventNameAscii,
BOOL bCreateAllowed
)
/*
Open or create an event; return a handle to the event.
*/
{
HANDLE EventHandle;
OBJECT_ATTRIBUTES EventAttributes;
UNICODE_STRING EventName;
NTSTATUS NtStatus;
ANSI_STRING EventName_A;
RtlInitAnsiString( & EventName_A, EventNameAscii );
NtStatus = RtlAnsiStringToUnicodeString(
&EventName,
&EventName_A,
TRUE
);
if ( ! NT_SUCCESS(NtStatus) )
return NULL ;
InitializeObjectAttributes( & EventAttributes, & EventName, 0, 0, NULL );
// First try to open the event; if failure, create it.
NtStatus = NtOpenEvent(
&EventHandle,
SYNCHRONIZE | EVENT_MODIFY_STATE,
&EventAttributes
);
if ( (! NT_SUCCESS( NtStatus )) && bCreateAllowed )
{
NtStatus = NtCreateEvent(
&EventHandle,
SYNCHRONIZE | EVENT_MODIFY_STATE,
&EventAttributes,
NotificationEvent,
FALSE // The event is initially not signaled
);
}
RtlFreeUnicodeString( & EventName );
return NT_SUCCESS( NtStatus )
? EventHandle
: NULL ;
}
//
// Number of milliseconds we will wait before yielding.
//
// The value below is 10 ms expressed as a relative NT time.
//
#define TIME_SLICE (-100000)
VOID
WaitForEventOrFailure(
IN LPSTR EventName,
IN BOOL WaitForFailureAlso,
IN DWORD Timeout,
IN LPSTR InfVar
)
{
SZ EventStatus;
HANDLE EventHandles[2];
TIME timeSlice;
LARGE_INTEGER timeRemaining;
NTSTATUS NtStatus;
//
// Create a local variable containing the timeslice value
// (ie, max wait time before a yield and rewait).
//
timeSlice.QuadPart = (LONGLONG)TIME_SLICE;
if(EventHandles[0] = FOpenOrCreateEvent(EventName,FALSE)) {
if(!WaitForFailureAlso || (EventHandles[1] = FOpenOrCreateEvent(EVENT_NAME_SETUP_FAILED,TRUE))) {
//
// If the timeout passed by the caller is 0, then we want to keep waiting
// until one of the events becomes signalled.
//
// The multiplication of the caller's supplied Timeout value by -10000
// converts milliseconds to a relative NT time.
//
for(timeRemaining.QuadPart = Int32x32To64(Timeout,-10000);
!Timeout || (timeRemaining.QuadPart < 0);
timeRemaining.QuadPart -= timeSlice.QuadPart)
{
NtStatus = NtWaitForMultipleObjects(
WaitForFailureAlso ? 2 : 1,
EventHandles,
WaitAny,
TRUE,
&timeSlice
);
if(NtStatus != STATUS_TIMEOUT) {
break;
}
FYield();
}
switch(NtStatus) {
case STATUS_TIMEOUT:
EventStatus = EVENT_TIMEOUT;
break;
case STATUS_WAIT_0:
EventStatus = EVENT_SET;
break;
case STATUS_WAIT_1:
default:
EventStatus = EVENT_FAILED;
break;
}
if(WaitForFailureAlso) {
NtClose(EventHandles[1]);
}
} else {
EventStatus = EVENT_NO_FAIL;
}
NtClose(EventHandles[0]);
} else {
EventStatus = EVENT_NOT_FOUND;
}
FAddSymbolValueToSymTab(InfVar,EventStatus);
}
BOOL
FWaitForEventOrFailure(
IN LPSTR InfVar,
IN LPSTR Event,
IN DWORD Timeout
)
{
WaitForEventOrFailure(Event,TRUE,Timeout,InfVar);
return TRUE;
}
BOOL
FWaitForEvent(
IN LPSTR InfVar,
IN LPSTR Event,
IN DWORD Timeout
)
{
WaitForEventOrFailure(Event,FALSE,Timeout,InfVar);
return TRUE;
}
// Never allow a "Sleep" command of greater than a minute.
#define SLEEP_MS_MAXIMUM (60000)
#define SLEEP_MS_INTERVAL (10)
BOOL FSleep(
DWORD dwMilliseconds
)
{
DWORD dwCycles;
if(dwMilliseconds > SLEEP_MS_MAXIMUM) {
dwMilliseconds = SLEEP_MS_MAXIMUM;
}
for(dwCycles = dwMilliseconds/SLEEP_MS_INTERVAL; dwCycles--; ) {
Sleep(SLEEP_MS_INTERVAL);
FYield();
}
return TRUE;
}
BOOL
FSignalEvent(
IN LPSTR InfVar,
IN LPSTR Event
)
{
SZ EventStatus = EVENT_SIGNALLED;
HANDLE EventHandle;
//
// Open the event
//
EventHandle = FOpenOrCreateEvent( Event, FALSE ) ;
if ( EventHandle == NULL )
{
EventStatus = EVENT_NOT_FOUND;
}
else
{
if ( ! NT_SUCCESS( NtSetEvent( EventHandle, NULL ) ) )
EventStatus = EVENT_NOT_SET ;
NtClose( EventHandle );
}
FAddSymbolValueToSymTab(InfVar, EventStatus);
return TRUE ;
}