ReactOS 0.4.15-dev-7931-gfd331f1
obwait.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for obwait.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI NtWaitForMultipleObjects (IN ULONG ObjectCount, IN PHANDLE HandleArray, IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL)
 
NTSTATUS NTAPI NtWaitForMultipleObjects32 (IN ULONG ObjectCount, IN PLONG Handles, IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL)
 
NTSTATUS NTAPI NtWaitForSingleObject (IN HANDLE ObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL)
 
NTSTATUS NTAPI NtSignalAndWaitForSingleObject (IN HANDLE ObjectHandleToSignal, IN HANDLE WaitableObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file obwait.c.

Function Documentation

◆ NtSignalAndWaitForSingleObject()

NTSTATUS NTAPI NtSignalAndWaitForSingleObject ( IN HANDLE  ObjectHandleToSignal,
IN HANDLE  WaitableObjectHandle,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

Definition at line 473 of file obwait.c.

477{
480 PVOID SignalObj, WaitObj, WaitableObject;
481 LARGE_INTEGER SafeTimeOut;
482 OBJECT_HANDLE_INFORMATION HandleInfo;
484
485 /* Check if we came with a timeout from user mode */
487 if ((TimeOut) && (PreviousMode != KernelMode))
488 {
489 /* Enter SEH for probing */
491 {
492 /* Make a copy on the stack */
493 SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
494 TimeOut = &SafeTimeOut;
495 }
497 {
498 /* Return the exception code */
500 }
501 _SEH2_END;
502 }
503
504 /* Start by getting the signal object*/
505 Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
506 0,
507 NULL,
509 &SignalObj,
510 &HandleInfo);
511 if (!NT_SUCCESS(Status)) return Status;
512
513 /* Now get the wait object */
514 Status = ObReferenceObjectByHandle(WaitableObjectHandle,
516 NULL,
518 &WaitObj,
519 NULL);
520 if (!NT_SUCCESS(Status))
521 {
522 /* Failed to reference the wait object */
523 ObDereferenceObject(SignalObj);
524 return Status;
525 }
526
527 /* Get the real waitable object */
528 WaitableObject = OBJECT_TO_OBJECT_HEADER(WaitObj)->Type->DefaultObject;
529
530 /* Handle internal offset */
531 if (IsPointerOffset(WaitableObject))
532 {
533 /* Get real pointer */
534 WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
535 (ULONG_PTR)WaitableObject);
536 }
537
538 /* Check Signal Object Type */
539 Type = OBJECT_TO_OBJECT_HEADER(SignalObj)->Type;
540 if (Type == ExEventObjectType)
541 {
542 /* Check if we came from user-mode without the right access */
543 if ((PreviousMode != KernelMode) &&
544 !(HandleInfo.GrantedAccess & EVENT_MODIFY_STATE))
545 {
546 /* Fail: lack of rights */
548 goto Quickie;
549 }
550
551 /* Set the Event */
552 KeSetEvent(SignalObj, EVENT_INCREMENT, TRUE);
553 }
554 else if (Type == ExMutantObjectType)
555 {
556 /* This can raise an exception */
558 {
559 /* Release the mutant */
561 }
566 {
567 /* Get the exception code */
569 }
570 _SEH2_END;
571 }
572 else if (Type == ExSemaphoreObjectType)
573 {
574 /* Check if we came from user-mode without the right access */
575 if ((PreviousMode != KernelMode) &&
577 {
578 /* Fail: lack of rights */
580 goto Quickie;
581 }
582
583 /* This can raise an exception*/
585 {
586 /* Release the semaphore */
588 }
592 {
593 /* Get the exception code */
595 }
596 _SEH2_END;
597 }
598 else
599 {
600 /* This isn't a valid object to be waiting on */
602 }
603
604 /* Make sure we didn't fail */
605 if (NT_SUCCESS(Status))
606 {
607 /* SEH this since it can also raise an exception */
609 {
610 /* Perform the wait now */
611 Status = KeWaitForSingleObject(WaitableObject,
614 Alertable,
615 TimeOut);
616 }
620 {
621 /* Get the exception code */
623 }
624 _SEH2_END;
625 }
626
627 /* We're done here, dereference both objects */
628Quickie:
629 ObDereferenceObject(SignalObj);
630 ObDereferenceObject(WaitObj);
631 return Status;
632}
#define ExMutantObjectType
Definition: ObTypes.c:122
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
#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:32
#define ULONG_PTR
Definition: config.h:101
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define ExGetPreviousMode
Definition: ex.h:140
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define KernelMode
Definition: asm.h:34
_In_ PVOID _In_ BOOLEAN Alertable
Definition: exfuncs.h:453
#define MUTANT_INCREMENT
Definition: extypes.h:84
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
#define SYNCHRONIZE
Definition: nt_native.h:61
POBJECT_TYPE ExEventObjectType
Definition: event.c:18
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define STATUS_MUTANT_LIMIT_EXCEEDED
Definition: ntstatus.h:634
#define STATUS_MUTANT_NOT_OWNED
Definition: ntstatus.h:306
#define STATUS_ABANDONED
Definition: ntstatus.h:75
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED
Definition: ntstatus.h:307
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
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 _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
POBJECT_TYPE ExSemaphoreObjectType
Definition: sem.c:22
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define SEMAPHORE_MODIFY_STATE
Definition: winbase.h:161
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
#define EVENT_INCREMENT
Definition: iotypes.h:597
#define SEMAPHORE_INCREMENT
Definition: iotypes.h:610
@ UserRequest
Definition: ketypes.h:421
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by SignalObjectAndWait().

◆ NtWaitForMultipleObjects()

NTSTATUS NTAPI NtWaitForMultipleObjects ( IN ULONG  ObjectCount,
IN PHANDLE  HandleArray,
IN WAIT_TYPE  WaitType,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

Definition at line 46 of file obwait.c.

51{
55 PVOID WaitObjects[MAXIMUM_WAIT_OBJECTS];
56 ULONG i, ReferencedObjects, j;
58 LARGE_INTEGER SafeTimeOut;
59 BOOLEAN LockInUse;
60 PHANDLE_TABLE_ENTRY HandleEntry;
61 POBJECT_HEADER ObjectHeader;
64 PVOID DefaultObject;
66 PAGED_CODE();
67
68 /* Check for valid Object Count */
70 {
71 /* Fail */
73 }
74
75 /* Check for valid Wait Type */
76 if ((WaitType != WaitAll) && (WaitType != WaitAny))
77 {
78 /* Fail */
80 }
81
82 /* Enter SEH */
85 {
86 /* Probe for user mode */
88 {
89 /* Check if we have a timeout */
90 if (TimeOut)
91 {
92 /* Make a local copy of the timeout on the stack */
93 SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
94 TimeOut = &SafeTimeOut;
95 }
96
97 /* Probe all the handles */
98 ProbeForRead(HandleArray,
99 ObjectCount * sizeof(HANDLE),
100 sizeof(HANDLE));
101 }
102
103 /*
104 * Make a copy so we don't have to guard with SEH later and keep
105 * track of what objects we referenced if dereferencing pointers
106 * suddenly fails
107 */
108 RtlCopyMemory(Handles,
109 HandleArray,
110 ObjectCount * sizeof(HANDLE));
111 }
112 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) //ExSystemExceptionFilter()
113 {
114 /* Cover up for kernel mode */
116 {
117 /* But don't fail silently */
118 DbgPrint("Mon dieu! Covering up for BAD driver passing invalid pointer (0x%p)! Hon hon hon!\n", HandleArray);
119 }
120
121 /* Return the exception code */
123 }
124 _SEH2_END;
125
126 /* Check if we can use the internal Wait Array */
128 {
129 /* Allocate from Pool */
132 sizeof(KWAIT_BLOCK),
133 TAG_WAIT);
134 if (!WaitBlockArray)
135 {
136 /* Fail */
138 }
139 }
140 else
141 {
142 /* No need for the array */
144 }
145
146 /* Enter a critical region since we'll play with handles */
147 LockInUse = TRUE;
149
150 /* Start the loop */
151 i = 0;
152 ReferencedObjects = 0;
153 do
154 {
155 /* Use the right Executive Handle */
156 if (ObpIsKernelHandle(Handles[i], PreviousMode))
157 {
158 /* Use the System Handle Table and decode */
161
162 /* Get a pointer to it */
164 }
165 else
166 {
167 /* Use the Process' Handle table and get the Ex Handle */
168 HandleTable = PsGetCurrentProcess()->ObjectTable;
169
170 /* Get a pointer to it */
171 HandleEntry = ExMapHandleToPointer(HandleTable, Handles[i]);
172 }
173
174 /* Check if we have an entry */
175 if (!HandleEntry)
176 {
177 /* Fail, handle is invalid */
179 DPRINT1("Invalid handle %p passed to NtWaitForMultipleObjects\n", Handles[i]);
180 goto Quickie;
181 }
182
183 /* Check for synchronize access */
184 GrantedAccess = HandleEntry->GrantedAccess;
186 {
187 /* Unlock the entry and fail */
189 DPRINT1("Handle does not have SYNCHRONIZE access\n");
191 goto Quickie;
192 }
193
194 /* Get the Object Header */
195 ObjectHeader = ObpGetHandleObject(HandleEntry);
196
197 /* Get default Object */
198 DefaultObject = ObjectHeader->Type->DefaultObject;
199
200 /* Check if it's the internal offset */
201 if (IsPointerOffset(DefaultObject))
202 {
203 /* Increase reference count */
205 ReferencedObjects++;
206
207 /* Save the Object and Wait Object, this is a relative offset */
208 Objects[i] = &ObjectHeader->Body;
209 WaitObjects[i] = (PVOID)((ULONG_PTR)&ObjectHeader->Body +
210 (ULONG_PTR)DefaultObject);
211 }
212 else
213 {
214 /* This is our internal Object */
215 ReferencedObjects++;
216 Objects[i] = NULL;
217 WaitObjects[i] = DefaultObject;
218 }
219
220 /* Unlock the Handle Table Entry */
222
223 /* Keep looping */
224 i++;
225 } while (i < ObjectCount);
226
227 /* For a Waitall, we can't have the same object more then once */
228 if (WaitType == WaitAll)
229 {
230 /* Clear the main loop variable */
231 i = 0;
232
233 /* Start the loop */
234 do
235 {
236 /* Check the current and forward object */
237 for (j = i + 1; j < ObjectCount; j++)
238 {
239 /* Make sure they don't match */
240 if (WaitObjects[i] == WaitObjects[j])
241 {
242 /* Fail */
244 DPRINT1("Passed a duplicate object to NtWaitForMultipleObjects\n");
245 goto Quickie;
246 }
247 }
248
249 /* Keep looping */
250 i++;
251 } while (i < ObjectCount);
252 }
253
254 /* Now we can finally wait. Always use SEH since it can raise an exception */
256 {
257 /* We're done playing with handles */
258 LockInUse = FALSE;
260
261 /* Do the kernel wait */
263 WaitObjects,
264 WaitType,
267 Alertable,
268 TimeOut,
270 }
274 {
275 /* Get the exception code */
277 }
278 _SEH2_END;
279
280Quickie:
281 /* First derefence */
282 while (ReferencedObjects)
283 {
284 /* Decrease the number of objects */
285 ReferencedObjects--;
286
287 /* Check if we had a valid object in this position */
288 if (Objects[ReferencedObjects])
289 {
290 /* Dereference it */
291 ObDereferenceObject(Objects[ReferencedObjects]);
292 }
293 }
294
295 /* Free wait block array */
297
298 /* Re-enable APCs if needed */
299 if (LockInUse) KeLeaveCriticalRegion();
300
301 /* Return status */
302 return Status;
303}
#define PAGED_CODE()
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
LONG ObjectCount
Definition: comsup.c:7
HANDLE KernelHandle
Definition: legacy.c:24
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
_Must_inspect_result_ _In_ WAIT_TYPE _In_opt_ PLARGE_INTEGER _In_opt_ PKWAIT_BLOCK WaitBlockArray
Definition: fsrtlfuncs.h:1153
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
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 GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:220
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
ULONG ACCESS_MASK
Definition: nt_native.h:40
@ WaitAll
@ WaitAny
PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle)
Definition: handle.c:1046
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:285
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:475
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:74
#define ObpGetHandleObject(x)
Definition: ob.h:91
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:83
WaitType
Definition: shlextdbg.cpp:386
Definition: extypes.h:596
ULONG GrantedAccess
Definition: extypes.h:606
LONG_PTR PointerCount
Definition: obtypes.h:487
POBJECT_TYPE Type
Definition: obtypes.h:493
PVOID DefaultObject
Definition: obtypes.h:384
#define TAG_WAIT
Definition: tag.h:120
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MAXIMUM_WAIT_OBJECTS
Definition: winbase.h:404
#define THREAD_WAIT_OBJECTS
Definition: ketypes.h:492
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20

Referenced by _main(), ConnectConsole(), IntAllocConsole(), IntAttachConsole(), NtWaitForMultipleObjects32(), START_TEST(), UnhandledExceptionFilter(), Wait_thread_proc(), and WaitForMultipleObjectsEx().

◆ NtWaitForMultipleObjects32()

NTSTATUS NTAPI NtWaitForMultipleObjects32 ( IN ULONG  ObjectCount,
IN PLONG  Handles,
IN WAIT_TYPE  WaitType,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

Definition at line 333 of file obwait.c.

338{
339 /* FIXME WOW64 */
341 (PHANDLE)Handles,
342 WaitType,
343 Alertable,
344 TimeOut);
345}
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
NTSTATUS NTAPI NtWaitForMultipleObjects(IN ULONG ObjectCount, IN PHANDLE HandleArray, IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER TimeOut OPTIONAL)
Definition: obwait.c:46

◆ NtWaitForSingleObject()

NTSTATUS NTAPI NtWaitForSingleObject ( IN HANDLE  ObjectHandle,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

Definition at line 369 of file obwait.c.

372{
373 PVOID Object, WaitableObject;
375 LARGE_INTEGER SafeTimeOut;
377
378 /* Check if we came with a timeout from user mode */
380 if ((TimeOut) && (PreviousMode != KernelMode))
381 {
382 /* Enter SEH for proving */
384 {
385 /* Make a copy on the stack */
386 SafeTimeOut = ProbeForReadLargeInteger(TimeOut);
387 TimeOut = &SafeTimeOut;
388 }
390 {
391 /* Return the exception code */
393 }
394 _SEH2_END;
395 }
396
397 /* Get the Object */
398 Status = ObReferenceObjectByHandle(ObjectHandle,
400 NULL,
402 &Object,
403 NULL);
404 if (NT_SUCCESS(Status))
405 {
406 /* Get the Waitable Object */
407 WaitableObject = OBJECT_TO_OBJECT_HEADER(Object)->Type->DefaultObject;
408
409 /* Is it an offset for internal objects? */
410 if (IsPointerOffset(WaitableObject))
411 {
412 /* Turn it into a pointer */
413 WaitableObject = (PVOID)((ULONG_PTR)Object +
414 (ULONG_PTR)WaitableObject);
415 }
416
417 /* SEH this since it can also raise an exception */
419 {
420 /* Ask the kernel to do the wait */
421 Status = KeWaitForSingleObject(WaitableObject,
424 Alertable,
425 TimeOut);
426 }
430 {
431 /* Get the exception code */
433 }
434 _SEH2_END;
435
436 /* Dereference the Object */
438 }
439 else
440 {
441 DPRINT1("Failed to reference the handle with status 0x%x\n", Status);
442 }
443
444 /* Return the status */
445 return Status;
446}
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object