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 *****************************************************************/
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 ObCreateObjectType(&Name
, &ObjectTypeInitializer
, NULL
, &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 _SEH2_EXCEPT(ExSystemExceptionFilter())
120 Status
= _SEH2_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
,
155 /* Check for success */
156 if(NT_SUCCESS(Status
))
158 /* Enter SEH for return */
161 /* Return the handle to the caller */
162 *EventHandle
= hEvent
;
164 _SEH2_EXCEPT(ExSystemExceptionFilter())
166 Status
= _SEH2_GetExceptionCode();
181 NtOpenEvent(OUT PHANDLE EventHandle
,
182 IN ACCESS_MASK DesiredAccess
,
183 IN POBJECT_ATTRIBUTES ObjectAttributes
)
186 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
187 NTSTATUS Status
= STATUS_SUCCESS
;
189 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n",
190 EventHandle
, DesiredAccess
, ObjectAttributes
);
192 /* Check if we were called from user-mode */
193 if(PreviousMode
!= KernelMode
)
195 /* Enter SEH Block */
198 /* Check handle pointer */
199 ProbeForWriteHandle(EventHandle
);
201 _SEH2_EXCEPT(ExSystemExceptionFilter())
203 Status
= _SEH2_GetExceptionCode();
207 /* Bail out if pointer was invalid */
208 if(!NT_SUCCESS(Status
)) return Status
;
211 /* Open the Object */
212 Status
= ObOpenObjectByName(ObjectAttributes
,
220 /* Check for success */
221 if(NT_SUCCESS(Status
))
223 /* Enter SEH for return */
226 /* Return the handle to the caller */
227 *EventHandle
= hEvent
;
229 _SEH2_EXCEPT(ExSystemExceptionFilter())
231 Status
= _SEH2_GetExceptionCode();
245 NtPulseEvent(IN HANDLE EventHandle
,
246 OUT PLONG PreviousState OPTIONAL
)
249 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
250 NTSTATUS Status
= STATUS_SUCCESS
;
252 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
253 EventHandle
, PreviousState
);
255 /* Check if we were called from user-mode */
256 if((PreviousState
) && (PreviousMode
!= KernelMode
))
258 /* Entry SEH Block */
261 /* Make sure the state pointer is valid */
262 ProbeForWriteLong(PreviousState
);
264 _SEH2_EXCEPT(ExSystemExceptionFilter())
266 Status
= _SEH2_GetExceptionCode();
270 /* Bail out if pointer was invalid */
271 if(!NT_SUCCESS(Status
)) return Status
;
274 /* Open the Object */
275 Status
= ObReferenceObjectByHandle(EventHandle
,
282 /* Check for success */
283 if(NT_SUCCESS(Status
))
285 /* Pulse the Event */
286 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
287 ObDereferenceObject(Event
);
289 /* Check if caller wants the old state back */
292 /* Entry SEH Block for return */
295 /* Return previous state */
296 *PreviousState
= Prev
;
298 _SEH2_EXCEPT(ExSystemExceptionFilter())
300 Status
= _SEH2_GetExceptionCode();
315 NtQueryEvent(IN HANDLE EventHandle
,
316 IN EVENT_INFORMATION_CLASS EventInformationClass
,
317 OUT PVOID EventInformation
,
318 IN ULONG EventInformationLength
,
319 OUT PULONG ReturnLength OPTIONAL
)
322 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
323 NTSTATUS Status
= STATUS_SUCCESS
;
324 PEVENT_BASIC_INFORMATION BasicInfo
=
325 (PEVENT_BASIC_INFORMATION
)EventInformation
;
327 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle
, EventInformationClass
);
329 /* Check buffers and class validity */
330 Status
= DefaultQueryInfoBufferCheck(EventInformationClass
,
332 sizeof(ExEventInfoClass
) /
333 sizeof(ExEventInfoClass
[0]),
335 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 _SEH2_EXCEPT(ExSystemExceptionFilter())
369 Status
= _SEH2_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 _SEH2_EXCEPT(ExSystemExceptionFilter())
407 Status
= _SEH2_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 _SEH2_EXCEPT(ExSystemExceptionFilter())
441 Status
= _SEH2_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 _SEH2_EXCEPT(ExSystemExceptionFilter())
477 Status
= _SEH2_GetExceptionCode();
481 /* Bail out if pointer was invalid */
482 if(!NT_SUCCESS(Status
)) return Status
;
485 /* Open the Object */
486 Status
= ObReferenceObjectByHandle(EventHandle
,
492 if (NT_SUCCESS(Status
))
495 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
496 ObDereferenceObject(Event
);
498 /* Check if caller wants the old state back */
501 /* Entry SEH Block for return */
504 /* Return previous state */
505 *PreviousState
= Prev
;
507 _SEH2_EXCEPT(ExSystemExceptionFilter())
509 Status
= _SEH2_GetExceptionCode();
524 NtSetEventBoostPriority(IN HANDLE EventHandle
)
530 /* Open the Object */
531 Status
= ObReferenceObjectByHandle(EventHandle
,
537 if (NT_SUCCESS(Status
))
540 KeSetEventBoostPriority(Event
, NULL
);
541 ObDereferenceObject(Event
);