ReactOS 0.4.17-dev-357-ga8f14ff
keyedevt.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/ex/keyedevt.c
5 * PURPOSE: Support for keyed events
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* INTERNAL TYPES *************************************************************/
16
17#define NUM_KEY_HASH_BUCKETS 23
18typedef struct _EX_KEYED_EVENT
19{
20 struct
21 {
27
28/* GLOBALS *******************************************************************/
29
32
33static
35{
40};
41
42/* FUNCTIONS *****************************************************************/
43
45CODE_SEG("INIT")
49{
50 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer = {0};
51 UNICODE_STRING TypeName = RTL_CONSTANT_STRING(L"KeyedEvent");
52 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\KernelObjects\\CritSecOutOfMemoryEvent");
56
57 /* Set up the object type initializer */
58 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
59 ObjectTypeInitializer.GenericMapping = ExpKeyedEventMapping;
60 ObjectTypeInitializer.PoolType = PagedPool;
61 ObjectTypeInitializer.ValidAccessMask = KEYEDEVENT_ALL_ACCESS;
62 ObjectTypeInitializer.UseDefaultObject = TRUE;
63
64 /* Create the keyed event object type */
65 Status = ObCreateObjectType(&TypeName,
66 &ObjectTypeInitializer,
67 NULL,
69 if (!NT_SUCCESS(Status)) return FALSE;
70
71 /* Create the out of memory event for critical sections */
73 Status = ZwCreateKeyedEvent(&EventHandle,
76 0);
77 if (NT_SUCCESS(Status))
78 {
79 /* Take a reference so we can get rid of the handle */
85 NULL);
87 return TRUE;
88 }
89
90 return FALSE;
91}
92
93VOID
96 _Out_ PEX_KEYED_EVENT KeyedEvent)
97{
98 ULONG i;
99
100 /* Loop all hash buckets */
101 for (i = 0; i < NUM_KEY_HASH_BUCKETS; i++)
102 {
103 /* Initialize the mutex and the wait lists */
104 ExInitializePushLock(&KeyedEvent->HashTable[i].Lock);
105 InitializeListHead(&KeyedEvent->HashTable[i].WaitListHead);
106 InitializeListHead(&KeyedEvent->HashTable[i].ReleaseListHead);
107 }
108}
109
112NTAPI
113ExpReleaseOrWaitForKeyedEvent(
114 _Inout_ PEX_KEYED_EVENT KeyedEvent,
115 _In_ PVOID KeyedWaitValue,
119{
120 PETHREAD Thread, CurrentThread;
121 PEPROCESS CurrentProcess;
122 PLIST_ENTRY ListEntry, WaitListHead1, WaitListHead2;
124 ULONG_PTR HashIndex;
125 PVOID PreviousKeyedWaitValue;
127
128 /* Get the current process */
129 CurrentProcess = PsGetCurrentProcess();
130
131 /* Calculate the hash index */
132 HashIndex = (ULONG_PTR)KeyedWaitValue >> 5;
133 HashIndex ^= (ULONG_PTR)CurrentProcess >> 6;
134 HashIndex %= NUM_KEY_HASH_BUCKETS;
135
136 /* Lock the lists */
138 ExAcquirePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
139
140 /* Get the lists for search and wait, depending on whether
141 we want to wait for the event or signal it */
142 if (Release)
143 {
144 WaitListHead1 = &KeyedEvent->HashTable[HashIndex].WaitListHead;
145 WaitListHead2 = &KeyedEvent->HashTable[HashIndex].ReleaseListHead;
146 }
147 else
148 {
149 WaitListHead1 = &KeyedEvent->HashTable[HashIndex].ReleaseListHead;
150 WaitListHead2 = &KeyedEvent->HashTable[HashIndex].WaitListHead;
151 }
152
153 /* loop the first wait list */
154 ListEntry = WaitListHead1->Flink;
155 while (ListEntry != WaitListHead1)
156 {
157 /* Get the waiting thread. Note that this thread cannot be terminated
158 as long as we hold the list lock, since it either needs to wait to
159 be signaled by this thread or, when the wait is aborted due to thread
160 termination, then it first needs to acquire the list lock. */
161 Thread = CONTAINING_RECORD(ListEntry, ETHREAD, KeyedWaitChain);
162 ListEntry = ListEntry->Flink;
163
164 /* Check if this thread is a correct waiter */
165 if ((Thread->Tcb.Process == &CurrentProcess->Pcb) &&
166 (Thread->KeyedWaitValue == KeyedWaitValue))
167 {
168 /* Remove the thread from the list */
170
171 /* Initialize the list entry to show that it was removed */
173
174 /* Wake the thread */
177 1,
178 FALSE);
179 Thread = NULL;
180
181 /* Unlock the list. After this it is not safe to access Thread */
182 ExReleasePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
184
185 return STATUS_SUCCESS;
186 }
187 }
188
189 /* Get the current thread */
190 CurrentThread = PsGetCurrentThread();
191
192 /* Set the wait key and remember the old value */
193 PreviousKeyedWaitValue = CurrentThread->KeyedWaitValue;
194 CurrentThread->KeyedWaitValue = KeyedWaitValue;
195
196 /* Initialize the wait semaphore */
197 KeInitializeSemaphore(&CurrentThread->KeyedWaitSemaphore, 0, 1);
198
199 /* Insert the current thread into the secondary wait list */
200 InsertTailList(WaitListHead2, &CurrentThread->KeyedWaitChain);
201
202 /* Unlock the list */
203 ExReleasePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
205
206 /* Wait for the keyed wait semaphore */
211 Alertable,
212 Timeout);
213
214 /* Check if the wait was aborted or timed out */
215 if (Status != STATUS_SUCCESS)
216 {
217 /* Lock the lists to make sure no one else messes with the entry */
219 ExAcquirePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
220
221 /* Check if the wait list entry is still in the list */
222 if (!IsListEmpty(&CurrentThread->KeyedWaitChain))
223 {
224 /* Remove the thread from the list */
225 RemoveEntryList(&CurrentThread->KeyedWaitChain);
226 InitializeListHead(&CurrentThread->KeyedWaitChain);
227 }
228
229 /* Unlock the list */
230 ExReleasePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
232 }
233
234 /* Restore the previous KeyedWaitValue, since this is a union member */
235 CurrentThread->KeyedWaitValue = PreviousKeyedWaitValue;
236
237 return Status;
238}
239
242NTAPI
243ExpWaitForKeyedEvent(
244 _Inout_ PEX_KEYED_EVENT KeyedEvent,
245 _In_ PVOID KeyedWaitValue,
248{
249 /* Call the generic internal function */
250 return ExpReleaseOrWaitForKeyedEvent(KeyedEvent,
251 KeyedWaitValue,
252 Alertable,
253 Timeout,
254 FALSE);
255}
256
259NTAPI
260ExpReleaseKeyedEvent(
261 _Inout_ PEX_KEYED_EVENT KeyedEvent,
262 _In_ PVOID KeyedWaitValue,
265{
266 /* Call the generic internal function */
267 return ExpReleaseOrWaitForKeyedEvent(KeyedEvent,
268 KeyedWaitValue,
269 Alertable,
270 Timeout,
271 TRUE);
272}
273
276NTAPI
278 _Out_ PHANDLE OutHandle,
282{
284 PEX_KEYED_EVENT KeyedEvent;
285 HANDLE KeyedEventHandle;
287
288 /* Check flags */
289 if (Flags != 0)
290 {
291 /* We don't support any flags yet */
293 }
294
295 /* Create the object */
300 NULL,
301 sizeof(EX_KEYED_EVENT),
302 0,
303 0,
304 (PVOID*)&KeyedEvent);
305
306 /* Check for success */
307 if (!NT_SUCCESS(Status)) return Status;
308
309 /* Initialize the keyed event */
310 ExpInitializeKeyedEvent(KeyedEvent);
311
312 /* Insert it */
313 Status = ObInsertObject(KeyedEvent,
314 NULL,
316 0,
317 NULL,
318 &KeyedEventHandle);
319
320 /* Check for success (ObInsertObject dereferences!) */
321 if (!NT_SUCCESS(Status)) return Status;
322
324 {
325 /* Enter SEH for return */
327 {
328 /* Return the handle to the caller */
329 ProbeForWrite(OutHandle, sizeof(HANDLE), sizeof(HANDLE));
330 *OutHandle = KeyedEventHandle;
331 }
333 {
334 /* Get the exception code */
336
337 /* Cleanup */
338 ObCloseHandle(KeyedEventHandle, PreviousMode);
339 }
340 _SEH2_END;
341 }
342 else
343 {
344 *OutHandle = KeyedEventHandle;
345 }
346
347 /* Return Status */
348 return Status;
349}
350
353NTAPI
355 _Out_ PHANDLE OutHandle,
358{
360 HANDLE KeyedEventHandle;
362
363 /* Open the object */
367 NULL,
369 NULL,
370 &KeyedEventHandle);
371
372 /* Check for success */
373 if (!NT_SUCCESS(Status)) return Status;
374
375 /* Enter SEH for return */
377 {
379 {
380 /* Return the handle to the caller */
381 ProbeForWrite(OutHandle, sizeof(HANDLE), sizeof(HANDLE));
382 *OutHandle = KeyedEventHandle;
383 }
385 {
386 /* Get the exception code */
388
389 /* Cleanup */
390 ObCloseHandle(KeyedEventHandle, PreviousMode);
391 }
392 _SEH2_END;
393 }
394 else
395 {
396 *OutHandle = KeyedEventHandle;
397 }
398
399 /* Return status */
400 return Status;
401}
402
405NTAPI
408 _In_ PVOID Key,
411{
413 PEX_KEYED_EVENT KeyedEvent;
415 LARGE_INTEGER TimeoutCopy;
416
417 /* Key must always be two-byte aligned */
418 if ((ULONG_PTR)Key & 1)
419 {
421 }
422
423 /* Check if the caller passed a timeout value and this is from user mode */
424 if ((Timeout != NULL) && (PreviousMode != KernelMode))
425 {
427 {
428 ProbeForRead(Timeout, sizeof(*Timeout), 1);
429 TimeoutCopy = *Timeout;
430 Timeout = &TimeoutCopy;
431 }
433 {
435 }
436 _SEH2_END;
437 }
438
439 /* Check if the caller provided a handle */
440 if (Handle != NULL)
441 {
442 /* Get the keyed event object */
447 (PVOID*)&KeyedEvent,
448 NULL);
449
450 /* Check for success */
451 if (!NT_SUCCESS(Status)) return Status;
452 }
453 else
454 {
455 /* Use the default keyed event for low memory critical sections */
456 KeyedEvent = ExpCritSecOutOfMemoryEvent;
457 }
458
459 /* Do the wait */
460 Status = ExpWaitForKeyedEvent(KeyedEvent, Key, Alertable, Timeout);
461
462 if (Handle != NULL)
463 {
464 /* Dereference the keyed event */
465 ObDereferenceObject(KeyedEvent);
466 }
467
468 /* Return the status */
469 return Status;
470}
471
474NTAPI
477 _In_ PVOID Key,
480{
482 PEX_KEYED_EVENT KeyedEvent;
484 LARGE_INTEGER TimeoutCopy;
485
486 /* Key must always be two-byte aligned */
487 if ((ULONG_PTR)Key & 1)
488 {
490 }
491
492 /* Check if the caller passed a timeout value and this is from user mode */
493 if ((Timeout != NULL) && (PreviousMode != KernelMode))
494 {
496 {
497 ProbeForRead(Timeout, sizeof(*Timeout), 1);
498 TimeoutCopy = *Timeout;
499 Timeout = &TimeoutCopy;
500 }
502 {
504 }
505 _SEH2_END;
506 }
507
508 /* Check if the caller provided a handle */
509 if (Handle != NULL)
510 {
511 /* Get the keyed event object */
516 (PVOID*)&KeyedEvent,
517 NULL);
518
519 /* Check for success */
520 if (!NT_SUCCESS(Status)) return Status;
521 }
522 else
523 {
524 /* Use the default keyed event for low memory critical sections */
525 KeyedEvent = ExpCritSecOutOfMemoryEvent;
526 }
527
528 /* Do the wait */
529 Status = ExpReleaseKeyedEvent(KeyedEvent, Key, Alertable, Timeout);
530
531 if (Handle != NULL)
532 {
533 /* Dereference the keyed event */
534 ObDereferenceObject(KeyedEvent);
535 }
536
537 /* Return the status */
538 return Status;
539}
540
541/* EOF */
#define CODE_SEG(...)
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
_In_ BOOLEAN Release
Definition: cdrom.h:920
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
#define ExInitializePushLock
Definition: ex.h:1016
BOOLEAN NTAPI ExpInitializeKeyedEventImplementation(VOID)
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1039
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1255
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
static GENERIC_MAPPING ExpKeyedEventMapping
Definition: keyedevt.c:34
#define NUM_KEY_HASH_BUCKETS
Definition: keyedevt.c:17
VOID NTAPI ExpInitializeKeyedEvent(_Out_ PEX_KEYED_EVENT KeyedEvent)
Definition: keyedevt.c:95
struct _EX_KEYED_EVENT * PEX_KEYED_EVENT
struct _EX_KEYED_EVENT EX_KEYED_EVENT
PEX_KEYED_EVENT ExpCritSecOutOfMemoryEvent
Definition: keyedevt.c:30
POBJECT_TYPE ExKeyedEventObjectType
Definition: keyedevt.c:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define KeGetPreviousMode()
Definition: ketypes.h:1115
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:453
_In_ ACCESS_MASK AccessMask
Definition: exfuncs.h:186
#define KernelMode
Definition: asm.h:38
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define STANDARD_RIGHTS_READ
Definition: nt_native.h:65
#define STANDARD_RIGHTS_WRITE
Definition: nt_native.h:66
#define STANDARD_RIGHTS_EXECUTE
Definition: nt_native.h:67
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2935
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1039
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define KEYEDEVENT_WAIT
Definition: om.c:103
#define KEYEDEVENT_ALL_ACCESS
Definition: om.c:105
#define KEYEDEVENT_WAKE
Definition: om.c:104
static ULONG Timeout
Definition: ping.c:61
#define OBJ_PERMANENT
Definition: winternl.h:226
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: hash.c:67
KPROCESS Pcb
Definition: pstypes.h:1351
KTHREAD Tcb
Definition: pstypes.h:1187
PVOID KeyedWaitValue
Definition: pstypes.h:1205
KSEMAPHORE KeyedWaitSemaphore
Definition: pstypes.h:1214
LIST_ENTRY KeyedWaitChain
Definition: pstypes.h:1193
EX_PUSH_LOCK Lock
Definition: keyedevt.c:22
LIST_ENTRY WaitListHead
Definition: keyedevt.c:23
LIST_ENTRY ReleaseListHead
Definition: keyedevt.c:24
PKPROCESS Process
Definition: ketypes.h:2055
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS WINAPI NtCreateKeyedEvent(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG)
NTSYSAPI NTSTATUS WINAPI NtOpenKeyedEvent(HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *)
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ WrKeyedEvent
Definition: ketypes.h:488
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17