2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/nt/event.c
5 * PURPOSE: Named event support
7 * PROGRAMMERS: Alex Ionescu(alex@relsoft.net) - Fixed bugs/commented
8 * Philip Susi and David Welch
11 /* INCLUDES *****************************************************************/
15 #include <internal/debug.h>
17 /* GLOBALS *******************************************************************/
19 POBJECT_TYPE ExEventObjectType
= NULL
;
21 static GENERIC_MAPPING ExpEventMapping
= {
22 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| EVENT_QUERY_STATE
,
23 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
| EVENT_MODIFY_STATE
,
24 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| EVENT_QUERY_STATE
,
27 static const INFORMATION_CLASS_INFO ExEventInfoClass
[] = {
29 /* EventBasicInformation */
30 ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION
), sizeof(ULONG
), ICIF_QUERY
),
33 /* FUNCTIONS *****************************************************************/
38 ExpInitializeEventImplementation(VOID
)
40 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
;
43 DPRINT("Creating Event Object Type\n");
45 /* Create the Event Object Type */
46 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
47 RtlInitUnicodeString(&Name
, L
"Event");
48 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
49 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(KEVENT
);
50 ObjectTypeInitializer
.GenericMapping
= ExpEventMapping
;
51 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
52 ObjectTypeInitializer
.ValidAccessMask
= EVENT_ALL_ACCESS
;
53 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &ExEventObjectType
);
61 NtClearEvent(IN HANDLE EventHandle
)
68 /* Reference the Object */
69 Status
= ObReferenceObjectByHandle(EventHandle
,
76 /* Check for Success */
77 if(NT_SUCCESS(Status
)) {
79 /* Clear the Event and Dereference */
81 ObDereferenceObject(Event
);
94 NtCreateEvent(OUT PHANDLE EventHandle
,
95 IN ACCESS_MASK DesiredAccess
,
96 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
97 IN EVENT_TYPE EventType
,
98 IN BOOLEAN InitialState
)
100 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
103 NTSTATUS Status
= STATUS_SUCCESS
;
106 DPRINT("NtCreateEvent(0x%p, 0x%x, 0x%p)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
108 /* Check Output Safety */
109 if(PreviousMode
!= KernelMode
) {
113 ProbeForWriteHandle(EventHandle
);
114 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
116 Status
= _SEH_GetExceptionCode();
120 if(!NT_SUCCESS(Status
)) return Status
;
123 /* Create the Object */
124 Status
= ObCreateObject(PreviousMode
,
134 /* Check for Success */
135 if(NT_SUCCESS(Status
)) {
137 /* Initalize the Event */
138 KeInitializeEvent(Event
,
143 Status
= ObInsertObject((PVOID
)Event
,
149 ObDereferenceObject(Event
);
151 /* Check for success and return handle */
152 if(NT_SUCCESS(Status
)) {
156 *EventHandle
= hEvent
;
158 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
160 Status
= _SEH_GetExceptionCode();
175 NtOpenEvent(OUT PHANDLE EventHandle
,
176 IN ACCESS_MASK DesiredAccess
,
177 IN POBJECT_ATTRIBUTES ObjectAttributes
)
180 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
181 NTSTATUS Status
= STATUS_SUCCESS
;
184 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
186 /* Check Output Safety */
187 if(PreviousMode
!= KernelMode
) {
191 ProbeForWriteHandle(EventHandle
);
192 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
194 Status
= _SEH_GetExceptionCode();
198 if(!NT_SUCCESS(Status
)) return Status
;
201 /* Open the Object */
202 Status
= ObOpenObjectByName(ObjectAttributes
,
210 /* Check for success and return handle */
211 if(NT_SUCCESS(Status
)) {
215 *EventHandle
= hEvent
;
217 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
219 Status
= _SEH_GetExceptionCode();
233 NtPulseEvent(IN HANDLE EventHandle
,
234 OUT PLONG PreviousState OPTIONAL
)
237 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
238 NTSTATUS Status
= STATUS_SUCCESS
;
241 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
242 EventHandle
, PreviousState
);
244 /* Check buffer validity */
245 if(PreviousState
&& PreviousMode
!= KernelMode
) {
249 ProbeForWriteLong(PreviousState
);
250 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
252 Status
= _SEH_GetExceptionCode();
256 if(!NT_SUCCESS(Status
)) return Status
;
259 /* Open the Object */
260 Status
= ObReferenceObjectByHandle(EventHandle
,
267 /* Check for success */
268 if(NT_SUCCESS(Status
)) {
270 /* Pulse the Event */
271 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
272 ObDereferenceObject(Event
);
279 *PreviousState
= Prev
;
281 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
283 Status
= _SEH_GetExceptionCode();
299 NtQueryEvent(IN HANDLE EventHandle
,
300 IN EVENT_INFORMATION_CLASS EventInformationClass
,
301 OUT PVOID EventInformation
,
302 IN ULONG EventInformationLength
,
303 OUT PULONG ReturnLength OPTIONAL
)
306 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
307 NTSTATUS Status
= STATUS_SUCCESS
;
308 PEVENT_BASIC_INFORMATION BasicInfo
= (PEVENT_BASIC_INFORMATION
)EventInformation
;
311 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle
, EventInformationClass
);
313 /* Check buffers and class validity */
314 Status
= DefaultQueryInfoBufferCheck(EventInformationClass
,
316 sizeof(ExEventInfoClass
) / sizeof(ExEventInfoClass
[0]),
318 EventInformationLength
,
321 if(!NT_SUCCESS(Status
)) {
323 /* Invalid buffers */
324 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
329 Status
= ObReferenceObjectByHandle(EventHandle
,
336 /* Check for success */
337 if(NT_SUCCESS(Status
)) {
341 /* Return Event Type and State */
342 BasicInfo
->EventType
= Event
->Header
.Type
;
343 BasicInfo
->EventState
= KeReadStateEvent(Event
);
346 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
348 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
350 Status
= _SEH_GetExceptionCode();
354 /* Dereference the Object */
355 ObDereferenceObject(Event
);
367 NtResetEvent(IN HANDLE EventHandle
,
368 OUT PLONG PreviousState OPTIONAL
)
371 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
372 NTSTATUS Status
= STATUS_SUCCESS
;
375 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
376 EventHandle
, PreviousState
);
378 /* Check buffer validity */
379 if(PreviousState
&& PreviousMode
!= KernelMode
) {
383 ProbeForWriteLong(PreviousState
);
384 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
386 Status
= _SEH_GetExceptionCode();
390 if(!NT_SUCCESS(Status
)) return Status
;
393 /* Open the Object */
394 Status
= ObReferenceObjectByHandle(EventHandle
,
401 /* Check for success */
402 if(NT_SUCCESS(Status
)) {
404 /* Reset the Event */
405 LONG Prev
= KeResetEvent(Event
);
406 ObDereferenceObject(Event
);
413 *PreviousState
= Prev
;
415 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
417 Status
= _SEH_GetExceptionCode();
432 NtSetEvent(IN HANDLE EventHandle
,
433 OUT PLONG PreviousState OPTIONAL
)
436 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
437 NTSTATUS Status
= STATUS_SUCCESS
;
440 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
441 EventHandle
, PreviousState
);
443 /* Check buffer validity */
444 if(PreviousState
!= NULL
&& PreviousMode
!= KernelMode
) {
448 ProbeForWriteLong(PreviousState
);
449 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
451 Status
= _SEH_GetExceptionCode();
455 if(!NT_SUCCESS(Status
)) return Status
;
458 /* Open the Object */
459 Status
= ObReferenceObjectByHandle(EventHandle
,
466 /* Check for success */
467 if(NT_SUCCESS(Status
)) {
470 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
471 ObDereferenceObject(Event
);
478 *PreviousState
= Prev
;
480 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
482 Status
= _SEH_GetExceptionCode();