3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/nt/event.c
22 * PURPOSE: Named event support
23 * PROGRAMMER: Philip Susi and David Welch
28 /* INCLUDES *****************************************************************/
31 #define NTOS_MODE_KERNEL
33 #include <internal/id.h>
34 #include <internal/ob.h>
35 #include <ntos/synch.h>
36 #include <internal/pool.h>
37 #include <internal/safe.h>
40 #include <internal/debug.h>
42 /* GLOBALS *******************************************************************/
44 POBJECT_TYPE EXPORTED ExEventObjectType
= NULL
;
46 static GENERIC_MAPPING ExpEventMapping
= {
47 STANDARD_RIGHTS_READ
| SYNCHRONIZE
| EVENT_QUERY_STATE
,
48 STANDARD_RIGHTS_WRITE
| SYNCHRONIZE
| EVENT_MODIFY_STATE
,
49 STANDARD_RIGHTS_EXECUTE
| SYNCHRONIZE
| EVENT_QUERY_STATE
,
53 /* FUNCTIONS *****************************************************************/
56 NtpCreateEvent(PVOID ObjectBody
,
59 POBJECT_ATTRIBUTES ObjectAttributes
)
61 DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n",
62 ObjectBody
, Parent
, RemainingPath
);
64 if (RemainingPath
!= NULL
&& wcschr(RemainingPath
+1, '\\') != NULL
)
66 return(STATUS_UNSUCCESSFUL
);
69 return(STATUS_SUCCESS
);
74 NtInitializeEventImplementation(VOID
)
76 ExEventObjectType
= ExAllocatePool(NonPagedPool
,sizeof(OBJECT_TYPE
));
78 RtlCreateUnicodeString(&ExEventObjectType
->TypeName
, L
"Event");
80 ExEventObjectType
->Tag
= TAG('E', 'V', 'T', 'T');
81 ExEventObjectType
->MaxObjects
= ULONG_MAX
;
82 ExEventObjectType
->MaxHandles
= ULONG_MAX
;
83 ExEventObjectType
->TotalObjects
= 0;
84 ExEventObjectType
->TotalHandles
= 0;
85 ExEventObjectType
->PagedPoolCharge
= 0;
86 ExEventObjectType
->NonpagedPoolCharge
= sizeof(KEVENT
);
87 ExEventObjectType
->Mapping
= &ExpEventMapping
;
88 ExEventObjectType
->Dump
= NULL
;
89 ExEventObjectType
->Open
= NULL
;
90 ExEventObjectType
->Close
= NULL
;
91 ExEventObjectType
->Delete
= NULL
;
92 ExEventObjectType
->Parse
= NULL
;
93 ExEventObjectType
->Security
= NULL
;
94 ExEventObjectType
->QueryName
= NULL
;
95 ExEventObjectType
->OkayToClose
= NULL
;
96 ExEventObjectType
->Create
= NtpCreateEvent
;
97 ExEventObjectType
->DuplicationNotify
= NULL
;
99 ObpCreateTypeObject(ExEventObjectType
);
104 NtClearEvent(IN HANDLE EventHandle
)
109 Status
= ObReferenceObjectByHandle(EventHandle
,
115 if (!NT_SUCCESS(Status
))
120 ObDereferenceObject(Event
);
121 return(STATUS_SUCCESS
);
129 NtCreateEvent(OUT PHANDLE UnsafeEventHandle
,
130 IN ACCESS_MASK DesiredAccess
,
131 IN POBJECT_ATTRIBUTES UnsafeObjectAttributes
,
132 IN BOOLEAN ManualReset
,
133 IN BOOLEAN InitialState
)
138 OBJECT_ATTRIBUTES SafeObjectAttributes
;
139 POBJECT_ATTRIBUTES ObjectAttributes
;
141 if (UnsafeObjectAttributes
!= NULL
)
143 Status
= MmCopyFromCaller(&SafeObjectAttributes
, UnsafeObjectAttributes
,
144 sizeof(OBJECT_ATTRIBUTES
));
145 if (!NT_SUCCESS(Status
))
149 ObjectAttributes
= &SafeObjectAttributes
;
153 ObjectAttributes
= NULL
;
156 Status
= ObCreateObject(ExGetPreviousMode(),
165 if (!NT_SUCCESS(Status
))
169 KeInitializeEvent(Event
,
170 ManualReset
? NotificationEvent
: SynchronizationEvent
,
173 Status
= ObInsertObject ((PVOID
)Event
,
179 ObDereferenceObject(Event
);
180 if (!NT_SUCCESS(Status
))
185 Status
= MmCopyToCaller(UnsafeEventHandle
, &EventHandle
, sizeof(HANDLE
));
186 if (!NT_SUCCESS(Status
))
188 ZwClose(EventHandle
);
191 return(STATUS_SUCCESS
);
196 NtOpenEvent(OUT PHANDLE UnsafeEventHandle
,
197 IN ACCESS_MASK DesiredAccess
,
198 IN POBJECT_ATTRIBUTES ObjectAttributes
)
203 DPRINT("ObjectName '%wZ'\n", ObjectAttributes
->ObjectName
);
205 Status
= ObOpenObjectByName(ObjectAttributes
,
213 Status
= MmCopyToCaller(UnsafeEventHandle
, &EventHandle
, sizeof(HANDLE
));
214 if (!NT_SUCCESS(Status
))
216 ZwClose(EventHandle
);
225 NtPulseEvent(IN HANDLE EventHandle
,
226 IN PULONG UnsafePulseCount OPTIONAL
)
231 DPRINT("NtPulseEvent(EventHandle %x UnsafePulseCount %x)\n",
232 EventHandle
, UnsafePulseCount
);
234 Status
= ObReferenceObjectByHandle(EventHandle
,
240 if (!NT_SUCCESS(Status
))
245 KePulseEvent(Event
, EVENT_INCREMENT
, FALSE
);
247 ObDereferenceObject(Event
);
248 return(STATUS_SUCCESS
);
253 NtQueryEvent(IN HANDLE EventHandle
,
254 IN EVENT_INFORMATION_CLASS EventInformationClass
,
255 OUT PVOID UnsafeEventInformation
,
256 IN ULONG EventInformationLength
,
257 OUT PULONG UnsafeReturnLength
)
259 EVENT_BASIC_INFORMATION Info
;
264 if (EventInformationClass
> EventBasicInformation
)
265 return STATUS_INVALID_INFO_CLASS
;
267 if (EventInformationLength
< sizeof(EVENT_BASIC_INFORMATION
))
268 return STATUS_INFO_LENGTH_MISMATCH
;
270 Status
= ObReferenceObjectByHandle(EventHandle
,
276 if (!NT_SUCCESS(Status
))
279 if (Event
->Header
.Type
== InternalNotificationEvent
)
280 Info
.EventType
= NotificationEvent
;
282 Info
.EventType
= SynchronizationEvent
;
283 Info
.EventState
= KeReadStateEvent(Event
);
285 Status
= MmCopyToCaller(UnsafeEventInformation
, &Event
,
286 sizeof(EVENT_BASIC_INFORMATION
));
287 if (!NT_SUCCESS(Status
))
289 ObDereferenceObject(Event
);
293 ReturnLength
= sizeof(EVENT_BASIC_INFORMATION
);
294 Status
= MmCopyToCaller(UnsafeReturnLength
, &ReturnLength
, sizeof(ULONG
));
295 if (!NT_SUCCESS(Status
))
297 ObDereferenceObject(Event
);
301 ObDereferenceObject(Event
);
303 return(STATUS_SUCCESS
);
308 NtResetEvent(IN HANDLE EventHandle
,
309 OUT PULONG UnsafeNumberOfWaitingThreads OPTIONAL
)
314 DPRINT("NtResetEvent(EventHandle %x)\n", EventHandle
);
316 Status
= ObReferenceObjectByHandle(EventHandle
,
322 if (!NT_SUCCESS(Status
))
327 ObDereferenceObject(Event
);
328 return(STATUS_SUCCESS
);
336 NtSetEvent(IN HANDLE EventHandle
,
337 OUT PULONG UnsafeNumberOfThreadsReleased
)
342 DPRINT("NtSetEvent(EventHandle %x)\n", EventHandle
);
344 Status
= ObReferenceObjectByHandle(EventHandle
,
350 if (!NT_SUCCESS(Status
))
354 KeSetEvent(Event
,EVENT_INCREMENT
,FALSE
);
355 ObDereferenceObject(Event
);
356 return(STATUS_SUCCESS
);