Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
5.7 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /*++
  4. Copyright (c) 1992 Microsoft Corporation
  5. Module Name:
  6. event.c
  7. Abstract:
  8. Routines related to event manipulation.
  9. Author:
  10. Sunil Pai (sunilp) 26-May-1992
  11. Revision History:
  12. --*/
  13. extern BOOL FYield(VOID);
  14. #define EVENT_SIGNALLED "EventSignalled"
  15. #define EVENT_NOT_FOUND "EventNotFound"
  16. #define EVENT_SET "EventSet"
  17. #define EVENT_NOT_SET "EventNotSet"
  18. #define EVENT_TIMEOUT "EventTimeout"
  19. #define EVENT_FAILED "EventFailed"
  20. #define EVENT_NO_FAIL "EventNoFailEvent"
  21. #define EVENT_NAME_SETUP_FAILED "\\SETUP_FAILED"
  22. HANDLE
  23. FOpenOrCreateEvent(
  24. IN LPSTR EventNameAscii,
  25. BOOL bCreateAllowed
  26. )
  27. /*
  28. Open or create an event; return a handle to the event.
  29. */
  30. {
  31. HANDLE EventHandle;
  32. OBJECT_ATTRIBUTES EventAttributes;
  33. UNICODE_STRING EventName;
  34. NTSTATUS NtStatus;
  35. ANSI_STRING EventName_A;
  36. RtlInitAnsiString( & EventName_A, EventNameAscii );
  37. NtStatus = RtlAnsiStringToUnicodeString(
  38. &EventName,
  39. &EventName_A,
  40. TRUE
  41. );
  42. if ( ! NT_SUCCESS(NtStatus) )
  43. return NULL ;
  44. InitializeObjectAttributes( & EventAttributes, & EventName, 0, 0, NULL );
  45. // First try to open the event; if failure, create it.
  46. NtStatus = NtOpenEvent(
  47. &EventHandle,
  48. SYNCHRONIZE | EVENT_MODIFY_STATE,
  49. &EventAttributes
  50. );
  51. if ( (! NT_SUCCESS( NtStatus )) && bCreateAllowed )
  52. {
  53. NtStatus = NtCreateEvent(
  54. &EventHandle,
  55. SYNCHRONIZE | EVENT_MODIFY_STATE,
  56. &EventAttributes,
  57. NotificationEvent,
  58. FALSE // The event is initially not signaled
  59. );
  60. }
  61. RtlFreeUnicodeString( & EventName );
  62. return NT_SUCCESS( NtStatus )
  63. ? EventHandle
  64. : NULL ;
  65. }
  66. //
  67. // Number of milliseconds we will wait before yielding.
  68. //
  69. // The value below is 10 ms expressed as a relative NT time.
  70. //
  71. #define TIME_SLICE (-100000)
  72. VOID
  73. WaitForEventOrFailure(
  74. IN LPSTR EventName,
  75. IN BOOL WaitForFailureAlso,
  76. IN DWORD Timeout,
  77. IN LPSTR InfVar
  78. )
  79. {
  80. SZ EventStatus;
  81. HANDLE EventHandles[2];
  82. TIME timeSlice;
  83. LARGE_INTEGER timeRemaining;
  84. NTSTATUS NtStatus;
  85. //
  86. // Create a local variable containing the timeslice value
  87. // (ie, max wait time before a yield and rewait).
  88. //
  89. timeSlice.QuadPart = (LONGLONG)TIME_SLICE;
  90. if(EventHandles[0] = FOpenOrCreateEvent(EventName,FALSE)) {
  91. if(!WaitForFailureAlso || (EventHandles[1] = FOpenOrCreateEvent(EVENT_NAME_SETUP_FAILED,TRUE))) {
  92. //
  93. // If the timeout passed by the caller is 0, then we want to keep waiting
  94. // until one of the events becomes signalled.
  95. //
  96. // The multiplication of the caller's supplied Timeout value by -10000
  97. // converts milliseconds to a relative NT time.
  98. //
  99. for(timeRemaining.QuadPart = Int32x32To64(Timeout,-10000);
  100. !Timeout || (timeRemaining.QuadPart < 0);
  101. timeRemaining.QuadPart -= timeSlice.QuadPart)
  102. {
  103. NtStatus = NtWaitForMultipleObjects(
  104. WaitForFailureAlso ? 2 : 1,
  105. EventHandles,
  106. WaitAny,
  107. TRUE,
  108. &timeSlice
  109. );
  110. if(NtStatus != STATUS_TIMEOUT) {
  111. break;
  112. }
  113. FYield();
  114. }
  115. switch(NtStatus) {
  116. case STATUS_TIMEOUT:
  117. EventStatus = EVENT_TIMEOUT;
  118. break;
  119. case STATUS_WAIT_0:
  120. EventStatus = EVENT_SET;
  121. break;
  122. case STATUS_WAIT_1:
  123. default:
  124. EventStatus = EVENT_FAILED;
  125. break;
  126. }
  127. if(WaitForFailureAlso) {
  128. NtClose(EventHandles[1]);
  129. }
  130. } else {
  131. EventStatus = EVENT_NO_FAIL;
  132. }
  133. NtClose(EventHandles[0]);
  134. } else {
  135. EventStatus = EVENT_NOT_FOUND;
  136. }
  137. FAddSymbolValueToSymTab(InfVar,EventStatus);
  138. }
  139. BOOL
  140. FWaitForEventOrFailure(
  141. IN LPSTR InfVar,
  142. IN LPSTR Event,
  143. IN DWORD Timeout
  144. )
  145. {
  146. WaitForEventOrFailure(Event,TRUE,Timeout,InfVar);
  147. return TRUE;
  148. }
  149. BOOL
  150. FWaitForEvent(
  151. IN LPSTR InfVar,
  152. IN LPSTR Event,
  153. IN DWORD Timeout
  154. )
  155. {
  156. WaitForEventOrFailure(Event,FALSE,Timeout,InfVar);
  157. return TRUE;
  158. }
  159. // Never allow a "Sleep" command of greater than a minute.
  160. #define SLEEP_MS_MAXIMUM (60000)
  161. #define SLEEP_MS_INTERVAL (10)
  162. BOOL FSleep(
  163. DWORD dwMilliseconds
  164. )
  165. {
  166. DWORD dwCycles;
  167. if(dwMilliseconds > SLEEP_MS_MAXIMUM) {
  168. dwMilliseconds = SLEEP_MS_MAXIMUM;
  169. }
  170. for(dwCycles = dwMilliseconds/SLEEP_MS_INTERVAL; dwCycles--; ) {
  171. Sleep(SLEEP_MS_INTERVAL);
  172. FYield();
  173. }
  174. return TRUE;
  175. }
  176. BOOL
  177. FSignalEvent(
  178. IN LPSTR InfVar,
  179. IN LPSTR Event
  180. )
  181. {
  182. SZ EventStatus = EVENT_SIGNALLED;
  183. HANDLE EventHandle;
  184. //
  185. // Open the event
  186. //
  187. EventHandle = FOpenOrCreateEvent( Event, FALSE ) ;
  188. if ( EventHandle == NULL )
  189. {
  190. EventStatus = EVENT_NOT_FOUND;
  191. }
  192. else
  193. {
  194. if ( ! NT_SUCCESS( NtSetEvent( EventHandle, NULL ) ) )
  195. EventStatus = EVENT_NOT_SET ;
  196. NtClose( EventHandle );
  197. }
  198. FAddSymbolValueToSymTab(InfVar, EventStatus);
  199. return TRUE ;
  200. }