- Remove unused ldr/userldr.c
[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 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 STDCALL
35 ExpInitializeEventPairImplementation(VOID)
36 {
37 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
38 UNICODE_STRING Name;
39
40 DPRINT("Creating Event Pair Object Type\n");
41
42 /* Create the Event Pair Object Type */
43 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
44 RtlInitUnicodeString(&Name, L"EventPair");
45 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
46 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KEVENT_PAIR);
47 ObjectTypeInitializer.GenericMapping = ExEventPairMapping;
48 ObjectTypeInitializer.PoolType = NonPagedPool;
49 ObjectTypeInitializer.ValidAccessMask = EVENT_PAIR_ALL_ACCESS;
50 ObjectTypeInitializer.UseDefaultObject = TRUE;
51 ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &ExEventPairObjectType);
52 }
53
54 NTSTATUS
55 STDCALL
56 NtCreateEventPair(OUT PHANDLE EventPairHandle,
57 IN ACCESS_MASK DesiredAccess,
58 IN POBJECT_ATTRIBUTES ObjectAttributes)
59 {
60 PKEVENT_PAIR EventPair;
61 HANDLE hEventPair;
62 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
63 NTSTATUS Status = STATUS_SUCCESS;
64
65 PAGED_CODE();
66 DPRINT("NtCreateEventPair: 0x%p\n", EventPairHandle);
67
68 /* Check Output Safety */
69 if(PreviousMode == UserMode) {
70
71 _SEH_TRY {
72
73 ProbeForWrite(EventPairHandle,
74 sizeof(HANDLE),
75 sizeof(ULONG));
76 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
77
78 Status = _SEH_GetExceptionCode();
79
80 } _SEH_END;
81
82 if(!NT_SUCCESS(Status)) return Status;
83 }
84
85 /* Create the Object */
86 DPRINT("Creating EventPair\n");
87 Status = ObCreateObject(PreviousMode,
88 ExEventPairObjectType,
89 ObjectAttributes,
90 PreviousMode,
91 NULL,
92 sizeof(KEVENT_PAIR),
93 0,
94 0,
95 (PVOID*)&EventPair);
96
97 /* Check for Success */
98 if(NT_SUCCESS(Status)) {
99
100 /* Initalize the Event */
101 DPRINT("Initializing EventPair\n");
102 KeInitializeEventPair(EventPair);
103
104 /* Insert it */
105 Status = ObInsertObject((PVOID)EventPair,
106 NULL,
107 DesiredAccess,
108 0,
109 NULL,
110 &hEventPair);
111 ObDereferenceObject(EventPair);
112
113 /* Check for success and return handle */
114 if(NT_SUCCESS(Status)) {
115
116 _SEH_TRY {
117
118 *EventPairHandle = hEventPair;
119
120 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
121
122 Status = _SEH_GetExceptionCode();
123
124 } _SEH_END;
125 }
126 }
127
128 /* Return Status */
129 return Status;
130 }
131
132 NTSTATUS
133 STDCALL
134 NtOpenEventPair(OUT PHANDLE EventPairHandle,
135 IN ACCESS_MASK DesiredAccess,
136 IN POBJECT_ATTRIBUTES ObjectAttributes)
137 {
138 HANDLE hEventPair;
139 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
140 NTSTATUS Status = STATUS_SUCCESS;
141
142 PAGED_CODE();
143
144 /* Check Output Safety */
145 if(PreviousMode == UserMode) {
146
147 _SEH_TRY {
148
149 ProbeForWrite(EventPairHandle,
150 sizeof(HANDLE),
151 sizeof(ULONG));
152 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
153
154 Status = _SEH_GetExceptionCode();
155
156 } _SEH_END;
157
158 if(!NT_SUCCESS(Status)) return Status;
159 }
160
161 /* Open the Object */
162 Status = ObOpenObjectByName(ObjectAttributes,
163 ExEventPairObjectType,
164 NULL,
165 PreviousMode,
166 DesiredAccess,
167 NULL,
168 &hEventPair);
169
170 /* Check for success and return handle */
171 if(NT_SUCCESS(Status)) {
172
173 _SEH_TRY {
174
175 *EventPairHandle = hEventPair;
176
177 } _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
178
179 Status = _SEH_GetExceptionCode();
180
181 } _SEH_END;
182 }
183
184 /* Return status */
185 return Status;
186 }
187
188
189 NTSTATUS
190 STDCALL
191 NtSetHighEventPair(IN HANDLE EventPairHandle)
192 {
193 PKEVENT_PAIR EventPair;
194 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
195 NTSTATUS Status;
196
197 PAGED_CODE();
198 DPRINT("NtSetHighEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
199
200 /* Open the Object */
201 Status = ObReferenceObjectByHandle(EventPairHandle,
202 SYNCHRONIZE,
203 ExEventPairObjectType,
204 PreviousMode,
205 (PVOID*)&EventPair,
206 NULL);
207
208 /* Check for Success */
209 if(NT_SUCCESS(Status)) {
210
211 /* Set the Event */
212 KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
213
214 /* Dereference Object */
215 ObDereferenceObject(EventPair);
216 }
217
218 /* Return status */
219 return Status;
220 }
221
222 NTSTATUS
223 STDCALL
224 NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
225 {
226 PKEVENT_PAIR EventPair;
227 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
228 NTSTATUS Status;
229
230 PAGED_CODE();
231 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
232
233 /* Open the Object */
234 Status = ObReferenceObjectByHandle(EventPairHandle,
235 SYNCHRONIZE,
236 ExEventPairObjectType,
237 PreviousMode,
238 (PVOID*)&EventPair,
239 NULL);
240
241 /* Check for Success */
242 if(NT_SUCCESS(Status)) {
243
244 /* Set the Event */
245 KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
246
247 /* Wait for the Other one */
248 KeWaitForSingleObject(&EventPair->LowEvent,
249 WrEventPair,
250 PreviousMode,
251 FALSE,
252 NULL);
253
254 /* Dereference Object */
255 ObDereferenceObject(EventPair);
256 }
257
258 /* Return status */
259 return Status;
260 }
261
262 NTSTATUS
263 STDCALL
264 NtSetLowEventPair(IN HANDLE EventPairHandle)
265 {
266 PKEVENT_PAIR EventPair;
267 KPROCESSOR_MODE PreviousMode;
268 NTSTATUS Status;
269
270 PAGED_CODE();
271
272 PreviousMode = ExGetPreviousMode();
273
274 DPRINT1("NtSetHighEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
275
276 /* Open the Object */
277 Status = ObReferenceObjectByHandle(EventPairHandle,
278 SYNCHRONIZE,
279 ExEventPairObjectType,
280 PreviousMode,
281 (PVOID*)&EventPair,
282 NULL);
283
284 /* Check for Success */
285 if(NT_SUCCESS(Status)) {
286
287 /* Set the Event */
288 KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
289
290 /* Dereference Object */
291 ObDereferenceObject(EventPair);
292 }
293
294 /* Return status */
295 return Status;
296 }
297
298
299 NTSTATUS STDCALL
300 NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
301 {
302 PKEVENT_PAIR EventPair;
303 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
304 NTSTATUS Status;
305
306 PAGED_CODE();
307 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
308
309 /* Open the Object */
310 Status = ObReferenceObjectByHandle(EventPairHandle,
311 SYNCHRONIZE,
312 ExEventPairObjectType,
313 PreviousMode,
314 (PVOID*)&EventPair,
315 NULL);
316
317 /* Check for Success */
318 if(NT_SUCCESS(Status)) {
319
320 /* Set the Event */
321 KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
322
323 /* Wait for the Other one */
324 KeWaitForSingleObject(&EventPair->HighEvent,
325 WrEventPair,
326 PreviousMode,
327 FALSE,
328 NULL);
329
330 /* Dereference Object */
331 ObDereferenceObject(EventPair);
332 }
333
334 /* Return status */
335 return Status;
336 }
337
338
339 NTSTATUS
340 STDCALL
341 NtWaitLowEventPair(IN HANDLE EventPairHandle)
342 {
343 PKEVENT_PAIR EventPair;
344 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
345 NTSTATUS Status;
346
347 PAGED_CODE();
348 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
349
350 /* Open the Object */
351 Status = ObReferenceObjectByHandle(EventPairHandle,
352 SYNCHRONIZE,
353 ExEventPairObjectType,
354 PreviousMode,
355 (PVOID*)&EventPair,
356 NULL);
357
358 /* Check for Success */
359 if(NT_SUCCESS(Status)) {
360
361 /* Wait for the Event */
362 KeWaitForSingleObject(&EventPair->LowEvent,
363 WrEventPair,
364 PreviousMode,
365 FALSE,
366 NULL);
367
368 /* Dereference Object */
369 ObDereferenceObject(EventPair);
370 }
371
372 /* Return status */
373 return Status;
374 }
375
376 NTSTATUS
377 STDCALL
378 NtWaitHighEventPair(IN HANDLE EventPairHandle)
379 {
380 PKEVENT_PAIR EventPair;
381 KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
382 NTSTATUS Status;
383
384 PAGED_CODE();
385 DPRINT("NtSetHighWaitLowEventPair(EventPairHandle 0x%p)\n", EventPairHandle);
386
387 /* Open the Object */
388 Status = ObReferenceObjectByHandle(EventPairHandle,
389 SYNCHRONIZE,
390 ExEventPairObjectType,
391 PreviousMode,
392 (PVOID*)&EventPair,
393 NULL);
394
395 /* Check for Success */
396 if(NT_SUCCESS(Status)) {
397
398 /* Wait for the Event */
399 KeWaitForSingleObject(&EventPair->HighEvent,
400 WrEventPair,
401 PreviousMode,
402 FALSE,
403 NULL);
404
405 /* Dereference Object */
406 ObDereferenceObject(EventPair);
407 }
408
409 /* Return status */
410 return Status;
411 }
412
413 /* EOF */