mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 20:36:35 +00:00
[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. svn path=/trunk/; revision=52799
This commit is contained in:
parent
72e42d63b1
commit
2179ae0c5e
1 changed files with 61 additions and 7 deletions
|
@ -38,6 +38,17 @@ WaitForSingleObjectEx(IN HANDLE hHandle,
|
||||||
PLARGE_INTEGER TimePtr;
|
PLARGE_INTEGER TimePtr;
|
||||||
LARGE_INTEGER Time;
|
LARGE_INTEGER Time;
|
||||||
NTSTATUS Status;
|
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 */
|
/* Get real handle */
|
||||||
hHandle = TranslateStdHandle(hHandle);
|
hHandle = TranslateStdHandle(hHandle);
|
||||||
|
@ -60,10 +71,13 @@ WaitForSingleObjectEx(IN HANDLE hHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* The wait failed */
|
/* The wait failed */
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus(Status);
|
||||||
return WAIT_FAILED;
|
Status = WAIT_FAILED;
|
||||||
}
|
}
|
||||||
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
||||||
|
|
||||||
|
/* Cleanup the activation context */
|
||||||
|
if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||||
|
|
||||||
/* Return wait status */
|
/* Return wait status */
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -104,6 +118,17 @@ WaitForMultipleObjectsEx(IN DWORD nCount,
|
||||||
HANDLE Handle[8];
|
HANDLE Handle[8];
|
||||||
DWORD i;
|
DWORD i;
|
||||||
NTSTATUS Status;
|
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 */
|
/* Check if we have more handles then we locally optimize */
|
||||||
if (nCount > 8)
|
if (nCount > 8)
|
||||||
|
@ -116,6 +141,7 @@ WaitForMultipleObjectsEx(IN DWORD nCount,
|
||||||
{
|
{
|
||||||
/* No buffer, fail the wait */
|
/* No buffer, fail the wait */
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||||
return WAIT_FAILED;
|
return WAIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,8 +182,8 @@ WaitForMultipleObjectsEx(IN DWORD nCount,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Wait failed */
|
/* Wait failed */
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus(Status);
|
||||||
return WAIT_FAILED;
|
Status = WAIT_FAILED;
|
||||||
}
|
}
|
||||||
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
||||||
|
|
||||||
|
@ -168,6 +194,9 @@ WaitForMultipleObjectsEx(IN DWORD nCount,
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, HandleBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cleanup the activation context */
|
||||||
|
if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||||
|
|
||||||
/* Return wait status */
|
/* Return wait status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +214,18 @@ SignalObjectAndWait(IN HANDLE hObjectToSignal,
|
||||||
PLARGE_INTEGER TimePtr;
|
PLARGE_INTEGER TimePtr;
|
||||||
LARGE_INTEGER Time;
|
LARGE_INTEGER Time;
|
||||||
NTSTATUS Status;
|
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 */
|
/* Get real handle */
|
||||||
hObjectToWaitOn = TranslateStdHandle(hObjectToWaitOn);
|
hObjectToWaitOn = TranslateStdHandle(hObjectToWaitOn);
|
||||||
|
|
||||||
|
@ -211,11 +251,14 @@ SignalObjectAndWait(IN HANDLE hObjectToSignal,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* The wait failed */
|
/* The wait failed */
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus(Status);
|
||||||
return WAIT_FAILED;
|
Status = WAIT_FAILED;
|
||||||
}
|
}
|
||||||
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
} while ((Status == STATUS_ALERTED) && (bAlertable));
|
||||||
|
|
||||||
|
/* Cleanup the activation context */
|
||||||
|
if (bAlertable) RtlDeactivateActivationContextUnsafeFast(&ActCtx);
|
||||||
|
|
||||||
/* Return wait status */
|
/* Return wait status */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -630,6 +673,17 @@ SleepEx(IN DWORD dwMilliseconds,
|
||||||
LARGE_INTEGER Time;
|
LARGE_INTEGER Time;
|
||||||
PLARGE_INTEGER TimePtr;
|
PLARGE_INTEGER TimePtr;
|
||||||
NTSTATUS errCode;
|
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 */
|
/* Convert the timeout */
|
||||||
TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
|
TimePtr = BaseFormatTimeOut(&Time, dwMilliseconds);
|
||||||
|
|
Loading…
Reference in a new issue