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
);