:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / ntoskrnl / nt / evtpair.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            ntoskrnl/nt/evtpair.c
6  * PURPOSE:         Support for event pairs
7  * PROGRAMMER:      David Welch (welch@mcmail.com)
8  * UPDATE HISTORY:
9  *                  Created 22/05/98
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <ntos/synch.h>
16 #include <limits.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21
22 /* GLOBALS *******************************************************************/
23
24 POBJECT_TYPE EXPORTED ExEventPairObjectType = NULL;
25
26 static GENERIC_MAPPING ExEventPairMapping = {
27         STANDARD_RIGHTS_READ,
28         STANDARD_RIGHTS_WRITE,
29         STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
30         EVENT_PAIR_ALL_ACCESS};
31
32 /* FUNCTIONS *****************************************************************/
33
34 NTSTATUS STDCALL
35 NtpCreateEventPair(PVOID ObjectBody,
36                    PVOID Parent,
37                    PWSTR RemainingPath,
38                    POBJECT_ATTRIBUTES ObjectAttributes)
39 {
40   DPRINT("NtpCreateEventPair(ObjectBody %x, Parent %x, RemainingPath %S)\n",
41          ObjectBody, Parent, RemainingPath);
42
43   if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
44     {
45       return(STATUS_UNSUCCESSFUL);
46     }
47   
48   return(STATUS_SUCCESS);
49 }
50
51 VOID NtInitializeEventPairImplementation(VOID)
52 {
53    ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
54    
55    RtlCreateUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair");
56    
57    ExEventPairObjectType->MaxObjects = ULONG_MAX;
58    ExEventPairObjectType->MaxHandles = ULONG_MAX;
59    ExEventPairObjectType->TotalObjects = 0;
60    ExEventPairObjectType->TotalHandles = 0;
61    ExEventPairObjectType->PagedPoolCharge = 0;
62    ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
63    ExEventPairObjectType->Mapping = &ExEventPairMapping;
64    ExEventPairObjectType->Dump = NULL;
65    ExEventPairObjectType->Open = NULL;
66    ExEventPairObjectType->Close = NULL;
67    ExEventPairObjectType->Delete = NULL;
68    ExEventPairObjectType->Parse = NULL;
69    ExEventPairObjectType->Security = NULL;
70    ExEventPairObjectType->QueryName = NULL;
71    ExEventPairObjectType->OkayToClose = NULL;
72    ExEventPairObjectType->Create = NtpCreateEventPair;
73    ExEventPairObjectType->DuplicationNotify = NULL;
74 }
75
76
77 NTSTATUS STDCALL
78 NtCreateEventPair(OUT PHANDLE EventPairHandle,
79                   IN ACCESS_MASK DesiredAccess,
80                   IN POBJECT_ATTRIBUTES ObjectAttributes)
81 {
82    PKEVENT_PAIR EventPair;
83    NTSTATUS Status;
84
85    DPRINT("NtCreateEventPair()\n");
86    Status = ObCreateObject(EventPairHandle,
87                            DesiredAccess,
88                            ObjectAttributes,
89                            ExEventPairObjectType,
90                            (PVOID*)&EventPair);
91    if (!NT_SUCCESS(Status))
92      {
93         return(Status);
94      }
95    KeInitializeEvent(&EventPair->LowEvent,
96                      SynchronizationEvent,
97                      FALSE);
98    KeInitializeEvent(&EventPair->HighEvent,
99                      SynchronizationEvent,
100                      FALSE);
101    ObDereferenceObject(EventPair);
102    return(STATUS_SUCCESS);
103 }
104
105
106 NTSTATUS STDCALL
107 NtOpenEventPair(OUT PHANDLE EventPairHandle,
108                 IN ACCESS_MASK DesiredAccess,
109                 IN POBJECT_ATTRIBUTES ObjectAttributes)
110 {
111    NTSTATUS Status;
112
113    DPRINT("NtOpenEventPair()\n");
114
115    Status = ObOpenObjectByName(ObjectAttributes,
116                                ExEventPairObjectType,
117                                NULL,
118                                UserMode,
119                                DesiredAccess,
120                                NULL,
121                                EventPairHandle);
122
123    return Status;
124 }
125
126
127 NTSTATUS STDCALL
128 NtSetHighEventPair(IN HANDLE EventPairHandle)
129 {
130    PKEVENT_PAIR EventPair;
131    NTSTATUS Status;
132
133    DPRINT("NtSetHighEventPair(EventPairHandle %x)\n",
134           EventPairHandle);
135
136    Status = ObReferenceObjectByHandle(EventPairHandle,
137                                       EVENT_PAIR_ALL_ACCESS,
138                                       ExEventPairObjectType,
139                                       UserMode,
140                                       (PVOID*)&EventPair,
141                                       NULL);
142    if (!NT_SUCCESS(Status))
143      return(Status);
144
145    KeSetEvent(&EventPair->HighEvent,
146               EVENT_INCREMENT,
147               FALSE);
148
149    ObDereferenceObject(EventPair);
150    return(STATUS_SUCCESS);
151 }
152
153
154 NTSTATUS STDCALL
155 NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
156 {
157    PKEVENT_PAIR EventPair;
158    NTSTATUS Status;
159
160    DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n",
161           EventPairHandle);
162
163    Status = ObReferenceObjectByHandle(EventPairHandle,
164                                       EVENT_PAIR_ALL_ACCESS,
165                                       ExEventPairObjectType,
166                                       UserMode,
167                                       (PVOID*)&EventPair,
168                                       NULL);
169    if (!NT_SUCCESS(Status))
170      return(Status);
171
172    KeSetEvent(&EventPair->HighEvent,
173               EVENT_INCREMENT,
174               FALSE);
175
176    KeWaitForSingleObject(&EventPair->LowEvent,
177                          WrEventPair,
178                          UserMode,
179                          FALSE,
180                          NULL);
181
182    ObDereferenceObject(EventPair);
183    return(STATUS_SUCCESS);
184 }
185
186
187 NTSTATUS STDCALL
188 NtSetLowEventPair(IN HANDLE EventPairHandle)
189 {
190    PKEVENT_PAIR EventPair;
191    NTSTATUS Status;
192
193    DPRINT("NtSetLowEventPair(EventPairHandle %x)\n",
194           EventPairHandle);
195
196    Status = ObReferenceObjectByHandle(EventPairHandle,
197                                       EVENT_PAIR_ALL_ACCESS,
198                                       ExEventPairObjectType,
199                                       UserMode,
200                                       (PVOID*)&EventPair,
201                                       NULL);
202    if (!NT_SUCCESS(Status))
203      return(Status);
204
205    KeSetEvent(&EventPair->LowEvent,
206               EVENT_INCREMENT,
207               FALSE);
208
209    ObDereferenceObject(EventPair);
210    return(STATUS_SUCCESS);
211 }
212
213
214 NTSTATUS STDCALL
215 NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
216 {
217    PKEVENT_PAIR EventPair;
218    NTSTATUS Status;
219
220    DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n",
221           EventPairHandle);
222
223    Status = ObReferenceObjectByHandle(EventPairHandle,
224                                       EVENT_PAIR_ALL_ACCESS,
225                                       ExEventPairObjectType,
226                                       UserMode,
227                                       (PVOID*)&EventPair,
228                                       NULL);
229    if (!NT_SUCCESS(Status))
230      return(Status);
231
232    KeSetEvent(&EventPair->LowEvent,
233               EVENT_INCREMENT,
234               FALSE);
235
236    KeWaitForSingleObject(&EventPair->HighEvent,
237                          WrEventPair,
238                          UserMode,
239                          FALSE,
240                          NULL);
241
242    ObDereferenceObject(EventPair);
243    return(STATUS_SUCCESS);
244 }
245
246
247 NTSTATUS STDCALL
248 NtWaitLowEventPair(IN HANDLE EventPairHandle)
249 {
250    PKEVENT_PAIR EventPair;
251    NTSTATUS Status;
252
253    DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n",
254           EventPairHandle);
255
256    Status = ObReferenceObjectByHandle(EventPairHandle,
257                                       EVENT_PAIR_ALL_ACCESS,
258                                       ExEventPairObjectType,
259                                       UserMode,
260                                       (PVOID*)&EventPair,
261                                       NULL);
262    if (!NT_SUCCESS(Status))
263      return(Status);
264
265    KeWaitForSingleObject(&EventPair->LowEvent,
266                          WrEventPair,
267                          UserMode,
268                          FALSE,
269                          NULL);
270
271    ObDereferenceObject(EventPair);
272    return(STATUS_SUCCESS);
273 }
274
275
276 NTSTATUS STDCALL
277 NtWaitHighEventPair(IN HANDLE EventPairHandle)
278 {
279    PKEVENT_PAIR EventPair;
280    NTSTATUS Status;
281
282    DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n",
283           EventPairHandle);
284
285    Status = ObReferenceObjectByHandle(EventPairHandle,
286                                       EVENT_PAIR_ALL_ACCESS,
287                                       ExEventPairObjectType,
288                                       UserMode,
289                                       (PVOID*)&EventPair,
290                                       NULL);
291    if (!NT_SUCCESS(Status))
292      return(Status);
293
294    KeWaitForSingleObject(&EventPair->HighEvent,
295                          WrEventPair,
296                          UserMode,
297                          FALSE,
298                          NULL);
299
300    ObDereferenceObject(EventPair);
301    return(STATUS_SUCCESS);
302 }
303
304 /* EOF */