Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

obwait.c File Reference

#include "obp.h"

Go to the source code of this file.

Functions

NTSTATUS NtSignalAndWaitForSingleObject (IN HANDLE SignalHandle, IN HANDLE WaitHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
NTSTATUS NtWaitForSingleObject (IN HANDLE Handle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
NTSTATUS NtWaitForMultipleObjects (IN ULONG Count, IN HANDLE Handles[], IN WAIT_TYPE WaitType, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
NTSTATUS ObWaitForSingleObject (IN HANDLE Handle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)

Variables

POBJECT_TYPE ExEventObjectType
POBJECT_TYPE ExMutantObjectType
POBJECT_TYPE ExSemaphoreObjectType


Function Documentation

NTSTATUS NtSignalAndWaitForSingleObject IN HANDLE  SignalHandle,
IN HANDLE  WaitHandle,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER Timeout  OPTIONAL
 

Definition at line 38 of file obwait.c.

References _OBJECT_TYPE::DefaultObject, EVENT_INCREMENT, EXCEPTION_EXECUTE_HANDLER, ExEventObjectType, ExMutantObjectType, ExSemaphoreObjectType, FALSE, _OBJECT_HANDLE_INFORMATION::GrantedAccess, KeReleaseMutant(), KeReleaseSemaphore(), KernelMode, KeSetEvent(), KeWaitForSingleObject(), KPROCESSOR_MODE, MUTANT_INCREMENT, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, OBJECT_TO_OBJECT_HEADER, ObReferenceObjectByHandle(), ProbeAndReadLargeInteger, SeComputeDeniedAccesses, SEMAPHORE_INCREMENT, Status, TRUE, _OBJECT_HEADER::Type, and UserRequest.

Referenced by DisplayModeTransition().

00047 : 00048 00049 This function atomically signals the specified signal object and then 00050 waits until the specified wait object attains a state of Signaled. An 00051 optional timeout can also be specified. If a timeout is not specified, 00052 then the wait will not be satisfied until the wait object attains a 00053 state of Signaled. If a timeout is specified, and the wait object has 00054 not attained a state of Signaled when the timeout expires, then the 00055 wait is automatically satisfied. If an explicit timeout value of zero 00056 is specified, then no wait will occur if the wait cannot be satisfied 00057 immediately. The wait can also be specified as alertable. 00058 00059 Arguments: 00060 00061 SignalHandle - Supplies the handle of the signal object. 00062 00063 WaitHandle - Supplies the handle for the wait object. 00064 00065 Alertable - Supplies a boolean value that specifies whether the wait 00066 is alertable. 00067 00068 Timeout - Supplies an pointer to an absolute or relative time over 00069 which the wait is to occur. 00070 00071 Return Value: 00072 00073 The wait completion status. A value of STATUS_TIMEOUT is returned if a 00074 timeout occurred. A value of STATUS_SUCCESS is returned if the specified 00075 object satisfied the wait. A value of STATUS_ALERTED is returned if the 00076 wait was aborted to deliver an alert to the current thread. A value of 00077 STATUS_USER_APC is returned if the wait was aborted to deliver a user 00078 APC to the current thread. 00079 00080 --*/ 00081 00082 { 00083 OBJECT_HANDLE_INFORMATION HandleInformation; 00084 KPROCESSOR_MODE PreviousMode; 00085 PVOID RealObject; 00086 PVOID SignalObject; 00087 POBJECT_HEADER SignalObjectHeader; 00088 NTSTATUS Status; 00089 LARGE_INTEGER TimeoutValue; 00090 PVOID WaitObject; 00091 POBJECT_HEADER WaitObjectHeader; 00092 00093 // 00094 // Establish an exception handler and probe the specified timeout value 00095 // if necessary. If the probe fails, then return the exception code as 00096 // the service status. 00097 // 00098 00099 PreviousMode = KeGetPreviousMode(); 00100 00101 if ((ARGUMENT_PRESENT(Timeout)) && (PreviousMode != KernelMode)) { 00102 00103 try { 00104 00105 TimeoutValue = ProbeAndReadLargeInteger(Timeout); 00106 Timeout = &TimeoutValue; 00107 00108 } except(EXCEPTION_EXECUTE_HANDLER) { 00109 00110 return GetExceptionCode(); 00111 } 00112 } 00113 00114 // 00115 // Reference the signal object by handle. 00116 // 00117 00118 Status = ObReferenceObjectByHandle( SignalHandle, 00119 0, 00120 NULL, 00121 PreviousMode, 00122 &SignalObject, 00123 &HandleInformation ); 00124 00125 // 00126 // If the reference was successful, then reference the wait object by 00127 // handle. 00128 // 00129 00130 if (NT_SUCCESS(Status)) { 00131 00132 Status = ObReferenceObjectByHandle( WaitHandle, 00133 SYNCHRONIZE, 00134 NULL, 00135 PreviousMode, 00136 &WaitObject, 00137 NULL ); 00138 00139 // 00140 // If the reference was successful, then determine the real wait 00141 // object, check the signal object access, signal the signal object, 00142 // and wait for the real wait object. 00143 // 00144 00145 if (NT_SUCCESS(Status)) { 00146 00147 WaitObjectHeader = OBJECT_TO_OBJECT_HEADER(WaitObject); 00148 RealObject = WaitObjectHeader->Type->DefaultObject; 00149 00150 if ((LONG_PTR)RealObject >= 0) { 00151 00152 RealObject = (PVOID)((PCHAR)WaitObject + (ULONG_PTR)RealObject); 00153 } 00154 00155 // 00156 // If the signal object is an event, then check for modify access 00157 // and set the event. Otherwise, if the signal object is a 00158 // mutant, then attempt to release ownership of the mutant. 00159 // Otherwise, if the object is a semaphore, then check for modify 00160 // access and release the semaphore. Otherwise, the signal objet 00161 // is invalid. 00162 // 00163 00164 SignalObjectHeader = OBJECT_TO_OBJECT_HEADER(SignalObject); 00165 Status = STATUS_ACCESS_DENIED; 00166 00167 if (SignalObjectHeader->Type == ExEventObjectType) { 00168 00169 // 00170 // Check for access to the specified event object, 00171 // 00172 00173 if ((PreviousMode != KernelMode) && 00174 (SeComputeDeniedAccesses( HandleInformation.GrantedAccess, 00175 EVENT_MODIFY_STATE) != 0 )) { 00176 00177 goto WaitExit; 00178 } 00179 00180 // 00181 // Set the specified event and wait atomically. 00182 // 00183 00184 KeSetEvent((PKEVENT)SignalObject, EVENT_INCREMENT, TRUE); 00185 00186 } else if (SignalObjectHeader->Type == ExMutantObjectType) { 00187 00188 // 00189 // Release the specified mutant and wait atomically. 00190 // 00191 // N.B. The release will only be successful if the current 00192 // thread is the owner of the mutant. 00193 // 00194 00195 try { 00196 00197 KeReleaseMutant( (PKMUTANT)SignalObject, 00198 MUTANT_INCREMENT, 00199 FALSE, 00200 TRUE ); 00201 00202 } except(EXCEPTION_EXECUTE_HANDLER) { 00203 00204 Status = GetExceptionCode(); 00205 00206 goto WaitExit; 00207 } 00208 00209 } else if (SignalObjectHeader->Type == ExSemaphoreObjectType) { 00210 00211 // 00212 // Check for access to the specified semaphore object, 00213 // 00214 00215 if ((PreviousMode != KernelMode) && 00216 (SeComputeDeniedAccesses( HandleInformation.GrantedAccess, 00217 SEMAPHORE_MODIFY_STATE) != 0 )) { 00218 00219 goto WaitExit; 00220 } 00221 00222 // 00223 // Release the specified semaphore and wait atomically. 00224 // 00225 00226 try { 00227 00228 // 00229 // Release the specified semaphore and wait atomically. 00230 // 00231 00232 KeReleaseSemaphore( (PKSEMAPHORE)SignalObject, 00233 SEMAPHORE_INCREMENT, 00234 1, 00235 TRUE ); 00236 00237 } except(EXCEPTION_EXECUTE_HANDLER) { 00238 00239 Status = GetExceptionCode(); 00240 00241 goto WaitExit; 00242 } 00243 00244 } else { 00245 00246 Status = STATUS_OBJECT_TYPE_MISMATCH; 00247 00248 goto WaitExit; 00249 } 00250 00251 // 00252 // Protect the wait call just in case KeWait decides to raise 00253 // For example, a mutant level is exceeded 00254 // 00255 00256 try { 00257 00258 Status = KeWaitForSingleObject( RealObject, 00259 UserRequest, 00260 PreviousMode, 00261 Alertable, 00262 Timeout ); 00263 00264 } except(EXCEPTION_EXECUTE_HANDLER) { 00265 00266 Status = GetExceptionCode(); 00267 } 00268 00269 WaitExit: 00270 00271 ObDereferenceObject(WaitObject); 00272 } 00273 00274 ObDereferenceObject(SignalObject); 00275 } 00276 00277 return Status; 00278 }

NTSTATUS NtWaitForMultipleObjects IN ULONG  Count,
IN HANDLE  Handles[],
IN WAIT_TYPE  WaitType,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER Timeout  OPTIONAL
 

Definition at line 406 of file obwait.c.

References ASSERT, _OBJECT_HEADER::Body, Count, DecodeKernelHandle, _OBJECT_TYPE::DefaultObject, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExMapHandleToPointer(), ExUnlockHandleTableEntry(), FALSE, _HANDLE_TABLE_ENTRY::GrantedAccess, _HANDLE_TABLE_ENTRY::GrantedAccessIndex, IsKernelHandle, KeEnterCriticalRegion, KeLeaveCriticalRegion, KernelMode, KeStackAttachProcess(), KeUnstackDetachProcess(), KeWaitForMultipleObjects(), KPROCESSOR_MODE, NonPagedPool, NtGlobalFlag, NTSTATUS(), NULL, ObDereferenceObject, OBJ_HANDLE_ATTRIBUTES, _HANDLE_TABLE_ENTRY::Object, ObpGetObjectTable, ObpIncrPointerCount, ObpKernelHandleTable, PAGED_CODE, _EPROCESS::Pcb, ProbeAndReadLargeInteger, ProbeForRead, PsGetCurrentProcess, PsInitialSystemProcess, RefCount, SeComputeDeniedAccesses, Size, Status, THREAD_WAIT_OBJECTS, TRUE, _OBJECT_HEADER::Type, and UserRequest.

Referenced by AllocConsoleInternal(), ConnectConsoleInternal(), NotificationThread(), obtest(), and RtlpWaitThread().

00416 : 00417 00418 This function waits until the specified objects attain a state of 00419 Signaled. The wait can be specified to wait until all of the objects 00420 attain a state of Signaled or until one of the objects attains a state 00421 of Signaled. An optional timeout can also be specified. If a timeout 00422 is not specified, then the wait will not be satisfied until the objects 00423 attain a state of Signaled. If a timeout is specified, and the objects 00424 have not attained a state of Signaled when the timeout expires, then 00425 the wait is automatically satisfied. If an explicit timeout value of 00426 zero is specified, then no wait will occur if the wait cannot be satisfied 00427 immediately. The wait can also be specified as alertable. 00428 00429 Arguments: 00430 00431 Count - Supplies a count of the number of objects that are to be waited 00432 on. 00433 00434 Handles[] - Supplies an array of handles to wait objects. 00435 00436 WaitType - Supplies the type of wait to perform (WaitAll, WaitAny). 00437 00438 Alertable - Supplies a boolean value that specifies whether the wait is 00439 alertable. 00440 00441 Timeout - Supplies a pointer to an optional absolute of relative time over 00442 which the wait is to occur. 00443 00444 Return Value: 00445 00446 The wait completion status. A value of STATUS_TIMEOUT is returned if a 00447 timeout occurred. The index of the object (zero based) in the object 00448 pointer array is returned if an object satisfied the wait. A value of 00449 STATUS_ALERTED is returned if the wait was aborted to deliver an alert 00450 to the current thread. A value of STATUS_USER_APC is returned if the 00451 wait was aborted to deliver a user APC to the current thread. 00452 00453 --*/ 00454 00455 { 00456 HANDLE CapturedHandles[MAXIMUM_WAIT_OBJECTS]; 00457 ULONG i; 00458 ULONG j; 00459 POBJECT_HEADER ObjectHeader; 00460 PVOID Objects[MAXIMUM_WAIT_OBJECTS]; 00461 KPROCESSOR_MODE PreviousMode; 00462 ULONG RefCount; 00463 ULONG Size; 00464 NTSTATUS Status; 00465 LARGE_INTEGER TimeoutValue; 00466 PKWAIT_BLOCK WaitBlockArray; 00467 ACCESS_MASK GrantedAccess; 00468 PVOID WaitObjects[MAXIMUM_WAIT_OBJECTS]; 00469 PHANDLE_TABLE HandleTable; 00470 PHANDLE_TABLE_ENTRY HandleEntry; 00471 BOOLEAN AttachedToProcess = FALSE; 00472 BOOLEAN InCriticalRegion = FALSE; 00473 KAPC_STATE ApcState; 00474 00475 PAGED_CODE(); 00476 00477 // 00478 // Protect ourselves from being interrupted while we hold a handle table 00479 // entry lock 00480 // 00481 00482 KeEnterCriticalRegion(); 00483 InCriticalRegion = TRUE; 00484 00485 try { 00486 00487 // 00488 // If the number of objects is zero or greater than the largest number 00489 // that can be waited on, then return and invalid parameter status. 00490 // 00491 00492 if ((Count == 0) || (Count > MAXIMUM_WAIT_OBJECTS)) { 00493 00494 Status = STATUS_INVALID_PARAMETER_1; 00495 leave; 00496 } 00497 00498 // 00499 // If the wait type is not wait any or wait all, then return an invalid 00500 // parameter status. 00501 // 00502 00503 if ((WaitType != WaitAny) && (WaitType != WaitAll)) { 00504 00505 Status = STATUS_INVALID_PARAMETER_3; 00506 leave; 00507 } 00508 00509 // 00510 // Get previous processor mode and probe and capture input arguments if 00511 // necessary. 00512 // 00513 00514 PreviousMode = KeGetPreviousMode(); 00515 00516 try { 00517 00518 if (PreviousMode != KernelMode) { 00519 00520 if (ARGUMENT_PRESENT(Timeout)) { 00521 00522 TimeoutValue = ProbeAndReadLargeInteger(Timeout); 00523 Timeout = &TimeoutValue; 00524 } 00525 00526 ProbeForRead( Handles, Count * sizeof(HANDLE), sizeof(HANDLE) ); 00527 } 00528 00529 i= 0; 00530 00531 do { 00532 00533 CapturedHandles[i] = Handles[i]; 00534 i += 1; 00535 00536 } while (i < Count); 00537 00538 } except(EXCEPTION_EXECUTE_HANDLER) { 00539 00540 Status = GetExceptionCode(); 00541 leave; 00542 } 00543 00544 // 00545 // If the number of objects to be waited on is greater than the number 00546 // of builtin wait blocks, then allocate an array of wait blocks from 00547 // nonpaged pool. If the wait block array cannot be allocated, then 00548 // return insufficient resources. 00549 // 00550 00551 WaitBlockArray = NULL; 00552 00553 if (Count > THREAD_WAIT_OBJECTS) { 00554 00555 Size = Count * sizeof( KWAIT_BLOCK ); 00556 WaitBlockArray = ExAllocatePoolWithTag(NonPagedPool, Size, 'tiaW'); 00557 00558 if (WaitBlockArray == NULL) { 00559 00560 Status = STATUS_INSUFFICIENT_RESOURCES; 00561 leave; 00562 } 00563 } 00564 00565 // 00566 // Loop through the array of handles and get a referenced pointer to 00567 // each object. 00568 // 00569 00570 i = 0; 00571 RefCount = 0; 00572 00573 Status = STATUS_SUCCESS; 00574 00575 do { 00576 00577 #if DBG 00578 // 00579 // On checked builds, check that if the Kernel handle bit is set, 00580 // then we're coming from Kernel mode. We should probably fail the 00581 // call if bit set && !Kmode 00582 // 00583 00584 if ((CapturedHandles[i] != NtCurrentThread()) && 00585 (CapturedHandles[i] != NtCurrentProcess())) { 00586 00587 ASSERT((CapturedHandles[i] < 0) ? (PreviousMode == KernelMode) : TRUE); 00588 } 00589 #endif 00590 00591 // 00592 // Get a pointer to the object table entry. Check if this is a kernel 00593 // handle and if so then use the kernel handle table otherwise use the 00594 // processes handle table. If we are going for a kernel handle we'll 00595 // need to attach to the kernel process otherwise we need to ensure 00596 // that we aren't attached. 00597 // 00598 00599 if (IsKernelHandle( CapturedHandles[i], PreviousMode )) { 00600 00601 HANDLE KernelHandle; 00602 00603 // 00604 // If we aren't already attached to the system process do so now 00605 // and remember that we are 00606 // 00607 00608 if (PsGetCurrentProcess() != PsInitialSystemProcess) { 00609 KeStackAttachProcess (&PsInitialSystemProcess->Pcb, &ApcState); 00610 AttachedToProcess = TRUE; 00611 } 00612 00613 // 00614 // Decode the user supplied handle into a regular handle value 00615 // and get its handle table entry 00616 // 00617 00618 KernelHandle = DecodeKernelHandle( CapturedHandles[i] ); 00619 00620 HandleTable = ObpKernelHandleTable; 00621 HandleEntry = ExMapHandleToPointer( HandleTable, KernelHandle ); 00622 00623 } else { 00624 00625 // 00626 // If we are attached to the system process then go back to the 00627 // original callers process 00628 // 00629 00630 if (AttachedToProcess) { 00631 KeUnstackDetachProcess(&ApcState); 00632 AttachedToProcess = FALSE; 00633 } 00634 00635 // 00636 // Get the handle table entry 00637 // 00638 00639 HandleTable = ObpGetObjectTable(); 00640 HandleEntry = ExMapHandleToPointer( HandleTable, CapturedHandles[ i ] ); 00641 } 00642 00643 // 00644 // Make sure the handle really did translate to a valid 00645 // entry 00646 // 00647 00648 if (HandleEntry != NULL) { 00649 00650 // 00651 // Get the granted access for the handle 00652 // 00653 00654 #if i386 && !FPO 00655 00656 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) { 00657 00658 if (PreviousMode != KernelMode) { 00659 00660 GrantedAccess = ObpTranslateGrantedAccessIndex( HandleEntry->GrantedAccessIndex ); 00661 } 00662 00663 } else { 00664 00665 GrantedAccess = HandleEntry->GrantedAccess; 00666 } 00667 00668 #else 00669 GrantedAccess = HandleEntry->GrantedAccess; 00670 00671 #endif // i386 && !FPO 00672 00673 // 00674 // Make sure the handle as synchronize access to the 00675 // object 00676 // 00677 00678 if ((PreviousMode != KernelMode) && 00679 (SeComputeDeniedAccesses( GrantedAccess, SYNCHRONIZE ) != 0)) { 00680 00681 Status = STATUS_ACCESS_DENIED; 00682 00683 ExUnlockHandleTableEntry( HandleTable, HandleEntry ); 00684 00685 goto ServiceFailed; 00686 00687 } else { 00688 00689 // 00690 // We have a object with proper access so get the header 00691 // and if the default objects points to a real object 00692 // then that is the one we're going to wait on. 00693 // Otherwise we'll find the kernel wait object at an 00694 // offset into the object body 00695 // 00696 00697 ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(HandleEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES); 00698 00699 if ((LONG_PTR)ObjectHeader->Type->DefaultObject < 0) { 00700 00701 RefCount += 1; 00702 Objects[i] = NULL; 00703 WaitObjects[i] = ObjectHeader->Type->DefaultObject; 00704 00705 } else { 00706 00707 ObpIncrPointerCount( ObjectHeader ); 00708 RefCount += 1; 00709 Objects[i] = &ObjectHeader->Body; 00710 00711 // 00712 // Compute the address of the kernel wait object. 00713 // 00714 00715 WaitObjects[i] = (PVOID)((PCHAR)&ObjectHeader->Body + 00716 (ULONG_PTR)ObjectHeader->Type->DefaultObject); 00717 } 00718 } 00719 00720 ExUnlockHandleTableEntry( HandleTable, HandleEntry ); 00721 00722 } else { 00723 00724 // 00725 // The entry in the handle table isn't in use 00726 // 00727 00728 Status = STATUS_INVALID_HANDLE; 00729 00730 goto ServiceFailed; 00731 } 00732 00733 i += 1; 00734 00735 } while (i < Count); 00736 00737 // 00738 // At this point the WaitObjects[] is set to the kernel wait objects 00739 // 00740 // Now Check to determine if any of the objects are specified more than 00741 // once, but we only need to check this for wait all, with a wait any 00742 // the user can specify the same object multiple times. 00743 // 00744 00745 if (WaitType == WaitAll) { 00746 00747 i = 0; 00748 00749 do { 00750 00751 for (j = i + 1; j < Count; j += 1) { 00752 00753 if (WaitObjects[i] == WaitObjects[j]) { 00754 00755 Status = STATUS_INVALID_PARAMETER_MIX; 00756 00757 goto ServiceFailed; 00758 } 00759 } 00760 00761 i += 1; 00762 00763 } while (i < Count); 00764 } 00765 00766 // 00767 // Wait for the specified objects to attain a state of Signaled or a 00768 // time out to occur. Protect the wait call just in case KeWait decides 00769 // to raise For example, a mutant level is exceeded 00770 // 00771 00772 try { 00773 00774 InCriticalRegion = FALSE; 00775 KeLeaveCriticalRegion(); 00776 Status = KeWaitForMultipleObjects( Count, 00777 WaitObjects, 00778 WaitType, 00779 UserRequest, 00780 PreviousMode, 00781 Alertable, 00782 Timeout, 00783 WaitBlockArray ); 00784 00785 } except(EXCEPTION_EXECUTE_HANDLER) { 00786 00787 Status = GetExceptionCode(); 00788 } 00789 00790 // 00791 // If any objects were referenced, then deference them. 00792 // 00793 00794 ServiceFailed: 00795 00796 while (RefCount > 0) { 00797 00798 RefCount -= 1; 00799 00800 if (Objects[RefCount] != NULL) { 00801 00802 ObDereferenceObject(Objects[RefCount]); 00803 } 00804 } 00805 00806 // 00807 // If are attached to the system process then return back to our callers 00808 // process 00809 00810 if (AttachedToProcess) { 00811 KeUnstackDetachProcess(&ApcState); 00812 AttachedToProcess = FALSE; 00813 } 00814 00815 // 00816 // If a wait block array was allocated, then deallocate it. 00817 // 00818 00819 if (WaitBlockArray != NULL) { 00820 00821 ExFreePool(WaitBlockArray); 00822 } 00823 00824 } finally { 00825 00826 if ( InCriticalRegion ) { 00827 00828 KeLeaveCriticalRegion(); 00829 } 00830 } 00831 00832 return Status; 00833 }

NTSTATUS NtWaitForSingleObject IN HANDLE  Handle,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER Timeout  OPTIONAL
 

Definition at line 282 of file obwait.c.

References _OBJECT_TYPE::DefaultObject, EXCEPTION_EXECUTE_HANDLER, Handle, KernelMode, KeWaitForSingleObject(), KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, OBJECT_TO_OBJECT_HEADER, ObReferenceObjectByHandle(), PAGED_CODE, ProbeAndReadLargeInteger, Status, _OBJECT_HEADER::Type, and UserRequest.

Referenced by _ExitWindowsEx(), DbgUiWaitStateChange(), DoPaste(), FsRtlpRegisterProviderWithMUP(), InitWindowsStuff(), KillProcess(), main(), NTFastDOSIO(), obtest(), RemoteMessageThread(), RtlAcquireResourceExclusive(), RtlAcquireResourceShared(), RtlConvertSharedToExclusive(), RtlDestroyQueryDebugBuffer(), RtlpWaitForCriticalSection(), RtlpWaitForEvent(), RtlQueryProcessDebugInformation(), RtlShutdownLpcServer(), SepClientOpenPipe(), SepReadPipe(), SepServerDisconnectPipe(), SepServerImpersonatePipe(), SepServerInitialize(), SepServerListenPipe(), SepTransceivePipe(), SepWritePipe(), SetConsoleCP(), SetConsoleDisplayMode(), StoreSelection(), SynchronousNtFsControlFile(), TerminalServerRequestThread(), UdbgTest1(), UdbgTest2(), UserClientShutdown(), UserHardErrorEx(), VideoPortCallout(), and WriteRegionToScreenBitMap().

00290 : 00291 00292 This function waits until the specified object attains a state of 00293 Signaled. An optional timeout can also be specified. If a timeout 00294 is not specified, then the wait will not be satisfied until the 00295 object attains a state of Signaled. If a timeout is specified, and 00296 the object has not attained a state of Signaled when the timeout 00297 expires, then the wait is automatically satisfied. If an explicit 00298 timeout value of zero is specified, then no wait will occur if the 00299 wait cannot be satisfied immediately. The wait can also be specified 00300 as alertable. 00301 00302 Arguments: 00303 00304 Handle - Supplies the handle for the wait object. 00305 00306 Alertable - Supplies a boolean value that specifies whether the wait 00307 is alertable. 00308 00309 Timeout - Supplies an pointer to an absolute or relative time over 00310 which the wait is to occur. 00311 00312 Return Value: 00313 00314 The wait completion status. A value of STATUS_TIMEOUT is returned if a 00315 timeout occurred. A value of STATUS_SUCCESS is returned if the specified 00316 object satisfied the wait. A value of STATUS_ALERTED is returned if the 00317 wait was aborted to deliver an alert to the current thread. A value of 00318 STATUS_USER_APC is returned if the wait was aborted to deliver a user 00319 APC to the current thread. 00320 00321 --*/ 00322 00323 { 00324 PVOID Object; 00325 POBJECT_HEADER ObjectHeader; 00326 KPROCESSOR_MODE PreviousMode; 00327 NTSTATUS Status; 00328 LARGE_INTEGER TimeoutValue; 00329 PVOID WaitObject; 00330 00331 PAGED_CODE(); 00332 00333 // 00334 // Get previous processor mode and probe and capture timeout argument 00335 // if necessary. 00336 // 00337 00338 PreviousMode = KeGetPreviousMode(); 00339 00340 if ((ARGUMENT_PRESENT(Timeout)) && (PreviousMode != KernelMode)) { 00341 00342 try { 00343 00344 TimeoutValue = ProbeAndReadLargeInteger(Timeout); 00345 Timeout = &TimeoutValue; 00346 00347 } except(EXCEPTION_EXECUTE_HANDLER) { 00348 00349 return GetExceptionCode(); 00350 } 00351 } 00352 00353 // 00354 // Get a referenced pointer to the specified object with synchronize 00355 // access. 00356 // 00357 00358 Status = ObReferenceObjectByHandle( Handle, 00359 SYNCHRONIZE, 00360 NULL, 00361 PreviousMode, 00362 &Object, 00363 NULL ); 00364 00365 // 00366 // If access is granted, then check to determine if the specified object 00367 // can be waited on. 00368 // 00369 00370 if (NT_SUCCESS(Status)) { 00371 00372 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 00373 WaitObject = ObjectHeader->Type->DefaultObject; 00374 00375 if ((LONG_PTR)WaitObject >= 0) { 00376 00377 WaitObject = (PVOID)((PCHAR)Object + (ULONG_PTR)WaitObject); 00378 } 00379 00380 // 00381 // Protect the wait call just in case KeWait decides to raise 00382 // For example, a mutant level is exceeded 00383 // 00384 00385 try { 00386 00387 Status = KeWaitForSingleObject( WaitObject, 00388 UserRequest, 00389 PreviousMode, 00390 Alertable, 00391 Timeout ); 00392 00393 } except(EXCEPTION_EXECUTE_HANDLER) { 00394 00395 Status = GetExceptionCode(); 00396 } 00397 00398 ObDereferenceObject(Object); 00399 } 00400 00401 return Status; 00402 }

NTSTATUS ObWaitForSingleObject IN HANDLE  Handle,
IN BOOLEAN  Alertable,
IN PLARGE_INTEGER Timeout  OPTIONAL
 

Definition at line 837 of file obwait.c.

References _OBJECT_TYPE::DefaultObject, EXCEPTION_EXECUTE_HANDLER, FALSE, Handle, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, OBJECT_TO_OBJECT_HEADER, ObReferenceObjectByHandle(), PAGED_CODE, Status, _OBJECT_HEADER::Type, and UserRequest.

00845 : 00846 00847 Please refer to NtWaitForSingleObject 00848 00849 Arguments: 00850 00851 Handle - Supplies the handle for the wait object. 00852 00853 Alertable - Supplies a boolean value that specifies whether the wait 00854 is alertable. 00855 00856 Timeout - Supplies an pointer to an absolute or relative time over 00857 which the wait is to occur. 00858 00859 Return Value: 00860 00861 The wait completion status. A value of STATUS_TIMEOUT is returned if a 00862 timeout occurred. A value of STATUS_SUCCESS is returned if the specified 00863 object satisfied the wait. A value of STATUS_ALERTED is returned if the 00864 wait was aborted to deliver an alert to the current thread. A value of 00865 STATUS_USER_APC is returned if the wait was aborted to deliver a user 00866 APC to the current thread. 00867 00868 --*/ 00869 00870 { 00871 POBJECT_HEADER ObjectHeader; 00872 PVOID Object; 00873 NTSTATUS Status; 00874 PVOID WaitObject; 00875 00876 PAGED_CODE(); 00877 00878 // 00879 // Get a referenced pointer to the specified object with synchronize 00880 // access. 00881 // 00882 00883 Status = ObReferenceObjectByHandle( Handle, 00884 SYNCHRONIZE, 00885 (POBJECT_TYPE)NULL, 00886 KernelMode, 00887 &Object, 00888 NULL ); 00889 00890 // 00891 // If access is granted, then check to determine if the specified object 00892 // can be waited on. 00893 // 00894 00895 if (NT_SUCCESS( Status ) != FALSE) { 00896 00897 ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 00898 00899 if ((LONG_PTR)ObjectHeader->Type->DefaultObject < 0) { 00900 00901 WaitObject = (PVOID)ObjectHeader->Type->DefaultObject; 00902 00903 } else { 00904 00905 WaitObject = (PVOID)((PCHAR)Object + (ULONG_PTR)ObjectHeader->Type->DefaultObject); 00906 } 00907 00908 // 00909 // Protect the wait call just in case KeWait decides 00910 // to raise For example, a mutant level is exceeded 00911 // 00912 00913 try { 00914 00915 Status = KeWaitForSingleObject( WaitObject, 00916 UserRequest, 00917 KernelMode, 00918 Alertable, 00919 Timeout ); 00920 00921 } except(EXCEPTION_EXECUTE_HANDLER) { 00922 00923 Status = GetExceptionCode(); 00924 } 00925 00926 ObDereferenceObject(Object); 00927 } 00928 00929 return Status; 00930 } }


Variable Documentation

POBJECT_TYPE ExEventObjectType
 

Definition at line 32 of file obwait.c.

POBJECT_TYPE ExMutantObjectType
 

Definition at line 33 of file obwait.c.

Referenced by ExpMutantInitialization(), NtCreateMutant(), NtOpenMutant(), NtQueryMutant(), NtReleaseMutant(), and NtSignalAndWaitForSingleObject().

POBJECT_TYPE ExSemaphoreObjectType
 

Definition at line 34 of file obwait.c.


Generated on Sat May 15 19:44:59 2004 for test by doxygen 1.3.7