Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensynch.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Win32 Base API 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll/win32/kernel32/synch/wait.c 00005 * PURPOSE: Wrappers for the NT Wait Implementation 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 #include <k32.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 #undef InterlockedIncrement 00016 #undef InterlockedDecrement 00017 #undef InterlockedExchange 00018 #undef InterlockedExchangeAdd 00019 #undef InterlockedCompareExchange 00020 00021 /* FUNCTIONS *****************************************************************/ 00022 00023 /* 00024 * @implemented 00025 */ 00026 LONG 00027 WINAPI 00028 InterlockedIncrement(IN OUT LONG volatile *lpAddend) 00029 { 00030 return _InterlockedIncrement(lpAddend); 00031 } 00032 00033 /* 00034 * @implemented 00035 */ 00036 LONG 00037 WINAPI 00038 InterlockedDecrement(IN OUT LONG volatile *lpAddend) 00039 { 00040 return _InterlockedDecrement(lpAddend); 00041 } 00042 00043 /* 00044 * @implemented 00045 */ 00046 LONG 00047 WINAPI 00048 InterlockedExchange(IN OUT LONG volatile *Target, 00049 IN LONG Value) 00050 { 00051 return _InterlockedExchange(Target, Value); 00052 } 00053 00054 /* 00055 * @implemented 00056 */ 00057 LONG 00058 WINAPI 00059 InterlockedExchangeAdd(IN OUT LONG volatile *Addend, 00060 IN LONG Value) 00061 { 00062 return _InterlockedExchangeAdd(Addend, Value); 00063 } 00064 00065 /* 00066 * @implemented 00067 */ 00068 LONG 00069 WINAPI 00070 InterlockedCompareExchange(IN OUT LONG volatile *Destination, 00071 IN LONG Exchange, 00072 IN LONG Comperand) 00073 { 00074 return _InterlockedCompareExchange(Destination, Exchange, Comperand); 00075 } 00076 00077 /* 00078 * @implemented 00079 */ 00080 DWORD 00081 WINAPI 00082 WaitForSingleObject(IN HANDLE hHandle, 00083 IN DWORD dwMilliseconds) 00084 { 00085 /* Call the extended API */ 00086 return WaitForSingleObjectEx(hHandle, dwMilliseconds, FALSE); 00087 } 00088 00089 /* 00090 * @implemented 00091 */ 00092 DWORD 00093 WINAPI 00094 WaitForSingleObjectEx(IN HANDLE hHandle, 00095 IN DWORD dwMilliseconds, 00096 IN BOOL bAlertable) 00097 { 00098 PLARGE_INTEGER TimePtr; 00099 LARGE_INTEGER Time; 00100 NTSTATUS Status; 00101 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; 00102 00103 /* APCs must execute with the default activation context */ 00104 if (bAlertable) 00105 { 00106 /* Setup the frame */ 00107 RtlZeroMemory(&ActCtx, sizeof(ActCtx)); 00108 ActCtx.Size = sizeof(ActCtx); 00109 ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; 00110 RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); 00111 } 00112 00113 /* Get real handle */ 00114 hHandle = TranslateStdHandle(hHandle); 00115 00116 /* Check for console handle */ 00117 if ((IsConsoleHandle(hHandle)) && (VerifyConsoleIoHandle(hHandle))) 00118 { 00119 /* Get the real wait handle */ 00120 hHandle = GetConsoleInputWaitHandle(); 00121 } 00122 00123 /* Convert the timeout */ 00124 TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds); 00125 00126 /* Start wait loop */ 00127 do 00128 { 00129 /* Do the wait */ 00130 Status = NtWaitForSingleObject(hHandle, (BOOLEAN)bAlertable, TimePtr); 00131 if (!NT_SUCCESS(Status)) 00132 { 00133 /* The wait failed */ 00134 BaseSetLastNTError(Status); 00135 Status = WAIT_FAILED; 00136 } 00137 } while ((Status == STATUS_ALERTED) && (bAlertable)); 00138 00139 /* Cleanup the activation context */ 00140 if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); 00141 00142 /* Return wait status */ 00143 return Status; 00144 } 00145 00146 /* 00147 * @implemented 00148 */ 00149 DWORD 00150 WINAPI 00151 WaitForMultipleObjects(IN DWORD nCount, 00152 IN CONST HANDLE *lpHandles, 00153 IN BOOL bWaitAll, 00154 IN DWORD dwMilliseconds) 00155 { 00156 /* Call the extended API */ 00157 return WaitForMultipleObjectsEx(nCount, 00158 lpHandles, 00159 bWaitAll, 00160 dwMilliseconds, 00161 FALSE); 00162 } 00163 00164 /* 00165 * @implemented 00166 */ 00167 DWORD 00168 WINAPI 00169 WaitForMultipleObjectsEx(IN DWORD nCount, 00170 IN CONST HANDLE *lpHandles, 00171 IN BOOL bWaitAll, 00172 IN DWORD dwMilliseconds, 00173 IN BOOL bAlertable) 00174 { 00175 PLARGE_INTEGER TimePtr; 00176 LARGE_INTEGER Time; 00177 PHANDLE HandleBuffer; 00178 HANDLE Handle[8]; 00179 DWORD i; 00180 NTSTATUS Status; 00181 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; 00182 00183 /* APCs must execute with the default activation context */ 00184 if (bAlertable) 00185 { 00186 /* Setup the frame */ 00187 RtlZeroMemory(&ActCtx, sizeof(ActCtx)); 00188 ActCtx.Size = sizeof(ActCtx); 00189 ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; 00190 RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); 00191 } 00192 00193 /* Check if we have more handles then we locally optimize */ 00194 if (nCount > 8) 00195 { 00196 /* Allocate a buffer for them */ 00197 HandleBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 00198 0, 00199 nCount * sizeof(HANDLE)); 00200 if (!HandleBuffer) 00201 { 00202 /* No buffer, fail the wait */ 00203 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00204 if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); 00205 return WAIT_FAILED; 00206 } 00207 } 00208 else 00209 { 00210 /* Otherwise, use our local buffer */ 00211 HandleBuffer = Handle; 00212 } 00213 00214 /* Copy the handles into our buffer and loop them all */ 00215 RtlCopyMemory(HandleBuffer, (LPVOID)lpHandles, nCount * sizeof(HANDLE)); 00216 for (i = 0; i < nCount; i++) 00217 { 00218 /* Check what kind of handle this is */ 00219 HandleBuffer[i] = TranslateStdHandle(HandleBuffer[i]); 00220 00221 /* Check for console handle */ 00222 if ((IsConsoleHandle(HandleBuffer[i])) && 00223 (VerifyConsoleIoHandle(HandleBuffer[i]))) 00224 { 00225 /* Get the real wait handle */ 00226 HandleBuffer[i] = GetConsoleInputWaitHandle(); 00227 } 00228 } 00229 00230 /* Convert the timeout */ 00231 TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds); 00232 00233 /* Start wait loop */ 00234 do 00235 { 00236 /* Do the wait */ 00237 Status = NtWaitForMultipleObjects(nCount, 00238 HandleBuffer, 00239 bWaitAll ? WaitAll : WaitAny, 00240 (BOOLEAN)bAlertable, 00241 TimePtr); 00242 if (!NT_SUCCESS(Status)) 00243 { 00244 /* Wait failed */ 00245 BaseSetLastNTError(Status); 00246 Status = WAIT_FAILED; 00247 } 00248 } while ((Status == STATUS_ALERTED) && (bAlertable)); 00249 00250 /* Check if we didn't use our local buffer */ 00251 if (HandleBuffer != Handle) 00252 { 00253 /* Free the allocated one */ 00254 RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer); 00255 } 00256 00257 /* Cleanup the activation context */ 00258 if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); 00259 00260 /* Return wait status */ 00261 return Status; 00262 } 00263 00264 /* 00265 * @implemented 00266 */ 00267 DWORD 00268 WINAPI 00269 SignalObjectAndWait(IN HANDLE hObjectToSignal, 00270 IN HANDLE hObjectToWaitOn, 00271 IN DWORD dwMilliseconds, 00272 IN BOOL bAlertable) 00273 { 00274 PLARGE_INTEGER TimePtr; 00275 LARGE_INTEGER Time; 00276 NTSTATUS Status; 00277 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; 00278 00279 /* APCs must execute with the default activation context */ 00280 if (bAlertable) 00281 { 00282 /* Setup the frame */ 00283 RtlZeroMemory(&ActCtx, sizeof(ActCtx)); 00284 ActCtx.Size = sizeof(ActCtx); 00285 ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; 00286 RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); 00287 } 00288 00289 /* Get real handle */ 00290 hObjectToWaitOn = TranslateStdHandle(hObjectToWaitOn); 00291 00292 /* Check for console handle */ 00293 if ((IsConsoleHandle(hObjectToWaitOn)) && 00294 (VerifyConsoleIoHandle(hObjectToWaitOn))) 00295 { 00296 /* Get the real wait handle */ 00297 hObjectToWaitOn = GetConsoleInputWaitHandle(); 00298 } 00299 00300 /* Convert the timeout */ 00301 TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds); 00302 00303 /* Start wait loop */ 00304 do 00305 { 00306 /* Do the wait */ 00307 Status = NtSignalAndWaitForSingleObject(hObjectToSignal, 00308 hObjectToWaitOn, 00309 (BOOLEAN)bAlertable, 00310 TimePtr); 00311 if (!NT_SUCCESS(Status)) 00312 { 00313 /* The wait failed */ 00314 BaseSetLastNTError(Status); 00315 Status = WAIT_FAILED; 00316 } 00317 } while ((Status == STATUS_ALERTED) && (bAlertable)); 00318 00319 /* Cleanup the activation context */ 00320 if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); 00321 00322 /* Return wait status */ 00323 return Status; 00324 } 00325 00326 /* 00327 * @implemented 00328 */ 00329 HANDLE 00330 WINAPI 00331 CreateWaitableTimerW(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL, 00332 IN BOOL bManualReset, 00333 IN LPCWSTR lpTimerName OPTIONAL) 00334 { 00335 CreateNtObjectFromWin32Api(WaitableTimer, Timer, TIMER, 00336 lpTimerAttributes, 00337 lpTimerName, 00338 bManualReset ? NotificationTimer : SynchronizationTimer); 00339 } 00340 00341 /* 00342 * @implemented 00343 */ 00344 HANDLE 00345 WINAPI 00346 CreateWaitableTimerA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL, 00347 IN BOOL bManualReset, 00348 IN LPCSTR lpTimerName OPTIONAL) 00349 { 00350 ConvertWin32AnsiObjectApiToUnicodeApi(WaitableTimer, lpTimerName, lpTimerAttributes, bManualReset); 00351 } 00352 00353 /* 00354 * @implemented 00355 */ 00356 HANDLE 00357 WINAPI 00358 OpenWaitableTimerW(IN DWORD dwDesiredAccess, 00359 IN BOOL bInheritHandle, 00360 IN LPCWSTR lpTimerName) 00361 { 00362 OpenNtObjectFromWin32Api(Timer, dwDesiredAccess, bInheritHandle, lpTimerName); 00363 } 00364 00365 /* 00366 * @implemented 00367 */ 00368 HANDLE 00369 WINAPI 00370 OpenWaitableTimerA(IN DWORD dwDesiredAccess, 00371 IN BOOL bInheritHandle, 00372 IN LPCSTR lpTimerName) 00373 { 00374 ConvertOpenWin32AnsiObjectApiToUnicodeApi(WaitableTimer, dwDesiredAccess, bInheritHandle, lpTimerName); 00375 } 00376 00377 /* 00378 * @implemented 00379 */ 00380 BOOL 00381 WINAPI 00382 SetWaitableTimer(IN HANDLE hTimer, 00383 IN const LARGE_INTEGER *pDueTime, 00384 IN LONG lPeriod, 00385 IN PTIMERAPCROUTINE pfnCompletionRoutine OPTIONAL, 00386 IN OPTIONAL LPVOID lpArgToCompletionRoutine, 00387 IN BOOL fResume) 00388 { 00389 NTSTATUS Status; 00390 00391 /* Set the timer */ 00392 Status = NtSetTimer(hTimer, 00393 (PLARGE_INTEGER)pDueTime, 00394 (PTIMER_APC_ROUTINE)pfnCompletionRoutine, 00395 lpArgToCompletionRoutine, 00396 (BOOLEAN)fResume, 00397 lPeriod, 00398 NULL); 00399 if (NT_SUCCESS(Status)) return TRUE; 00400 00401 /* If we got here, then we failed */ 00402 BaseSetLastNTError(Status); 00403 return FALSE; 00404 } 00405 00406 /* 00407 * @implemented 00408 */ 00409 BOOL 00410 WINAPI 00411 CancelWaitableTimer(IN HANDLE hTimer) 00412 { 00413 NTSTATUS Status; 00414 00415 /* Cancel the timer */ 00416 Status = NtCancelTimer(hTimer, NULL); 00417 if (NT_SUCCESS(Status)) return TRUE; 00418 00419 /* If we got here, then we failed */ 00420 BaseSetLastNTError(Status); 00421 return FALSE; 00422 } 00423 00424 /* 00425 * @implemented 00426 */ 00427 HANDLE 00428 WINAPI 00429 CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, 00430 IN LONG lInitialCount, 00431 IN LONG lMaximumCount, 00432 IN LPCSTR lpName OPTIONAL) 00433 { 00434 ConvertWin32AnsiObjectApiToUnicodeApi(Semaphore, lpName, lpSemaphoreAttributes, lInitialCount, lMaximumCount); 00435 } 00436 00437 /* 00438 * @implemented 00439 */ 00440 HANDLE 00441 WINAPI 00442 CreateSemaphoreW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, 00443 IN LONG lInitialCount, 00444 IN LONG lMaximumCount, 00445 IN LPCWSTR lpName OPTIONAL) 00446 { 00447 CreateNtObjectFromWin32Api(Semaphore, Semaphore, SEMAPHORE, 00448 lpSemaphoreAttributes, 00449 lpName, 00450 lInitialCount, 00451 lMaximumCount); 00452 } 00453 00454 /* 00455 * @implemented 00456 */ 00457 HANDLE 00458 WINAPI 00459 OpenSemaphoreA(IN DWORD dwDesiredAccess, 00460 IN BOOL bInheritHandle, 00461 IN LPCSTR lpName) 00462 { 00463 ConvertOpenWin32AnsiObjectApiToUnicodeApi(Semaphore, dwDesiredAccess, bInheritHandle, lpName); 00464 } 00465 00466 /* 00467 * @implemented 00468 */ 00469 HANDLE 00470 WINAPI 00471 OpenSemaphoreW(IN DWORD dwDesiredAccess, 00472 IN BOOL bInheritHandle, 00473 IN LPCWSTR lpName) 00474 { 00475 OpenNtObjectFromWin32Api(Semaphore, dwDesiredAccess, bInheritHandle, lpName); 00476 } 00477 00478 /* 00479 * @implemented 00480 */ 00481 BOOL 00482 WINAPI 00483 ReleaseSemaphore(IN HANDLE hSemaphore, 00484 IN LONG lReleaseCount, 00485 IN LPLONG lpPreviousCount) 00486 { 00487 NTSTATUS Status; 00488 00489 /* Release the semaphore */ 00490 Status = NtReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount); 00491 if (NT_SUCCESS(Status)) return TRUE; 00492 00493 /* If we got here, then we failed */ 00494 BaseSetLastNTError(Status); 00495 return FALSE; 00496 } 00497 00498 /* 00499 * @implemented 00500 */ 00501 HANDLE 00502 WINAPI 00503 CreateMutexA(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, 00504 IN BOOL bInitialOwner, 00505 IN LPCSTR lpName OPTIONAL) 00506 { 00507 ConvertWin32AnsiObjectApiToUnicodeApi(Mutex, lpName, lpMutexAttributes, bInitialOwner); 00508 } 00509 00510 /* 00511 * @implemented 00512 */ 00513 HANDLE 00514 WINAPI 00515 CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, 00516 IN BOOL bInitialOwner, 00517 IN LPCWSTR lpName OPTIONAL) 00518 { 00519 CreateNtObjectFromWin32Api(Mutex, Mutant, MUTEX, 00520 lpMutexAttributes, 00521 lpName, 00522 bInitialOwner); 00523 } 00524 00525 /* 00526 * @implemented 00527 */ 00528 HANDLE 00529 WINAPI 00530 OpenMutexA(IN DWORD dwDesiredAccess, 00531 IN BOOL bInheritHandle, 00532 IN LPCSTR lpName) 00533 { 00534 ConvertOpenWin32AnsiObjectApiToUnicodeApi(Mutex, dwDesiredAccess, bInheritHandle, lpName); 00535 } 00536 00537 /* 00538 * @implemented 00539 */ 00540 HANDLE 00541 WINAPI 00542 OpenMutexW(IN DWORD dwDesiredAccess, 00543 IN BOOL bInheritHandle, 00544 IN LPCWSTR lpName) 00545 { 00546 OpenNtObjectFromWin32Api(Mutant, dwDesiredAccess, bInheritHandle, lpName); 00547 } 00548 00549 /* 00550 * @implemented 00551 */ 00552 BOOL 00553 WINAPI 00554 ReleaseMutex(IN HANDLE hMutex) 00555 { 00556 NTSTATUS Status; 00557 00558 /* Release the mutant */ 00559 Status = NtReleaseMutant(hMutex, NULL); 00560 if (NT_SUCCESS(Status)) return TRUE; 00561 00562 /* If we got here, then we failed */ 00563 BaseSetLastNTError(Status); 00564 return FALSE; 00565 } 00566 00567 /* 00568 * @implemented 00569 */ 00570 HANDLE 00571 WINAPI 00572 CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, 00573 IN BOOL bManualReset, 00574 IN BOOL bInitialState, 00575 IN LPCSTR lpName OPTIONAL) 00576 { 00577 ConvertWin32AnsiObjectApiToUnicodeApi(Event, lpName, lpEventAttributes, bManualReset, bInitialState); 00578 } 00579 00580 /* 00581 * @implemented 00582 */ 00583 HANDLE 00584 WINAPI 00585 CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, 00586 IN BOOL bManualReset, 00587 IN BOOL bInitialState, 00588 IN LPCWSTR lpName OPTIONAL) 00589 { 00590 CreateNtObjectFromWin32Api(Event, Event, EVENT, 00591 lpEventAttributes, 00592 lpName, 00593 bManualReset ? NotificationTimer : SynchronizationTimer, 00594 bInitialState); 00595 } 00596 00597 /* 00598 * @implemented 00599 */ 00600 HANDLE 00601 WINAPI 00602 OpenEventA(IN DWORD dwDesiredAccess, 00603 IN BOOL bInheritHandle, 00604 IN LPCSTR lpName) 00605 { 00606 ConvertOpenWin32AnsiObjectApiToUnicodeApi(Event, dwDesiredAccess, bInheritHandle, lpName); 00607 } 00608 00609 /* 00610 * @implemented 00611 */ 00612 HANDLE 00613 WINAPI 00614 OpenEventW(IN DWORD dwDesiredAccess, 00615 IN BOOL bInheritHandle, 00616 IN LPCWSTR lpName) 00617 { 00618 OpenNtObjectFromWin32Api(Event, dwDesiredAccess, bInheritHandle, lpName); 00619 } 00620 00621 /* 00622 * @implemented 00623 */ 00624 BOOL 00625 WINAPI 00626 PulseEvent(IN HANDLE hEvent) 00627 { 00628 NTSTATUS Status; 00629 00630 /* Pulse the event */ 00631 Status = NtPulseEvent(hEvent, NULL); 00632 if (NT_SUCCESS(Status)) return TRUE; 00633 00634 /* If we got here, then we failed */ 00635 BaseSetLastNTError(Status); 00636 return FALSE; 00637 } 00638 00639 /* 00640 * @implemented 00641 */ 00642 BOOL 00643 WINAPI 00644 ResetEvent(IN HANDLE hEvent) 00645 { 00646 NTSTATUS Status; 00647 00648 /* Clear the event */ 00649 Status = NtResetEvent(hEvent, NULL); 00650 if (NT_SUCCESS(Status)) return TRUE; 00651 00652 /* If we got here, then we failed */ 00653 BaseSetLastNTError(Status); 00654 return FALSE; 00655 } 00656 00657 /* 00658 * @implemented 00659 */ 00660 BOOL 00661 WINAPI 00662 SetEvent(IN HANDLE hEvent) 00663 { 00664 NTSTATUS Status; 00665 00666 /* Set the event */ 00667 Status = NtSetEvent(hEvent, NULL); 00668 if (NT_SUCCESS(Status)) return TRUE; 00669 00670 /* If we got here, then we failed */ 00671 BaseSetLastNTError(Status); 00672 return FALSE; 00673 } 00674 00675 /* 00676 * @implemented 00677 */ 00678 VOID 00679 WINAPI 00680 InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection) 00681 { 00682 NTSTATUS Status; 00683 00684 /* Initialize the critical section and raise an exception if we failed */ 00685 Status = RtlInitializeCriticalSection((PVOID)lpCriticalSection); 00686 if (!NT_SUCCESS(Status)) RtlRaiseStatus(Status); 00687 } 00688 00689 /* 00690 * @implemented 00691 */ 00692 BOOL 00693 WINAPI 00694 InitializeCriticalSectionAndSpinCount(OUT LPCRITICAL_SECTION lpCriticalSection, 00695 IN DWORD dwSpinCount) 00696 { 00697 NTSTATUS Status; 00698 00699 /* Initialize the critical section */ 00700 Status = RtlInitializeCriticalSectionAndSpinCount((PVOID)lpCriticalSection, 00701 dwSpinCount); 00702 if (!NT_SUCCESS(Status)) 00703 { 00704 /* Set failure code */ 00705 BaseSetLastNTError(Status); 00706 return FALSE; 00707 } 00708 00709 /* Success */ 00710 return TRUE; 00711 } 00712 00713 /* 00714 * @implemented 00715 */ 00716 VOID 00717 WINAPI 00718 Sleep(IN DWORD dwMilliseconds) 00719 { 00720 /* Call the new API */ 00721 SleepEx(dwMilliseconds, FALSE); 00722 } 00723 00724 00725 /* 00726 * @implemented 00727 */ 00728 DWORD 00729 WINAPI 00730 SleepEx(IN DWORD dwMilliseconds, 00731 IN BOOL bAlertable) 00732 { 00733 LARGE_INTEGER Time; 00734 PLARGE_INTEGER TimePtr; 00735 NTSTATUS errCode; 00736 RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; 00737 00738 /* APCs must execute with the default activation context */ 00739 if (bAlertable) 00740 { 00741 /* Setup the frame */ 00742 RtlZeroMemory(&ActCtx, sizeof(ActCtx)); 00743 ActCtx.Size = sizeof(ActCtx); 00744 ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; 00745 RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); 00746 } 00747 00748 /* Convert the timeout */ 00749 TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds); 00750 if (!TimePtr) 00751 { 00752 /* Turn an infinite wait into a really long wait */ 00753 Time.LowPart = 0; 00754 Time.HighPart = 0x80000000; 00755 TimePtr = &Time; 00756 } 00757 00758 /* Loop the delay while APCs are alerting us */ 00759 do 00760 { 00761 /* Do the delay */ 00762 errCode = NtDelayExecution((BOOLEAN)bAlertable, TimePtr); 00763 } 00764 while ((bAlertable) && (errCode == STATUS_ALERTED)); 00765 00766 /* Cleanup the activation context */ 00767 if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); 00768 00769 /* Return the correct code */ 00770 return (errCode == STATUS_USER_APC) ? WAIT_IO_COMPLETION : 0; 00771 } 00772 00773 /* 00774 * @implemented 00775 */ 00776 BOOL 00777 WINAPI 00778 RegisterWaitForSingleObject(OUT PHANDLE phNewWaitObject, 00779 IN HANDLE hObject, 00780 IN WAITORTIMERCALLBACK Callback, 00781 IN PVOID Context, 00782 IN ULONG dwMilliseconds, 00783 IN ULONG dwFlags) 00784 { 00785 NTSTATUS Status; 00786 00787 /* Get real handle */ 00788 hObject = TranslateStdHandle(hObject); 00789 00790 /* Check for console handle */ 00791 if ((IsConsoleHandle(hObject)) && (VerifyConsoleIoHandle(hObject))) 00792 { 00793 /* Get the real wait handle */ 00794 hObject = GetConsoleInputWaitHandle(); 00795 } 00796 00797 /* Register the wait now */ 00798 Status = RtlRegisterWait(phNewWaitObject, 00799 hObject, 00800 Callback, 00801 Context, 00802 dwMilliseconds, 00803 dwFlags); 00804 if (!NT_SUCCESS(Status)) 00805 { 00806 /* Return failure */ 00807 BaseSetLastNTError(Status); 00808 return FALSE; 00809 } 00810 00811 /* All good */ 00812 return TRUE; 00813 } 00814 00815 /* 00816 * @implemented 00817 */ 00818 HANDLE 00819 WINAPI 00820 RegisterWaitForSingleObjectEx(IN HANDLE hObject, 00821 IN WAITORTIMERCALLBACK Callback, 00822 IN PVOID Context, 00823 IN ULONG dwMilliseconds, 00824 IN ULONG dwFlags) 00825 { 00826 NTSTATUS Status; 00827 HANDLE hNewWaitObject; 00828 00829 /* Get real handle */ 00830 hObject = TranslateStdHandle(hObject); 00831 00832 /* Check for console handle */ 00833 if ((IsConsoleHandle(hObject)) && (VerifyConsoleIoHandle(hObject))) 00834 { 00835 /* Get the real wait handle */ 00836 hObject = GetConsoleInputWaitHandle(); 00837 } 00838 00839 /* Register the wait */ 00840 Status = RtlRegisterWait(&hNewWaitObject, 00841 hObject, 00842 Callback, 00843 Context, 00844 dwMilliseconds, 00845 dwFlags); 00846 if (!NT_SUCCESS(Status)) 00847 { 00848 /* Return failure */ 00849 BaseSetLastNTError(Status); 00850 return NULL; 00851 } 00852 00853 /* Return the object */ 00854 return hNewWaitObject; 00855 } 00856 00857 /* 00858 * @implemented 00859 */ 00860 BOOL 00861 WINAPI 00862 UnregisterWait(IN HANDLE WaitHandle) 00863 { 00864 NTSTATUS Status; 00865 00866 /* Check for invalid handle */ 00867 if (!WaitHandle) 00868 { 00869 /* Fail */ 00870 SetLastError(ERROR_INVALID_HANDLE); 00871 return FALSE; 00872 } 00873 00874 /* Deregister the wait and check status */ 00875 Status = RtlDeregisterWaitEx(WaitHandle, NULL); 00876 if (!(NT_SUCCESS(Status)) || (Status == STATUS_PENDING)) 00877 { 00878 /* Failure or non-blocking call */ 00879 BaseSetLastNTError(Status); 00880 return FALSE; 00881 } 00882 00883 /* All good */ 00884 return TRUE; 00885 } 00886 00887 /* 00888 * @implemented 00889 */ 00890 BOOL 00891 WINAPI 00892 UnregisterWaitEx(IN HANDLE WaitHandle, 00893 IN HANDLE CompletionEvent) 00894 { 00895 NTSTATUS Status; 00896 00897 /* Check for invalid handle */ 00898 if (!WaitHandle) 00899 { 00900 /* Fail */ 00901 SetLastError(ERROR_INVALID_HANDLE); 00902 return FALSE; 00903 } 00904 00905 /* Deregister the wait and check status */ 00906 Status = RtlDeregisterWaitEx(WaitHandle, CompletionEvent); 00907 if (!(NT_SUCCESS(Status)) || 00908 ((CompletionEvent != INVALID_HANDLE_VALUE) && (Status == STATUS_PENDING))) 00909 { 00910 /* Failure or non-blocking call */ 00911 BaseSetLastNTError(Status); 00912 return FALSE; 00913 } 00914 00915 /* All good */ 00916 return TRUE; 00917 } 00918 00919 /* EOF */ Generated on Thu May 24 2012 04:24:46 for ReactOS by
1.7.6.1
|