Author: ion Date: Sat Jul 23 11:17:36 2011 New Revision: 52799
URL: http://svn.reactos.org/svn/reactos?rev=52799&view=rev Log: [KERNEL32]: Fix Bugs #30, #31, #32, #33: WaitForSingleObjectEx, WaitForMultipleObjectsEx, SignalObjectAndWait, SleepEx need to set the default activation context active so that APCs can execute under it in the case of alertable wait. [KERNEL32]: Fix Bug #34: WaitForMultipleObjectsEx was leaking the wait block array in case of a wait failure.
Modified: trunk/reactos/dll/win32/kernel32/client/synch.c
Modified: trunk/reactos/dll/win32/kernel32/client/synch.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/s... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/synch.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/synch.c [iso-8859-1] Sat Jul 23 11:17:36 2011 @@ -38,6 +38,17 @@ PLARGE_INTEGER TimePtr; LARGE_INTEGER Time; NTSTATUS Status; + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; + + /* APCs must execute with the default activation context */ + if (bAlertable) + { + /* Setup the frame */ + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + ActCtx.Size = sizeof(ActCtx); + ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; + RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); + }
/* Get real handle */ hHandle = TranslateStdHandle(hHandle); @@ -60,10 +71,13 @@ if (!NT_SUCCESS(Status)) { /* The wait failed */ - SetLastErrorByStatus (Status); - return WAIT_FAILED; + SetLastErrorByStatus(Status); + Status = WAIT_FAILED; } } while ((Status == STATUS_ALERTED) && (bAlertable)); + + /* Cleanup the activation context */ + if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);
/* Return wait status */ return Status; @@ -104,6 +118,17 @@ HANDLE Handle[8]; DWORD i; NTSTATUS Status; + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; + + /* APCs must execute with the default activation context */ + if (bAlertable) + { + /* Setup the frame */ + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + ActCtx.Size = sizeof(ActCtx); + ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; + RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); + }
/* Check if we have more handles then we locally optimize */ if (nCount > 8) @@ -116,6 +141,7 @@ { /* No buffer, fail the wait */ SetLastError(ERROR_NOT_ENOUGH_MEMORY); + if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); return WAIT_FAILED; } } @@ -156,8 +182,8 @@ if (!NT_SUCCESS(Status)) { /* Wait failed */ - SetLastErrorByStatus (Status); - return WAIT_FAILED; + SetLastErrorByStatus(Status); + Status = WAIT_FAILED; } } while ((Status == STATUS_ALERTED) && (bAlertable));
@@ -168,6 +194,9 @@ RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer); }
+ /* Cleanup the activation context */ + if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); + /* Return wait status */ return Status; } @@ -185,7 +214,18 @@ PLARGE_INTEGER TimePtr; LARGE_INTEGER Time; NTSTATUS Status; - + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; + + /* APCs must execute with the default activation context */ + if (bAlertable) + { + /* Setup the frame */ + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + ActCtx.Size = sizeof(ActCtx); + ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; + RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); + } + /* Get real handle */ hObjectToWaitOn = TranslateStdHandle(hObjectToWaitOn);
@@ -211,11 +251,14 @@ if (!NT_SUCCESS(Status)) { /* The wait failed */ - SetLastErrorByStatus (Status); - return WAIT_FAILED; + SetLastErrorByStatus(Status); + Status = WAIT_FAILED; } } while ((Status == STATUS_ALERTED) && (bAlertable));
+ /* Cleanup the activation context */ + if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx); + /* Return wait status */ return Status; } @@ -630,6 +673,17 @@ LARGE_INTEGER Time; PLARGE_INTEGER TimePtr; NTSTATUS errCode; + RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME ActCtx; + + /* APCs must execute with the default activation context */ + if (bAlertable) + { + /* Setup the frame */ + RtlZeroMemory(&ActCtx, sizeof(ActCtx)); + ActCtx.Size = sizeof(ActCtx); + ActCtx.Format = RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER; + RtlActivateActivationContextUnsafeFast(&ActCtx, NULL); + }
/* Convert the timeout */ TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);