3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/nt/event.c
6 * PURPOSE: Named event support
8 * PROGRAMMERS: 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 RtlpCreateUnicodeString(&ExEventObjectType
->TypeName
, L
"Event", NonPagedPool
);
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
;
114 /* Check Output Safety */
115 if(PreviousMode
== UserMode
) {
119 ProbeForWrite(EventHandle
,
124 Status
= _SEH_GetExceptionCode();
128 if(!NT_SUCCESS(Status
)) return Status
;
131 /* Create the Object */
132 Status
= ObCreateObject(PreviousMode
,
142 /* Check for Success */
143 if(NT_SUCCESS(Status
)) {
145 /* Initalize the Event */
146 KeInitializeEvent(Event
,
151 Status
= ObInsertObject((PVOID
)Event
,
157 ObDereferenceObject(Event
);
159 /* Check for success and return handle */
160 if(NT_SUCCESS(Status
)) {
164 *EventHandle
= hEvent
;
168 Status
= _SEH_GetExceptionCode();
183 NtOpenEvent(OUT PHANDLE EventHandle
,
184 IN ACCESS_MASK DesiredAccess
,
185 IN POBJECT_ATTRIBUTES ObjectAttributes
)
188 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
189 NTSTATUS Status
= STATUS_SUCCESS
;
192 DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle
, DesiredAccess
, ObjectAttributes
);
194 /* Check Output Safety */
195 if(PreviousMode
== UserMode
) {
199 ProbeForWrite(EventHandle
,
204 Status
= _SEH_GetExceptionCode();
208 if(!NT_SUCCESS(Status
)) return Status
;
211 /* Open the Object */
212 Status
= ObOpenObjectByName(ObjectAttributes
,
220 /* Check for success and return handle */
221 if(NT_SUCCESS(Status
)) {
225 *EventHandle
= hEvent
;
229 Status
= _SEH_GetExceptionCode();
243 NtPulseEvent(IN HANDLE EventHandle
,
244 OUT PLONG PreviousState OPTIONAL
)
247 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
248 NTSTATUS Status
= STATUS_SUCCESS
;
251 DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
252 EventHandle
, PreviousState
);
254 /* Check buffer validity */
255 if(PreviousState
&& PreviousMode
== UserMode
) {
259 ProbeForWrite(PreviousState
,
264 Status
= _SEH_GetExceptionCode();
268 if(!NT_SUCCESS(Status
)) return Status
;
271 /* Open the Object */
272 Status
= ObReferenceObjectByHandle(EventHandle
,
279 /* Check for success */
280 if(NT_SUCCESS(Status
)) {
282 /* Pulse the Event */
283 LONG Prev
= KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
284 ObDereferenceObject(Event
);
291 *PreviousState
= Prev
;
295 Status
= _SEH_GetExceptionCode();
311 NtQueryEvent(IN HANDLE EventHandle
,
312 IN EVENT_INFORMATION_CLASS EventInformationClass
,
313 OUT PVOID EventInformation
,
314 IN ULONG EventInformationLength
,
315 OUT PULONG ReturnLength OPTIONAL
)
318 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
319 NTSTATUS Status
= STATUS_SUCCESS
;
320 PEVENT_BASIC_INFORMATION BasicInfo
= (PEVENT_BASIC_INFORMATION
)EventInformation
;
322 /* Check buffers and class validity */
323 DefaultQueryInfoBufferCheck(EventInformationClass
,
326 EventInformationLength
,
330 if(!NT_SUCCESS(Status
)) {
332 /* Invalid buffers */
333 DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status
);
338 Status
= ObReferenceObjectByHandle(EventHandle
,
345 /* Check for success */
346 if(NT_SUCCESS(Status
)) {
350 /* Return Event Type and State */
351 BasicInfo
->EventType
= Event
->Header
.Type
;
352 BasicInfo
->EventState
= KeReadStateEvent(Event
);
355 if(ReturnLength
) *ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
359 Status
= _SEH_GetExceptionCode();
363 /* Dereference the Object */
364 ObDereferenceObject(Event
);
376 NtResetEvent(IN HANDLE EventHandle
,
377 OUT PLONG PreviousState OPTIONAL
)
380 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
381 NTSTATUS Status
= STATUS_SUCCESS
;
385 DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
386 EventHandle
, PreviousState
);
388 /* Check buffer validity */
389 if(PreviousState
&& PreviousMode
== UserMode
) {
393 ProbeForWrite(PreviousState
,
398 Status
= _SEH_GetExceptionCode();
402 if(!NT_SUCCESS(Status
)) return Status
;
405 /* Open the Object */
406 Status
= ObReferenceObjectByHandle(EventHandle
,
413 /* Check for success */
414 if(NT_SUCCESS(Status
)) {
416 /* Reset the Event */
417 LONG Prev
= KeResetEvent(Event
);
418 ObDereferenceObject(Event
);
425 *PreviousState
= Prev
;
429 Status
= _SEH_GetExceptionCode();
444 NtSetEvent(IN HANDLE EventHandle
,
445 OUT PLONG PreviousState OPTIONAL
)
448 KPROCESSOR_MODE PreviousMode
= ExGetPreviousMode();
449 NTSTATUS Status
= STATUS_SUCCESS
;
453 DPRINT1("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
454 EventHandle
, PreviousState
);
456 /* Check buffer validity */
457 if(PreviousState
!= NULL
&& PreviousMode
== UserMode
) {
461 ProbeForWrite(PreviousState
,
466 Status
= _SEH_GetExceptionCode();
470 if(!NT_SUCCESS(Status
)) return Status
;
473 /* Open the Object */
474 Status
= ObReferenceObjectByHandle(EventHandle
,
481 /* Check for success */
482 if(NT_SUCCESS(Status
)) {
485 LONG Prev
= KeSetEvent(Event
, EVENT_INCREMENT
, FALSE
);
486 ObDereferenceObject(Event
);
493 *PreviousState
= Prev
;
497 Status
= _SEH_GetExceptionCode();