merge ROS Shell without integrated explorer part into trunk
[reactos.git] / reactos / ntoskrnl / ex / evtpair.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ex/evtpair.c
5 * PURPOSE: Support for event pairs
6 *
7 * PROGRAMMERS: Alex Ionescu (Commented, reorganized, removed Thread Pair, used
8 * KeInitializeEventPair, added SEH)
9 * David Welch (welch@mcmail.com)
10 * Skywing (skywing@valhallalegends.com)
11 */
12
13 /* INCLUDES *****************************************************************/
14
15 #include <ntoskrnl.h>
16 #define NDEBUG
17 #include <internal/debug.h>
18
19 /* GLOBALS *******************************************************************/
20
21 POBJECT_TYPE EXPORTED ExEventPairObjectType = NULL;
22
23 static GENERIC_MAPPING ExEventPairMapping = {
24 STANDARD_RIGHTS_READ,
25 STANDARD_RIGHTS_WRITE,
26 STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
27 EVENT_PAIR_ALL_ACCESS};
28
29
30 /* FUNCTIONS *****************************************************************/
31
32 VOID
33 INIT_FUNCTION
34 ExpInitializeEventPairImplementation(VOID)
35 {
36 /* Create the Event Pair Object Type */
37 ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
38 RtlInitUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair");
39 ExEventPairObjectType->Tag = TAG('E', 'v', 'P', 'a');
40 ExEventPairObjectType->PeakObjects = 0;
41 ExEventPairObjectType->PeakHandles = 0;
42 ExEventPairObjectType->TotalObjects = 0;
43 ExEventPairObjectType->TotalHandles = 0;
44 ExEventPairObjectType->PagedPoolCharge = 0;
45 ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
46 ExEventPairObjectType->Mapping = &ExEventPairMapping;
47 ExEventPairObjectType->Dump = NULL;
48 ExEventPairObjectType->Open = NULL;
49 ExEventPairObjectType->Close = NULL;
50 ExEventPairObjectType->Delete = NULL;
51 ExEventPairObjectType->Parse = NULL;
52 ExEventPairObjectType->Security = NULL;
53 ExEventPairObjectType->QueryName = NULL;
54 ExEventPairObjectType->OkayToClose = NULL;
55 ExEventPairObjectType->Create = NULL;
56 ExEventPairObjectType->DuplicationNotify = NULL;
57 ObpCreateTypeObject(ExEventPairObjectType);
58 }
59
60 NTSTATUS
61 STDCALL
62 NtCreateEventPair(OUT PHANDLE EventPairHandle,
63 IN ACCESS_MASK DesiredAccess,
64 IN POBJECT_ATTRIBUTES ObjectAttributes)
65 {
66 PKEVENT_PAIR EventPair;
67 HANDLE hEventPair;
68 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
69 NTSTATUS Status = STATUS_SUCCESS;
70
71 PAGED_CODE();
72 DPRINT("NtCreateEventPair: %x\n", EventPairHandle);
73
74 /* Check Output Safety */
75 if(PreviousMode == UserMode) {
76
77 _SEH_TRY {
78
79 ProbeForWrite(EventPairHandle,
80 sizeof(HANDLE),
81 sizeof(ULONG));
82 } _SEH_HANDLE {
83
84 Status = _SEH_GetExceptionCode();
85
86 } _SEH_END;
87
88 if(!NT_SUCCESS(Status)) return Status;
89 }
90
91 /* Create the Object */
92 DPRINT("Creating EventPair\n");
93 Status = ObCreateObject(PreviousMode,
94 ExEventPairObjectType,
95 ObjectAttributes,
96 PreviousMode,
97 NULL,
98 sizeof(KEVENT_PAIR),
99 0,
100 0,
101 (PVOID*)&EventPair);
102
103 /* Check for Success */
104 if(NT_SUCCESS(Status)) {
105
106 /* Initalize the Event */
107 DPRINT("Initializing EventPair\n");
108 KeInitializeEventPair(EventPair);
109
110 /* Insert it */
111 Status = ObInsertObject((PVOID)EventPair,
112 NULL,
113 DesiredAccess,
114 0,
115 NULL,
116 &hEventPair);
117 ObDereferenceObject(EventPair);
118
119 /* Check for success and return handle */
120 if(NT_SUCCESS(Status)) {
121
122 _SEH_TRY {
123
124 *EventPairHandle = hEventPair;
125
126 } _SEH_HANDLE {
127
128 Status = _SEH_GetExceptionCode();
129
130 } _SEH_END;
131 }
132 }
133
134 /* Return Status */
135 return Status;
136 }
137
138 NTSTATUS
139 STDCALL
140 NtOpenEventPair(OUT PHANDLE EventPairHandle,
141 IN ACCESS_MASK DesiredAccess,
142 IN POBJECT_ATTRIBUTES ObjectAttributes)
143 {
144 HANDLE hEventPair;
145 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
146 NTSTATUS Status = STATUS_SUCCESS;
147
148 PAGED_CODE();
149
150 /* Check Output Safety */
151 if(PreviousMode == UserMode) {
152
153 _SEH_TRY {
154
155 ProbeForWrite(EventPairHandle,
156 sizeof(HANDLE),
157 sizeof(ULONG));
158 } _SEH_HANDLE {
159
160 Status = _SEH_GetExceptionCode();
161
162 } _SEH_END;
163
164 if(!NT_SUCCESS(Status)) return Status;
165 }
166
167 /* Open the Object */
168 Status = ObOpenObjectByName(ObjectAttributes,
169 ExEventPairObjectType,
170 NULL,
171 PreviousMode,
172 DesiredAccess,
173 NULL,
174 &hEventPair);
175
176 /* Check for success and return handle */
177 if(NT_SUCCESS(Status)) {
178
179 _SEH_TRY {
180
181 *EventPairHandle = hEventPair;
182
183 } _SEH_HANDLE {
184
185 Status = _SEH_GetExceptionCode();
186
187 } _SEH_END;
188 }
189
190 /* Return status */
191 return Status;
192 }
193
194
195 NTSTATUS
196 STDCALL
197 NtSetHighEventPair(IN HANDLE EventPairHandle)
198 {
199 PKEVENT_PAIR EventPair;
200 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
201 NTSTATUS Status;
202
203 PAGED_CODE();
204 DPRINT("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
205
206 /* Open the Object */
207 Status = ObReferenceObjectByHandle(EventPairHandle,
208 SYNCHRONIZE,
209 ExEventPairObjectType,
210 PreviousMode,
211 (PVOID*)&EventPair,
212 NULL);
213
214 /* Check for Success */
215 if(NT_SUCCESS(Status)) {
216
217 /* Set the Event */
218 KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
219
220 /* Dereference Object */
221 ObDereferenceObject(EventPair);
222 }
223
224 /* Return status */
225 return Status;
226 }
227
228 NTSTATUS
229 STDCALL
230 NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
231 {
232 PKEVENT_PAIR EventPair;
233 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
234 NTSTATUS Status;
235
236 PAGED_CODE();
237 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
238
239 /* Open the Object */
240 Status = ObReferenceObjectByHandle(EventPairHandle,
241 SYNCHRONIZE,
242 ExEventPairObjectType,
243 PreviousMode,
244 (PVOID*)&EventPair,
245 NULL);
246
247 /* Check for Success */
248 if(NT_SUCCESS(Status)) {
249
250 /* Set the Event */
251 KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
252
253 /* Wait for the Other one */
254 KeWaitForSingleObject(&EventPair->LowEvent,
255 WrEventPair,
256 PreviousMode,
257 FALSE,
258 NULL);
259
260 /* Dereference Object */
261 ObDereferenceObject(EventPair);
262 }
263
264 /* Return status */
265 return Status;
266 }
267
268 NTSTATUS
269 STDCALL
270 NtSetLowEventPair(IN HANDLE EventPairHandle)
271 {
272 PKEVENT_PAIR EventPair;
273 KPROCESSOR_MODE PreviousMode;
274 NTSTATUS Status;
275
276 PAGED_CODE();
277
278 PreviousMode = ExGetPreviousMode();
279
280 DPRINT1("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
281
282 /* Open the Object */
283 Status = ObReferenceObjectByHandle(EventPairHandle,
284 SYNCHRONIZE,
285 ExEventPairObjectType,
286 PreviousMode,
287 (PVOID*)&EventPair,
288 NULL);
289
290 /* Check for Success */
291 if(NT_SUCCESS(Status)) {
292
293 /* Set the Event */
294 KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
295
296 /* Dereference Object */
297 ObDereferenceObject(EventPair);
298 }
299
300 /* Return status */
301 return Status;
302 }
303
304
305 NTSTATUS STDCALL
306 NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
307 {
308 PKEVENT_PAIR EventPair;
309 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
310 NTSTATUS Status;
311
312 PAGED_CODE();
313 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
314
315 /* Open the Object */
316 Status = ObReferenceObjectByHandle(EventPairHandle,
317 SYNCHRONIZE,
318 ExEventPairObjectType,
319 PreviousMode,
320 (PVOID*)&EventPair,
321 NULL);
322
323 /* Check for Success */
324 if(NT_SUCCESS(Status)) {
325
326 /* Set the Event */
327 KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
328
329 /* Wait for the Other one */
330 KeWaitForSingleObject(&EventPair->HighEvent,
331 WrEventPair,
332 PreviousMode,
333 FALSE,
334 NULL);
335
336 /* Dereference Object */
337 ObDereferenceObject(EventPair);
338 }
339
340 /* Return status */
341 return Status;
342 }
343
344
345 NTSTATUS
346 STDCALL
347 NtWaitLowEventPair(IN HANDLE EventPairHandle)
348 {
349 PKEVENT_PAIR EventPair;
350 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
351 NTSTATUS Status;
352
353 PAGED_CODE();
354 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
355
356 /* Open the Object */
357 Status = ObReferenceObjectByHandle(EventPairHandle,
358 SYNCHRONIZE,
359 ExEventPairObjectType,
360 PreviousMode,
361 (PVOID*)&EventPair,
362 NULL);
363
364 /* Check for Success */
365 if(NT_SUCCESS(Status)) {
366
367 /* Wait for the Event */
368 KeWaitForSingleObject(&EventPair->LowEvent,
369 WrEventPair,
370 PreviousMode,
371 FALSE,
372 NULL);
373
374 /* Dereference Object */
375 ObDereferenceObject(EventPair);
376 }
377
378 /* Return status */
379 return Status;
380 }
381
382 NTSTATUS
383 STDCALL
384 NtWaitHighEventPair(IN HANDLE EventPairHandle)
385 {
386 PKEVENT_PAIR EventPair;
387 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
388 NTSTATUS Status;
389
390 PAGED_CODE();
391 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
392
393 /* Open the Object */
394 Status = ObReferenceObjectByHandle(EventPairHandle,
395 SYNCHRONIZE,
396 ExEventPairObjectType,
397 PreviousMode,
398 (PVOID*)&EventPair,
399 NULL);
400
401 /* Check for Success */
402 if(NT_SUCCESS(Status)) {
403
404 /* Wait for the Event */
405 KeWaitForSingleObject(&EventPair->HighEvent,
406 WrEventPair,
407 PreviousMode,
408 FALSE,
409 NULL);
410
411 /* Dereference Object */
412 ObDereferenceObject(EventPair);
413 }
414
415 /* Return status */
416 return Status;
417 }
418
419 /* EOF */