2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/ex/event.c
5 * PURPOSE: Event support
6 * PROGRAMMERS: Alex Ionescu(alex@relsoft.net)
10 /* INCLUDES *****************************************************************/
14 #include <internal/debug.h>
16 #if defined (ALLOC_PRAGMA)
17 #pragma alloc_text(INIT, ExpInitializeEventImplementation)
20 /* GLOBALS *******************************************************************/
22 POBJECT_TYPE ExEventObjectType
= NULL
;
24 GENERIC_MAPPING ExpEventMapping
=
26 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| EVENT_QUERY_STATE
,
27 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
| EVENT_MODIFY_STATE
,
28 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| EVENT_QUERY_STATE
,
31 static const INFORMATION_CLASS_INFO ExEventInfoClass
[] =
33 /* EventBasicInformation */
34 ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
),
37 /* FUNCTIONS *****************************************************************/
42 ExpInitializeEventImplementation(VOID
)
44 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
46 DPRINT("Creating Event Object Type\n");
48 /* Create the Event Object Type */
49 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
50 RtlInitUnicodeString(&Name
, L
"Event");
51 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
52 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(KEVENT
);
53 ObjectTypeInitializer
.GenericMapping
= ExpEventMapping
;
54 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
55 ObjectTypeInitializer
.ValidAccessMask
= EVENT_ALL_ACCESS
;
56 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &ExEventObjectType
);
64 NtClearEvent(IN HANDLE EventHandle
)
70 /* Reference the Object */
71 Status
= ObReferenceObjectByHandle(EventHandle
,
78 /* Check for Success */
79 if(NT_SUCCESS(Status
))
81 /* Clear the Event and Dereference */
83 ObDereferenceObject(Event
);
95 NtCreateEvent(OUT PHANDLE EventHandle
,
96 IN ACCESS_MASK DesiredAccess
,
97 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
98 IN EVENT_TYPE EventType
,
99 IN BOOLEAN InitialState
)
101 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
104 NTSTATUS Status
= STATUS_SUCCESS
;
106 DPRINT("NtCreateEvent(0x%p, 0x%x, 0x%p)\n",
107 EventHandle
, DesiredAccess
, ObjectAttributes
);
109 /* Check if we were called from user-mode */
110 if(PreviousMode
!= KernelMode
)
112 /* Enter SEH Block */
115 /* Check handle pointer */
116 ProbeForWriteHandle(EventHandle
);
118 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
120 Status
= _SEH_GetExceptionCode();
124 /* Bail out if pointer was invalid */
125 if(!NT_SUCCESS(Status
)) return Status
;
128 /* Create the Object */
129 Status
= ObCreateObject(PreviousMode
,
139 /* Check for Success */
140 if(NT_SUCCESS(Status
))
142 /* Initalize the Event */
143 KeInitializeEvent(Event
,
148 Status
= ObInsertObject((PVOID
)Event
,
154 ObDereferenceObject(Event
);
156 /* Check for success */
157 if(NT_SUCCESS(Status
))
159 /* Enter SEH for return */
162 /* Return the handle to the caller */
163 *EventHandle
= hEvent
;
165 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
167 Status
= _SEH_GetExceptionCode();
182 NtOpenEvent(OUT PHANDLE EventHandle
,
183 IN ACCESS_MASK DesiredAccess
,
184 IN POBJECT_ATTRIBUTES ObjectAttributes
)
187 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
188 NTSTATUS Status
= STATUS_SUCCESS
;
190 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n",
191 EventHandle
, DesiredAccess
, ObjectAttributes
);
193 /* Check if we were called from user-mode */
194 if(PreviousMode
!= KernelMode
)
196 /* Enter SEH Block */
199 /* Check handle pointer */
200 ProbeForWriteHandle(EventHandle
);
202 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
204 Status
= _SEH_GetExceptionCode();
208 /* Bail out if pointer was invalid */
209 if(!NT_SUCCESS(Status
)) return Status
;
212 /* Open the Object */
213 Status
= ObOpenObjectByName(ObjectAttributes
,
221 /* Check for success */
222 if(NT_SUCCESS(Status
))
224 /* Enter SEH for return */
227 /* Return the handle to the caller */
228 *EventHandle
= hEvent
;
230 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
232 Status
= _SEH_GetExceptionCode();
246 NtPulseEvent(IN HANDLE EventHandle
,
247 OUT PLONG PreviousState OPTIONAL
)
250 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
251 NTSTATUS Status
= STATUS_SUCCESS
;
253 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
254 EventHandle
, PreviousState
);
256 /* Check if we were called from user-mode */
257 if((PreviousState
) && (PreviousMode
!= KernelMode
))
259 /* Entry SEH Block */
262 /* Make sure the state pointer is valid */
263 ProbeForWriteLong(PreviousState
);
265 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
267 Status
= _SEH_GetExceptionCode();
271 /* Bail out if pointer was invalid */
272 if(!NT_SUCCESS(Status
)) return Status
;
275 /* Open the Object */
276 Status
= ObReferenceObjectByHandle(EventHandle
,
283 /* Check for success */
284 if(NT_SUCCESS(Status
))
286 /* Pulse the Event */
287 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
288 ObDereferenceObject(Event
);
290 /* Check if caller wants the old state back */
293 /* Entry SEH Block for return */
296 /* Return previous state */
297 *PreviousState
= Prev
;
299 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
301 Status
= _SEH_GetExceptionCode();
316 NtQueryEvent(IN HANDLE EventHandle
,
317 IN EVENT_INFORMATION_CLASS EventInformationClass
,
318 OUT PVOID EventInformation
,
319 IN ULONG EventInformationLength
,
320 OUT PULONG ReturnLength OPTIONAL
)
323 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
324 NTSTATUS Status
= STATUS_SUCCESS
;
325 PEVENT_BASIC_INFORMATION BasicInfo
=
326 (PEVENT_BASIC_INFORMATION
)EventInformation
;
328 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle
, EventInformationClass
);
330 /* Check buffers and class validity */
331 Status
= DefaultQueryInfoBufferCheck(EventInformationClass
,
333 sizeof(ExEventInfoClass
) /
334 sizeof(ExEventInfoClass
[0]),
336 EventInformationLength
,
339 if(!NT_SUCCESS(Status
))
341 /* Invalid buffers */
342 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
347 Status
= ObReferenceObjectByHandle(EventHandle
,
354 /* Check for success */
355 if(NT_SUCCESS(Status
))
357 /* Entry SEH Block */
360 /* Return Event Type and State */
361 BasicInfo
->EventType
= Event
->Header
.Type
;
362 BasicInfo
->EventState
= KeReadStateEvent(Event
);
365 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
367 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
369 Status
= _SEH_GetExceptionCode();
373 /* Dereference the Object */
374 ObDereferenceObject(Event
);
386 NtResetEvent(IN HANDLE EventHandle
,
387 OUT PLONG PreviousState OPTIONAL
)
390 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
391 NTSTATUS Status
= STATUS_SUCCESS
;
393 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
394 EventHandle
, PreviousState
);
396 /* Check if we were called from user-mode */
397 if((PreviousState
) && (PreviousMode
!= KernelMode
))
399 /* Entry SEH Block */
402 /* Make sure the state pointer is valid */
403 ProbeForWriteLong(PreviousState
);
405 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
407 Status
= _SEH_GetExceptionCode();
411 /* Bail out if pointer was invalid */
412 if(!NT_SUCCESS(Status
)) return Status
;
415 /* Open the Object */
416 Status
= ObReferenceObjectByHandle(EventHandle
,
423 /* Check for success */
424 if(NT_SUCCESS(Status
))
426 /* Reset the Event */
427 LONG Prev
= KeResetEvent(Event
);
428 ObDereferenceObject(Event
);
430 /* Check if caller wants the old state back */
433 /* Entry SEH Block for return */
436 /* Return previous state */
437 *PreviousState
= Prev
;
439 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
441 Status
= _SEH_GetExceptionCode();
456 NtSetEvent(IN HANDLE EventHandle
,
457 OUT PLONG PreviousState OPTIONAL
)
460 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
461 NTSTATUS Status
= STATUS_SUCCESS
;
463 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
464 EventHandle
, PreviousState
);
466 /* Check if we were called from user-mode */
467 if((PreviousState
) && (PreviousMode
!= KernelMode
))
469 /* Entry SEH Block */
472 /* Make sure the state pointer is valid */
473 ProbeForWriteLong(PreviousState
);
475 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
477 Status
= _SEH_GetExceptionCode();
481 /* Bail out if pointer was invalid */
482 if(!NT_SUCCESS(Status
)) return Status
;
485 /* Open the Object */
486 Status
= ObReferenceObjectByHandle(EventHandle
,
493 /* Check for success */
494 if(NT_SUCCESS(Status
))
497 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
498 ObDereferenceObject(Event
);
500 /* Check if caller wants the old state back */
503 /* Entry SEH Block for return */
506 /* Return previous state */
507 *PreviousState
= Prev
;
509 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
511 Status
= _SEH_GetExceptionCode();