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 #include <ddk/ntddk.h>
32 #include <internal/id.h>
33 #include <ntos/synch.h>
34 #include <internal/pool.h>
35 #include <internal/safe.h>
38 #include <internal/debug.h>
40 /* GLOBALS *******************************************************************/
42 POBJECT_TYPE EXPORTED ExEventObjectType = NULL;
44 static GENERIC_MAPPING ExpEventMapping = {
45 STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
46 STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
47 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
51 /* FUNCTIONS *****************************************************************/
54 NtpCreateEvent(PVOID ObjectBody,
57 POBJECT_ATTRIBUTES ObjectAttributes)
59 DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n",
60 ObjectBody, Parent, RemainingPath);
62 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
64 return(STATUS_UNSUCCESSFUL);
67 return(STATUS_SUCCESS);
72 NtInitializeEventImplementation(VOID)
74 ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
76 RtlCreateUnicodeString(&ExEventObjectType->TypeName, L"Event");
78 ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
79 ExEventObjectType->MaxObjects = ULONG_MAX;
80 ExEventObjectType->MaxHandles = ULONG_MAX;
81 ExEventObjectType->TotalObjects = 0;
82 ExEventObjectType->TotalHandles = 0;
83 ExEventObjectType->PagedPoolCharge = 0;
84 ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
85 ExEventObjectType->Mapping = &ExpEventMapping;
86 ExEventObjectType->Dump = NULL;
87 ExEventObjectType->Open = NULL;
88 ExEventObjectType->Close = NULL;
89 ExEventObjectType->Delete = NULL;
90 ExEventObjectType->Parse = NULL;
91 ExEventObjectType->Security = NULL;
92 ExEventObjectType->QueryName = NULL;
93 ExEventObjectType->OkayToClose = NULL;
94 ExEventObjectType->Create = NtpCreateEvent;
95 ExEventObjectType->DuplicationNotify = NULL;
100 NtClearEvent(IN HANDLE EventHandle)
105 Status = ObReferenceObjectByHandle(EventHandle,
111 if (!NT_SUCCESS(Status))
116 ObDereferenceObject(Event);
117 return(STATUS_SUCCESS);
122 NtCreateEvent(OUT PHANDLE UnsafeEventHandle,
123 IN ACCESS_MASK DesiredAccess,
124 IN POBJECT_ATTRIBUTES UnsafeObjectAttributes,
125 IN BOOLEAN ManualReset,
126 IN BOOLEAN InitialState)
131 OBJECT_ATTRIBUTES SafeObjectAttributes;
132 POBJECT_ATTRIBUTES ObjectAttributes;
134 if (UnsafeObjectAttributes != NULL)
136 Status = MmCopyFromCaller(&SafeObjectAttributes, UnsafeObjectAttributes,
137 sizeof(OBJECT_ATTRIBUTES));
138 if (!NT_SUCCESS(Status))
142 ObjectAttributes = &SafeObjectAttributes;
146 ObjectAttributes = NULL;
149 Status = ObCreateObject(&EventHandle,
154 if (!NT_SUCCESS(Status))
158 KeInitializeEvent(Event,
159 ManualReset ? NotificationEvent : SynchronizationEvent,
161 ObDereferenceObject(Event);
163 Status = MmCopyToCaller(UnsafeEventHandle, &EventHandle, sizeof(HANDLE));
164 if (!NT_SUCCESS(Status))
166 ZwClose(EventHandle);
169 return(STATUS_SUCCESS);
174 NtOpenEvent(OUT PHANDLE UnsafeEventHandle,
175 IN ACCESS_MASK DesiredAccess,
176 IN POBJECT_ATTRIBUTES ObjectAttributes)
181 DPRINT("ObjectName '%wZ'\n", ObjectAttributes->ObjectName);
183 Status = ObOpenObjectByName(ObjectAttributes,
191 Status = MmCopyToCaller(UnsafeEventHandle, &EventHandle, sizeof(HANDLE));
192 if (!NT_SUCCESS(Status))
194 ZwClose(EventHandle);
203 NtPulseEvent(IN HANDLE EventHandle,
204 IN PULONG UnsafePulseCount OPTIONAL)
209 DPRINT("NtPulseEvent(EventHandle %x UnsafePulseCount %x)\n",
210 EventHandle, UnsafePulseCount);
212 Status = ObReferenceObjectByHandle(EventHandle,
218 if (!NT_SUCCESS(Status))
223 KePulseEvent(Event, EVENT_INCREMENT, FALSE);
225 ObDereferenceObject(Event);
226 return(STATUS_SUCCESS);
231 NtQueryEvent(IN HANDLE EventHandle,
232 IN EVENT_INFORMATION_CLASS EventInformationClass,
233 OUT PVOID UnsafeEventInformation,
234 IN ULONG EventInformationLength,
235 OUT PULONG UnsafeReturnLength)
237 EVENT_BASIC_INFORMATION Info;
242 if (EventInformationClass > EventBasicInformation)
243 return STATUS_INVALID_INFO_CLASS;
245 if (EventInformationLength < sizeof(EVENT_BASIC_INFORMATION))
246 return STATUS_INFO_LENGTH_MISMATCH;
248 Status = ObReferenceObjectByHandle(EventHandle,
254 if (!NT_SUCCESS(Status))
257 if (Event->Header.Type == InternalNotificationEvent)
258 Info.EventType = NotificationEvent;
260 Info.EventType = SynchronizationEvent;
261 Info.EventState = KeReadStateEvent(Event);
263 Status = MmCopyToCaller(UnsafeEventInformation, &Event,
264 sizeof(EVENT_BASIC_INFORMATION));
265 if (!NT_SUCCESS(Status))
267 ObDereferenceObject(Event);
271 ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
272 Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
273 if (!NT_SUCCESS(Status))
275 ObDereferenceObject(Event);
279 ObDereferenceObject(Event);
281 return(STATUS_SUCCESS);
286 NtResetEvent(IN HANDLE EventHandle,
287 OUT PULONG UnsafeNumberOfWaitingThreads OPTIONAL)
292 DPRINT("NtResetEvent(EventHandle %x)\n", EventHandle);
294 Status = ObReferenceObjectByHandle(EventHandle,
300 if (!NT_SUCCESS(Status))
305 ObDereferenceObject(Event);
306 return(STATUS_SUCCESS);
311 NtSetEvent(IN HANDLE EventHandle,
312 OUT PULONG UnsafeNumberOfThreadsReleased)
317 DPRINT("NtSetEvent(EventHandle %x)\n", EventHandle);
319 Status = ObReferenceObjectByHandle(EventHandle,
325 if (!NT_SUCCESS(Status))
329 KeSetEvent(Event,EVENT_INCREMENT,FALSE);
330 ObDereferenceObject(Event);
331 return(STATUS_SUCCESS);