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 #if defined (ALLOC_PRAGMA)
18 #pragma alloc_text(INIT, ExpInitializeEventImplementation)
21 /* GLOBALS *******************************************************************/
23 POBJECT_TYPE ExEventObjectType
= NULL
;
25 static 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
;
47 DPRINT("Creating Event Object Type\n");
49 /* Create the Event Object Type */
50 RtlZeroMemory(&ObjectTypeInitializer
, sizeof(ObjectTypeInitializer
));
51 RtlInitUnicodeString(&Name
, L
"Event");
52 ObjectTypeInitializer
.Length
= sizeof(ObjectTypeInitializer
);
53 ObjectTypeInitializer
.DefaultNonPagedPoolCharge
= sizeof(KEVENT
);
54 ObjectTypeInitializer
.GenericMapping
= ExpEventMapping
;
55 ObjectTypeInitializer
.PoolType
= NonPagedPool
;
56 ObjectTypeInitializer
.ValidAccessMask
= EVENT_ALL_ACCESS
;
57 ObpCreateTypeObject(&ObjectTypeInitializer
, &Name
, &ExEventObjectType
);
65 NtClearEvent(IN HANDLE EventHandle
)
72 /* Reference the Object */
73 Status
= ObReferenceObjectByHandle(EventHandle
,
80 /* Check for Success */
81 if(NT_SUCCESS(Status
)) {
83 /* Clear the Event and Dereference */
85 ObDereferenceObject(Event
);
98 NtCreateEvent(OUT PHANDLE EventHandle
,
99 IN ACCESS_MASK DesiredAccess
,
100 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
101 IN EVENT_TYPE EventType
,
102 IN BOOLEAN InitialState
)
104 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
107 NTSTATUS Status
= STATUS_SUCCESS
;
110 DPRINT("NtCreateEvent(0x%p, 0x%x, 0x%p)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
112 /* Check Output Safety */
113 if(PreviousMode
!= KernelMode
) {
117 ProbeForWriteHandle(EventHandle
);
118 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
120 Status
= _SEH_GetExceptionCode();
124 if(!NT_SUCCESS(Status
)) return Status
;
127 /* Create the Object */
128 Status
= ObCreateObject(PreviousMode
,
138 /* Check for Success */
139 if(NT_SUCCESS(Status
)) {
141 /* Initalize the Event */
142 KeInitializeEvent(Event
,
147 Status
= ObInsertObject((PVOID
)Event
,
153 ObDereferenceObject(Event
);
155 /* Check for success and return handle */
156 if(NT_SUCCESS(Status
)) {
160 *EventHandle
= hEvent
;
162 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
164 Status
= _SEH_GetExceptionCode();
179 NtOpenEvent(OUT PHANDLE EventHandle
,
180 IN ACCESS_MASK DesiredAccess
,
181 IN POBJECT_ATTRIBUTES ObjectAttributes
)
184 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
185 NTSTATUS Status
= STATUS_SUCCESS
;
188 DPRINT("NtOpenEvent(0x%p, 0x%x, 0x%p)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
190 /* Check Output Safety */
191 if(PreviousMode
!= KernelMode
) {
195 ProbeForWriteHandle(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
!= KernelMode
) {
253 ProbeForWriteLong(PreviousState
);
254 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
256 Status
= _SEH_GetExceptionCode();
260 if(!NT_SUCCESS(Status
)) return Status
;
263 /* Open the Object */
264 Status
= ObReferenceObjectByHandle(EventHandle
,
271 /* Check for success */
272 if(NT_SUCCESS(Status
)) {
274 /* Pulse the Event */
275 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
276 ObDereferenceObject(Event
);
283 *PreviousState
= Prev
;
285 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
287 Status
= _SEH_GetExceptionCode();
303 NtQueryEvent(IN HANDLE EventHandle
,
304 IN EVENT_INFORMATION_CLASS EventInformationClass
,
305 OUT PVOID EventInformation
,
306 IN ULONG EventInformationLength
,
307 OUT PULONG ReturnLength OPTIONAL
)
310 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
311 NTSTATUS Status
= STATUS_SUCCESS
;
312 PEVENT_BASIC_INFORMATION BasicInfo
= (PEVENT_BASIC_INFORMATION
)EventInformation
;
315 DPRINT("NtQueryEvent(0x%p, 0x%x)\n", EventHandle
, EventInformationClass
);
317 /* Check buffers and class validity */
318 Status
= DefaultQueryInfoBufferCheck(EventInformationClass
,
320 sizeof(ExEventInfoClass
) / sizeof(ExEventInfoClass
[0]),
322 EventInformationLength
,
325 if(!NT_SUCCESS(Status
)) {
327 /* Invalid buffers */
328 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
333 Status
= ObReferenceObjectByHandle(EventHandle
,
340 /* Check for success */
341 if(NT_SUCCESS(Status
)) {
345 /* Return Event Type and State */
346 BasicInfo
->EventType
= Event
->Header
.Type
;
347 BasicInfo
->EventState
= KeReadStateEvent(Event
);
350 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
352 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
354 Status
= _SEH_GetExceptionCode();
358 /* Dereference the Object */
359 ObDereferenceObject(Event
);
371 NtResetEvent(IN HANDLE EventHandle
,
372 OUT PLONG PreviousState OPTIONAL
)
375 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
376 NTSTATUS Status
= STATUS_SUCCESS
;
379 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
380 EventHandle
, PreviousState
);
382 /* Check buffer validity */
383 if(PreviousState
&& PreviousMode
!= KernelMode
) {
387 ProbeForWriteLong(PreviousState
);
388 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
390 Status
= _SEH_GetExceptionCode();
394 if(!NT_SUCCESS(Status
)) return Status
;
397 /* Open the Object */
398 Status
= ObReferenceObjectByHandle(EventHandle
,
405 /* Check for success */
406 if(NT_SUCCESS(Status
)) {
408 /* Reset the Event */
409 LONG Prev
= KeResetEvent(Event
);
410 ObDereferenceObject(Event
);
417 *PreviousState
= Prev
;
419 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
421 Status
= _SEH_GetExceptionCode();
436 NtSetEvent(IN HANDLE EventHandle
,
437 OUT PLONG PreviousState OPTIONAL
)
440 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
441 NTSTATUS Status
= STATUS_SUCCESS
;
444 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
445 EventHandle
, PreviousState
);
447 /* Check buffer validity */
448 if(PreviousState
!= NULL
&& PreviousMode
!= KernelMode
) {
452 ProbeForWriteLong(PreviousState
);
453 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
455 Status
= _SEH_GetExceptionCode();
459 if(!NT_SUCCESS(Status
)) return Status
;
462 /* Open the Object */
463 Status
= ObReferenceObjectByHandle(EventHandle
,
470 /* Check for success */
471 if(NT_SUCCESS(Status
)) {
474 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
475 ObDereferenceObject(Event
);
482 *PreviousState
= Prev
;
484 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter
) {
486 Status
= _SEH_GetExceptionCode();