258 lines
5.7 KiB
C
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 ;
|
|
}
|
|
|