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 <ntos/synch.h>
35 #include <internal/pool.h>
36 #include <internal/safe.h>
39 #include <internal/debug.h>
41 /* GLOBALS *******************************************************************/
43 POBJECT_TYPE EXPORTED ExEventObjectType = NULL;
45 static GENERIC_MAPPING ExpEventMapping = {
46 STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
47 STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
48 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
52 /* FUNCTIONS *****************************************************************/
55 NtpCreateEvent(PVOID ObjectBody,
58 POBJECT_ATTRIBUTES ObjectAttributes)
60 DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n",
61 ObjectBody, Parent, RemainingPath);
63 if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
65 return(STATUS_UNSUCCESSFUL);
68 return(STATUS_SUCCESS);
73 NtInitializeEventImplementation(VOID)
75 ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
77 RtlCreateUnicodeString(&ExEventObjectType->TypeName, L"Event");
79 ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
80 ExEventObjectType->MaxObjects = ULONG_MAX;
81 ExEventObjectType->MaxHandles = ULONG_MAX;
82 ExEventObjectType->TotalObjects = 0;
83 ExEventObjectType->TotalHandles = 0;
84 ExEventObjectType->PagedPoolCharge = 0;
85 ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
86 ExEventObjectType->Mapping = &ExpEventMapping;
87 ExEventObjectType->Dump = NULL;
88 ExEventObjectType->Open = NULL;
89 ExEventObjectType->Close = NULL;
90 ExEventObjectType->Delete = NULL;
91 ExEventObjectType->Parse = NULL;
92 ExEventObjectType->Security = NULL;
93 ExEventObjectType->QueryName = NULL;
94 ExEventObjectType->OkayToClose = NULL;
95 ExEventObjectType->Create = NtpCreateEvent;
96 ExEventObjectType->DuplicationNotify = NULL;
101 NtClearEvent(IN HANDLE EventHandle)
106 Status = ObReferenceObjectByHandle(EventHandle,
112 if (!NT_SUCCESS(Status))
117 ObDereferenceObject(Event);
118 return(STATUS_SUCCESS);
126 NtCreateEvent(OUT PHANDLE UnsafeEventHandle,
127 IN ACCESS_MASK DesiredAccess,
128 IN POBJECT_ATTRIBUTES UnsafeObjectAttributes,
129 IN BOOLEAN ManualReset,
130 IN BOOLEAN InitialState)
135 OBJECT_ATTRIBUTES SafeObjectAttributes;
136 POBJECT_ATTRIBUTES ObjectAttributes;
138 if (UnsafeObjectAttributes != NULL)
140 Status = MmCopyFromCaller(&SafeObjectAttributes, UnsafeObjectAttributes,
141 sizeof(OBJECT_ATTRIBUTES));
142 if (!NT_SUCCESS(Status))
146 ObjectAttributes = &SafeObjectAttributes;
150 ObjectAttributes = NULL;
153 Status = ObRosCreateObject(&EventHandle,
158 if (!NT_SUCCESS(Status))
162 KeInitializeEvent(Event,
163 ManualReset ? NotificationEvent : SynchronizationEvent,
165 ObDereferenceObject(Event);
167 Status = MmCopyToCaller(UnsafeEventHandle, &EventHandle, sizeof(HANDLE));
168 if (!NT_SUCCESS(Status))
170 ZwClose(EventHandle);
173 return(STATUS_SUCCESS);
178 NtOpenEvent(OUT PHANDLE UnsafeEventHandle,
179 IN ACCESS_MASK DesiredAccess,
180 IN POBJECT_ATTRIBUTES ObjectAttributes)
185 DPRINT("ObjectName '%wZ'\n", ObjectAttributes->ObjectName);
187 Status = ObOpenObjectByName(ObjectAttributes,
195 Status = MmCopyToCaller(UnsafeEventHandle, &EventHandle, sizeof(HANDLE));
196 if (!NT_SUCCESS(Status))
198 ZwClose(EventHandle);
207 NtPulseEvent(IN HANDLE EventHandle,
208 IN PULONG UnsafePulseCount OPTIONAL)
213 DPRINT("NtPulseEvent(EventHandle %x UnsafePulseCount %x)\n",
214 EventHandle, UnsafePulseCount);
216 Status = ObReferenceObjectByHandle(EventHandle,
222 if (!NT_SUCCESS(Status))
227 KePulseEvent(Event, EVENT_INCREMENT, FALSE);
229 ObDereferenceObject(Event);
230 return(STATUS_SUCCESS);
235 NtQueryEvent(IN HANDLE EventHandle,
236 IN EVENT_INFORMATION_CLASS EventInformationClass,
237 OUT PVOID UnsafeEventInformation,
238 IN ULONG EventInformationLength,
239 OUT PULONG UnsafeReturnLength)
241 EVENT_BASIC_INFORMATION Info;
246 if (EventInformationClass > EventBasicInformation)
247 return STATUS_INVALID_INFO_CLASS;
249 if (EventInformationLength < sizeof(EVENT_BASIC_INFORMATION))
250 return STATUS_INFO_LENGTH_MISMATCH;
252 Status = ObReferenceObjectByHandle(EventHandle,
258 if (!NT_SUCCESS(Status))
261 if (Event->Header.Type == InternalNotificationEvent)
262 Info.EventType = NotificationEvent;
264 Info.EventType = SynchronizationEvent;
265 Info.EventState = KeReadStateEvent(Event);
267 Status = MmCopyToCaller(UnsafeEventInformation, &Event,
268 sizeof(EVENT_BASIC_INFORMATION));
269 if (!NT_SUCCESS(Status))
271 ObDereferenceObject(Event);
275 ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
276 Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
277 if (!NT_SUCCESS(Status))
279 ObDereferenceObject(Event);
283 ObDereferenceObject(Event);
285 return(STATUS_SUCCESS);
290 NtResetEvent(IN HANDLE EventHandle,
291 OUT PULONG UnsafeNumberOfWaitingThreads OPTIONAL)
296 DPRINT("NtResetEvent(EventHandle %x)\n", EventHandle);
298 Status = ObReferenceObjectByHandle(EventHandle,
304 if (!NT_SUCCESS(Status))
309 ObDereferenceObject(Event);
310 return(STATUS_SUCCESS);
318 NtSetEvent(IN HANDLE EventHandle,
319 OUT PULONG UnsafeNumberOfThreadsReleased)
324 DPRINT("NtSetEvent(EventHandle %x)\n", EventHandle);
326 Status = ObReferenceObjectByHandle(EventHandle,
332 if (!NT_SUCCESS(Status))
336 KeSetEvent(Event,EVENT_INCREMENT,FALSE);
337 ObDereferenceObject(Event);
338 return(STATUS_SUCCESS);