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 EXPORTED 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 ProbeForWrite(EventHandle
,
116 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
118 Status
= _SEH_GetExceptionCode();
122 if(!NT_SUCCESS(Status
)) return Status
;
125 /* Create the Object */
126 Status
= ObCreateObject(PreviousMode
,
136 /* Check for Success */
137 if(NT_SUCCESS(Status
)) {
139 /* Initalize the Event */
140 KeInitializeEvent(Event
,
145 Status
= ObInsertObject((PVOID
)Event
,
151 ObDereferenceObject(Event
);
153 /* Check for success and return handle */
154 if(NT_SUCCESS(Status
)) {
158 *EventHandle
= hEvent
;
160 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
162 Status
= _SEH_GetExceptionCode();
177 NtOpenEvent(OUT PHANDLE EventHandle
,
178 IN ACCESS_MASK DesiredAccess
,
179 IN POBJECT_ATTRIBUTES ObjectAttributes
)
182 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
183 NTSTATUS Status
= STATUS_SUCCESS
;
186 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
188 /* Check Output Safety */
189 if(PreviousMode
!= KernelMode
) {
193 ProbeForWrite(EventHandle
,
196 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
198 Status
= _SEH_GetExceptionCode();
202 if(!NT_SUCCESS(Status
)) return Status
;
205 /* Open the Object */
206 Status
= ObOpenObjectByName(ObjectAttributes
,
214 /* Check for success and return handle */
215 if(NT_SUCCESS(Status
)) {
219 *EventHandle
= hEvent
;
221 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
223 Status
= _SEH_GetExceptionCode();
237 NtPulseEvent(IN HANDLE EventHandle
,
238 OUT PLONG PreviousState OPTIONAL
)
241 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
242 NTSTATUS Status
= STATUS_SUCCESS
;
245 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
246 EventHandle
, PreviousState
);
248 /* Check buffer validity */
249 if(PreviousState
&& PreviousMode
== UserMode
) {
253 ProbeForWrite(PreviousState
,
256 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
258 Status
= _SEH_GetExceptionCode();
262 if(!NT_SUCCESS(Status
)) return Status
;
265 /* Open the Object */
266 Status
= ObReferenceObjectByHandle(EventHandle
,
273 /* Check for success */
274 if(NT_SUCCESS(Status
)) {
276 /* Pulse the Event */
277 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
278 ObDereferenceObject(Event
);
285 *PreviousState
= Prev
;
287 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
289 Status
= _SEH_GetExceptionCode();
305 NtQueryEvent(IN HANDLE EventHandle
,
306 IN EVENT_INFORMATION_CLASS EventInformationClass
,
307 OUT PVOID EventInformation
,
308 IN ULONG EventInformationLength
,
309 OUT PULONG ReturnLength OPTIONAL
)
312 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
313 NTSTATUS Status
= STATUS_SUCCESS
;
314 PEVENT_BASIC_INFORMATION BasicInfo
= (PEVENT_BASIC_INFORMATION
)EventInformation
;
317 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle
, EventInformationClass
);
319 /* Check buffers and class validity */
320 DefaultQueryInfoBufferCheck(EventInformationClass
,
323 EventInformationLength
,
327 if(!NT_SUCCESS(Status
)) {
329 /* Invalid buffers */
330 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
335 Status
= ObReferenceObjectByHandle(EventHandle
,
342 /* Check for success */
343 if(NT_SUCCESS(Status
)) {
347 /* Return Event Type and State */
348 BasicInfo
->EventType
= Event
->Header
.Type
;
349 BasicInfo
->EventState
= KeReadStateEvent(Event
);
352 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
354 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
356 Status
= _SEH_GetExceptionCode();
360 /* Dereference the Object */
361 ObDereferenceObject(Event
);
373 NtResetEvent(IN HANDLE EventHandle
,
374 OUT PLONG PreviousState OPTIONAL
)
377 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
378 NTSTATUS Status
= STATUS_SUCCESS
;
381 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
382 EventHandle
, PreviousState
);
384 /* Check buffer validity */
385 if(PreviousState
&& PreviousMode
== UserMode
) {
389 ProbeForWrite(PreviousState
,
392 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
394 Status
= _SEH_GetExceptionCode();
398 if(!NT_SUCCESS(Status
)) return Status
;
401 /* Open the Object */
402 Status
= ObReferenceObjectByHandle(EventHandle
,
409 /* Check for success */
410 if(NT_SUCCESS(Status
)) {
412 /* Reset the Event */
413 LONG Prev
= KeResetEvent(Event
);
414 ObDereferenceObject(Event
);
421 *PreviousState
= Prev
;
423 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
425 Status
= _SEH_GetExceptionCode();
440 NtSetEvent(IN HANDLE EventHandle
,
441 OUT PLONG PreviousState OPTIONAL
)
444 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
445 NTSTATUS Status
= STATUS_SUCCESS
;
448 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
449 EventHandle
, PreviousState
);
451 /* Check buffer validity */
452 if(PreviousState
!= NULL
&& PreviousMode
== UserMode
) {
456 ProbeForWrite(PreviousState
,
459 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
461 Status
= _SEH_GetExceptionCode();
465 if(!NT_SUCCESS(Status
)) return Status
;
468 /* Open the Object */
469 Status
= ObReferenceObjectByHandle(EventHandle
,
476 /* Check for success */
477 if(NT_SUCCESS(Status
)) {
480 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
481 ObDereferenceObject(Event
);
488 *PreviousState
= Prev
;
490 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
492 Status
= _SEH_GetExceptionCode();