Leaked source code of windows server 2003
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.

337 lines
7.0 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: w32kevnt.c
  3. *
  4. * Event handling functions
  5. *
  6. * Copyright (c) 1996-1999 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include "engine.h"
  10. #include "pw32kevt.h"
  11. /*
  12. * Object type exported from the kernel
  13. */
  14. extern POBJECT_TYPE *ExEventObjectType;
  15. BOOL
  16. EngCreateEvent(
  17. OUT PEVENT *ppEvent
  18. )
  19. /*+++
  20. Routine Description:
  21. EngCreateEvent creates a synchronization type event object that can
  22. be used to synchronize hardware access between a display driver and
  23. video miniport.
  24. ---*/
  25. {
  26. PENG_EVENT *ppEngEvent = (PENG_EVENT *)ppEvent;
  27. PENG_EVENT pEngEvent;
  28. PUCHAR pAllocTmp;
  29. ULONG engevtsize = sizeof(ENG_EVENT);
  30. //
  31. // Align size to next higher multiple of 8.
  32. //
  33. engevtsize = (engevtsize + 7) & ~7;
  34. //
  35. // Allocate the whole amount and set pEngEvent to the top.
  36. //
  37. pAllocTmp = (PUCHAR)ENG_KEVENTALLOC(engevtsize + sizeof(KEVENT));
  38. pEngEvent = (PENG_EVENT)pAllocTmp;
  39. if (pEngEvent) {
  40. RtlZeroMemory(pEngEvent, sizeof(ENG_EVENT));
  41. //
  42. // Skip past the ENG_EVENT and set pEngEvent->pKEvent to that.
  43. //
  44. pAllocTmp += engevtsize;
  45. pEngEvent->pKEvent = (PKEVENT)pAllocTmp;
  46. //
  47. // Initialize the KEVENT and then put the PENG_EVENT in the
  48. // PPENG_EVENT.
  49. //
  50. KeInitializeEvent(pEngEvent->pKEvent, SynchronizationEvent, FALSE);
  51. *ppEngEvent = pEngEvent;
  52. } else {
  53. return FALSE;
  54. }
  55. return TRUE;
  56. }
  57. BOOL
  58. EngDeleteEvent(
  59. IN PEVENT pEvent
  60. )
  61. /*+++
  62. Routine Description:
  63. EngDeleteEvent deletes the specified event object.
  64. ---*/
  65. {
  66. PENG_EVENT pEngEvent = (PENG_EVENT)pEvent;
  67. if ( !(pEngEvent->fFlags & ENG_EVENT_FLAG_IS_MAPPED_USER)) {
  68. ENG_KEVENTFREE(pEngEvent);
  69. return TRUE;
  70. } else {
  71. ASSERTGDI(FALSE, "Don't delete MappedUserEvents");
  72. return FALSE;
  73. }
  74. }
  75. PEVENT
  76. EngMapEvent(
  77. IN HDEV hDev,
  78. IN HANDLE hUserObject,
  79. IN PVOID Reserved1,
  80. IN PVOID Reserved2,
  81. IN PVOID Reserved3
  82. )
  83. /*+++
  84. Routine Description:
  85. This routine allocates a ENG_EVENT and initialize its pKEvent pointer
  86. to the event object returned from Object manager.
  87. The reserved fields must be set to NULL
  88. ---*/
  89. {
  90. LONG status;
  91. PENG_EVENT pEngEvent;
  92. //
  93. // Allocate a pEngEvent, but don't allocate the PKEvent that
  94. // resides within this is done by ObReferenceObjectByHandle().
  95. //
  96. pEngEvent = ENG_KEVENTALLOC(sizeof(ENG_EVENT));
  97. if (!pEngEvent) {
  98. return NULL;
  99. }
  100. RtlZeroMemory(pEngEvent, sizeof(ENG_EVENT));
  101. //
  102. // Create the reference to the HANDLE
  103. // The ObRef call allocates and puts a PKEVENT object at
  104. // the location pointed to by pEngEvent.
  105. //
  106. status = ObReferenceObjectByHandle( hUserObject,
  107. EVENT_ALL_ACCESS,
  108. *ExEventObjectType,
  109. UserMode,
  110. (PVOID)&(pEngEvent->pKEvent),
  111. NULL);
  112. //
  113. // If the reference was successful, then pulse the event object.
  114. //
  115. // KePulseEvent atomically sets the signal state of an event object
  116. // to Signaled, attempts to satisfy as many Waits as possible, and
  117. // then resets the signal state of the event object to Not-Signaled.
  118. // The previous signalstate of the event object is returned as the
  119. // function value.
  120. //
  121. if (NT_SUCCESS(status)) {
  122. KePulseEvent(pEngEvent->pKEvent, EVENT_INCREMENT, FALSE);
  123. pEngEvent->fFlags |= ENG_EVENT_FLAG_IS_MAPPED_USER;
  124. } else {
  125. ENG_KEVENTFREE(pEngEvent);
  126. pEngEvent = NULL;
  127. }
  128. //
  129. // If the caller is using the old prototype of EngMapEvent, we should
  130. // return the pointer of kernel event to the place pointed by the third
  131. // argument.
  132. //
  133. if ( Reserved1 != NULL ) {
  134. *(PENG_EVENT *)Reserved1 = pEngEvent;
  135. }
  136. return (PEVENT) pEngEvent;
  137. }
  138. BOOL
  139. EngUnmapEvent(
  140. IN PEVENT pEvent
  141. )
  142. /*+++
  143. Routine Description:
  144. EngUnmapEvent cleans up the kernel-mode resources allocated for a
  145. mapped user-mode event.
  146. ---*/
  147. {
  148. PENG_EVENT pEngEvent = (PENG_EVENT)pEvent;
  149. if ( pEngEvent->fFlags & ENG_EVENT_FLAG_IS_MAPPED_USER ) {
  150. //
  151. // Decrements the object's reference count free the all the memory
  152. //
  153. ObDereferenceObject(pEngEvent->pKEvent);
  154. ENG_KEVENTFREE(pEngEvent);
  155. return TRUE;
  156. } else {
  157. return FALSE;
  158. }
  159. }
  160. BOOL
  161. EngWaitForSingleObject(
  162. IN PEVENT pEvent,
  163. IN PLARGE_INTEGER pTimeOut
  164. )
  165. /*+++
  166. Routine Description:
  167. Called by Display driver. Can only be called on events created by
  168. the Display or miniport driver, not on mapped events.
  169. Return Value:
  170. TRUE if successful, FALSE otherwise. A return value of FALSE indicates
  171. that either one of the parameters is invalid or a time-out occurred.
  172. ---*/
  173. {
  174. PENG_EVENT pEngEvent = (PENG_EVENT)pEvent;
  175. PKEVENT pKEvent;
  176. NTSTATUS Status;
  177. pKEvent = pEngEvent->pKEvent;
  178. //
  179. // Don't even wait if it's mapped user. In fact, don't wait if it's
  180. // invalid.
  181. //
  182. if (pKEvent && (!(pEngEvent->fFlags & ENG_EVENT_FLAG_IS_MAPPED_USER))) {
  183. Status = KeWaitForSingleObject( pKEvent,
  184. Executive,
  185. KernelMode,
  186. FALSE,
  187. pTimeOut );
  188. } else {
  189. ASSERTGDI(FALSE, "No waiting on mapped user events.");
  190. return FALSE;
  191. }
  192. if (NT_SUCCESS(Status))
  193. return TRUE;
  194. else
  195. return FALSE;
  196. }
  197. LONG
  198. EngSetEvent(
  199. IN PEVENT pEvent
  200. )
  201. /*+++
  202. Routine Description:
  203. EngSetEvent sets the state of the event object to signaled and returns
  204. the previous state of the event object
  205. ---*/
  206. {
  207. PENG_EVENT pEngEvent = (PENG_EVENT)pEvent;
  208. return ( KeSetEvent(pEngEvent->pKEvent, 0, FALSE) );
  209. }
  210. VOID
  211. EngClearEvent (
  212. IN PEVENT pEvent
  213. )
  214. /*+++
  215. Routine Description:
  216. EngClearEvent sets the given event to a not signaled state.
  217. ---*/
  218. {
  219. PENG_EVENT pEngEvent = (PENG_EVENT)pEvent;
  220. KeClearEvent(pEngEvent->pKEvent);
  221. }
  222. LONG
  223. EngReadStateEvent (
  224. IN PEVENT pEvent
  225. )
  226. /*+++
  227. Routine Description:
  228. EngReadStateEvent returns the current state, signaled or not signaled,
  229. of a given event object.
  230. ---*/
  231. {
  232. PENG_EVENT pEngEvent = (PENG_EVENT)pEvent;
  233. return ( KeReadStateEvent(pEngEvent->pKEvent) );
  234. }