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