ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

synch.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.