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 and return handle */
157 if(NT_SUCCESS(Status
))
161 *EventHandle
= hEvent
;
163 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
165 Status
= _SEH_GetExceptionCode();
180 NtOpenEvent(OUT PHANDLE EventHandle
,
181 IN ACCESS_MASK DesiredAccess
,
182 IN POBJECT_ATTRIBUTES ObjectAttributes
)
185 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
186 NTSTATUS Status
= STATUS_SUCCESS
;
188 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n",
189 EventHandle
, DesiredAccess
, ObjectAttributes
);
191 /* Check if we were called from user-mode */
192 if(PreviousMode
!= KernelMode
)
194 /* Enter SEH Block */
197 /* Check handle pointer */
198 ProbeForWriteHandle(EventHandle
);
200 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
202 Status
= _SEH_GetExceptionCode();
206 /* Bail out if pointer was invalid */
207 if(!NT_SUCCESS(Status
)) return Status
;
210 /* Open the Object */
211 Status
= ObOpenObjectByName(ObjectAttributes
,
219 /* Check for success */
220 if(NT_SUCCESS(Status
))
222 /* Enter SEH for return */
225 /* Return the handle to the caller */
226 *EventHandle
= hEvent
;
228 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
230 Status
= _SEH_GetExceptionCode();
244 NtPulseEvent(IN HANDLE EventHandle
,
245 OUT PLONG PreviousState OPTIONAL
)
248 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
249 NTSTATUS Status
= STATUS_SUCCESS
;
251 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
252 EventHandle
, PreviousState
);
254 /* Check if we were called from user-mode */
255 if((PreviousState
) && (PreviousMode
!= KernelMode
))
257 /* Entry SEH Block */
260 /* Make sure the state pointer is valid */
261 ProbeForWriteLong(PreviousState
);
263 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
265 Status
= _SEH_GetExceptionCode();
269 /* Bail out if pointer was invalid */
270 if(!NT_SUCCESS(Status
)) return Status
;
273 /* Open the Object */
274 Status
= ObReferenceObjectByHandle(EventHandle
,
281 /* Check for success */
282 if(NT_SUCCESS(Status
))
284 /* Pulse the Event */
285 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
286 ObDereferenceObject(Event
);
288 /* Check if caller wants the old state back */
291 /* Entry SEH Block for return */
294 /* Return previous state */
295 *PreviousState
= Prev
;
297 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
299 Status
= _SEH_GetExceptionCode();
314 NtQueryEvent(IN HANDLE EventHandle
,
315 IN EVENT_INFORMATION_CLASS EventInformationClass
,
316 OUT PVOID EventInformation
,
317 IN ULONG EventInformationLength
,
318 OUT PULONG ReturnLength OPTIONAL
)
321 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
322 NTSTATUS Status
= STATUS_SUCCESS
;
323 PEVENT_BASIC_INFORMATION BasicInfo
= (PEVENT_BASIC_INFORMATION
)EventInformation
;
325 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle
, EventInformationClass
);
327 /* Check buffers and class validity */
328 Status
= DefaultQueryInfoBufferCheck(EventInformationClass
,
330 sizeof(ExEventInfoClass
) / sizeof(ExEventInfoClass
[0]),
332 EventInformationLength
,
335 if(!NT_SUCCESS(Status
))
337 /* Invalid buffers */
338 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
343 Status
= ObReferenceObjectByHandle(EventHandle
,
350 /* Check for success */
351 if(NT_SUCCESS(Status
))
353 /* Entry SEH Block */
356 /* Return Event Type and State */
357 BasicInfo
->EventType
= Event
->Header
.Type
;
358 BasicInfo
->EventState
= KeReadStateEvent(Event
);
361 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
363 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
365 Status
= _SEH_GetExceptionCode();
369 /* Dereference the Object */
370 ObDereferenceObject(Event
);
382 NtResetEvent(IN HANDLE EventHandle
,
383 OUT PLONG PreviousState OPTIONAL
)
386 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
387 NTSTATUS Status
= STATUS_SUCCESS
;
389 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
390 EventHandle
, PreviousState
);
392 /* Check if we were called from user-mode */
393 if((PreviousState
) && (PreviousMode
!= KernelMode
))
395 /* Entry SEH Block */
398 /* Make sure the state pointer is valid */
399 ProbeForWriteLong(PreviousState
);
401 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
403 Status
= _SEH_GetExceptionCode();
407 /* Bail out if pointer was invalid */
408 if(!NT_SUCCESS(Status
)) return Status
;
411 /* Open the Object */
412 Status
= ObReferenceObjectByHandle(EventHandle
,
419 /* Check for success */
420 if(NT_SUCCESS(Status
))
422 /* Reset the Event */
423 LONG Prev
= KeResetEvent(Event
);
424 ObDereferenceObject(Event
);
426 /* Check if caller wants the old state back */
429 /* Entry SEH Block for return */
432 /* Return previous state */
433 *PreviousState
= Prev
;
435 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
437 Status
= _SEH_GetExceptionCode();
452 NtSetEvent(IN HANDLE EventHandle
,
453 OUT PLONG PreviousState OPTIONAL
)
456 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
457 NTSTATUS Status
= STATUS_SUCCESS
;
459 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
460 EventHandle
, PreviousState
);
462 /* Check if we were called from user-mode */
463 if((PreviousState
) && (PreviousMode
!= KernelMode
))
465 /* Entry SEH Block */
468 /* Make sure the state pointer is valid */
469 ProbeForWriteLong(PreviousState
);
471 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
473 Status
= _SEH_GetExceptionCode();
477 /* Bail out if pointer was invalid */
478 if(!NT_SUCCESS(Status
)) return Status
;
481 /* Open the Object */
482 Status
= ObReferenceObjectByHandle(EventHandle
,
489 /* Check for success */
490 if(NT_SUCCESS(Status
))
493 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
494 ObDereferenceObject(Event
);
496 /* Check if caller wants the old state back */
499 /* Entry SEH Block for return */
502 /* Return previous state */
503 *PreviousState
= Prev
;
505 _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
)
507 Status
= _SEH_GetExceptionCode();