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 *****************************************************************/
37 ExpInitializeEventImplementation(VOID
)
39 /* Create the Event Object Type */
40 ExEventObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
41 RtlInitUnicodeString(&ExEventObjectType
->TypeName
, L
"Event");
42 ExEventObjectType
->Tag
= TAG('E', 'V', 'T', 'T');
43 ExEventObjectType
->PeakObjects
= 0;
44 ExEventObjectType
->PeakHandles
= 0;
45 ExEventObjectType
->TotalObjects
= 0;
46 ExEventObjectType
->TotalHandles
= 0;
47 ExEventObjectType
->PagedPoolCharge
= 0;
48 ExEventObjectType
->NonpagedPoolCharge
= sizeof(KEVENT
);
49 ExEventObjectType
->Mapping
= &ExpEventMapping
;
50 ExEventObjectType
->Dump
= NULL
;
51 ExEventObjectType
->Open
= NULL
;
52 ExEventObjectType
->Close
= NULL
;
53 ExEventObjectType
->Delete
= NULL
;
54 ExEventObjectType
->Parse
= NULL
;
55 ExEventObjectType
->Security
= NULL
;
56 ExEventObjectType
->QueryName
= NULL
;
57 ExEventObjectType
->OkayToClose
= NULL
;
58 ExEventObjectType
->Create
= NULL
;
59 ExEventObjectType
->DuplicationNotify
= NULL
;
60 ObpCreateTypeObject(ExEventObjectType
);
68 NtClearEvent(IN HANDLE EventHandle
)
75 /* Reference the Object */
76 Status
= ObReferenceObjectByHandle(EventHandle
,
83 /* Check for Success */
84 if(NT_SUCCESS(Status
)) {
86 /* Clear the Event and Dereference */
88 ObDereferenceObject(Event
);
101 NtCreateEvent(OUT PHANDLE EventHandle
,
102 IN ACCESS_MASK DesiredAccess
,
103 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
104 IN EVENT_TYPE EventType
,
105 IN BOOLEAN InitialState
)
107 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
110 NTSTATUS Status
= STATUS_SUCCESS
;
113 DPRINT("NtCreateEvent(0x%x, 0x%x, 0x%x)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
115 /* Check Output Safety */
116 if(PreviousMode
!= KernelMode
) {
120 ProbeForWrite(EventHandle
,
125 Status
= _SEH_GetExceptionCode();
129 if(!NT_SUCCESS(Status
)) return Status
;
132 /* Create the Object */
133 Status
= ObCreateObject(PreviousMode
,
143 /* Check for Success */
144 if(NT_SUCCESS(Status
)) {
146 /* Initalize the Event */
147 KeInitializeEvent(Event
,
152 Status
= ObInsertObject((PVOID
)Event
,
158 ObDereferenceObject(Event
);
160 /* Check for success and return handle */
161 if(NT_SUCCESS(Status
)) {
165 *EventHandle
= hEvent
;
169 Status
= _SEH_GetExceptionCode();
184 NtOpenEvent(OUT PHANDLE EventHandle
,
185 IN ACCESS_MASK DesiredAccess
,
186 IN POBJECT_ATTRIBUTES ObjectAttributes
)
189 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
190 NTSTATUS Status
= STATUS_SUCCESS
;
193 DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
195 /* Check Output Safety */
196 if(PreviousMode
!= KernelMode
) {
200 ProbeForWrite(EventHandle
,
205 Status
= _SEH_GetExceptionCode();
209 if(!NT_SUCCESS(Status
)) return Status
;
212 /* Open the Object */
213 Status
= ObOpenObjectByName(ObjectAttributes
,
221 /* Check for success and return handle */
222 if(NT_SUCCESS(Status
)) {
226 *EventHandle
= hEvent
;
230 Status
= _SEH_GetExceptionCode();
244 NtPulseEvent(IN HANDLE EventHandle
,
245 OUT PLONG PreviousState OPTIONAL
)
248 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
249 NTSTATUS Status
= STATUS_SUCCESS
;
252 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
253 EventHandle
, PreviousState
);
255 /* Check buffer validity */
256 if(PreviousState
&& PreviousMode
== UserMode
) {
260 ProbeForWrite(PreviousState
,
265 Status
= _SEH_GetExceptionCode();
269 if(!NT_SUCCESS(Status
)) return Status
;
272 /* Open the Object */
273 Status
= ObReferenceObjectByHandle(EventHandle
,
280 /* Check for success */
281 if(NT_SUCCESS(Status
)) {
283 /* Pulse the Event */
284 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
285 ObDereferenceObject(Event
);
292 *PreviousState
= Prev
;
296 Status
= _SEH_GetExceptionCode();
312 NtQueryEvent(IN HANDLE EventHandle
,
313 IN EVENT_INFORMATION_CLASS EventInformationClass
,
314 OUT PVOID EventInformation
,
315 IN ULONG EventInformationLength
,
316 OUT PULONG ReturnLength OPTIONAL
)
319 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
320 NTSTATUS Status
= STATUS_SUCCESS
;
321 PEVENT_BASIC_INFORMATION BasicInfo
= (PEVENT_BASIC_INFORMATION
)EventInformation
;
324 DPRINT("NtQueryEvent(0x%x, 0x%x, 0x%x)\n", EventHandle
, EventInformationClass
);
326 /* Check buffers and class validity */
327 DefaultQueryInfoBufferCheck(EventInformationClass
,
330 EventInformationLength
,
334 if(!NT_SUCCESS(Status
)) {
336 /* Invalid buffers */
337 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
342 Status
= ObReferenceObjectByHandle(EventHandle
,
349 /* Check for success */
350 if(NT_SUCCESS(Status
)) {
354 /* Return Event Type and State */
355 BasicInfo
->EventType
= Event
->Header
.Type
;
356 BasicInfo
->EventState
= KeReadStateEvent(Event
);
359 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
363 Status
= _SEH_GetExceptionCode();
367 /* Dereference the Object */
368 ObDereferenceObject(Event
);
380 NtResetEvent(IN HANDLE EventHandle
,
381 OUT PLONG PreviousState OPTIONAL
)
384 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
385 NTSTATUS Status
= STATUS_SUCCESS
;
388 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
389 EventHandle
, PreviousState
);
391 /* Check buffer validity */
392 if(PreviousState
&& PreviousMode
== UserMode
) {
396 ProbeForWrite(PreviousState
,
401 Status
= _SEH_GetExceptionCode();
405 if(!NT_SUCCESS(Status
)) return Status
;
408 /* Open the Object */
409 Status
= ObReferenceObjectByHandle(EventHandle
,
416 /* Check for success */
417 if(NT_SUCCESS(Status
)) {
419 /* Reset the Event */
420 LONG Prev
= KeResetEvent(Event
);
421 ObDereferenceObject(Event
);
428 *PreviousState
= Prev
;
432 Status
= _SEH_GetExceptionCode();
447 NtSetEvent(IN HANDLE EventHandle
,
448 OUT PLONG PreviousState OPTIONAL
)
451 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
452 NTSTATUS Status
= STATUS_SUCCESS
;
455 DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
456 EventHandle
, PreviousState
);
458 /* Check buffer validity */
459 if(PreviousState
!= NULL
&& PreviousMode
== UserMode
) {
463 ProbeForWrite(PreviousState
,
468 Status
= _SEH_GetExceptionCode();
472 if(!NT_SUCCESS(Status
)) return Status
;
475 /* Open the Object */
476 Status
= ObReferenceObjectByHandle(EventHandle
,
483 /* Check for success */
484 if(NT_SUCCESS(Status
)) {
487 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
488 ObDereferenceObject(Event
);
495 *PreviousState
= Prev
;
499 Status
= _SEH_GetExceptionCode();