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/…
==============================================================================
--- 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);