#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 ; }