mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 20:50:29 +00:00
[NTOS]
- In ExpReleaseOrWaitForKeyedEvent, always restore previous values for ETHREAD::KeyedWaitValue and ETHREAD::KeyedWaitChain, as these fields have alternative meanings outside of keyed events - Add missing list walk in ExpReleaseOrWaitForKeyedEvent - In Nt(WaitFor|Release)KeyedEvent, refuse keys that are not two-byte aligned as shown by Wine tests - Don't forget to set KTHREAD::Process on thread creation Fixes hang when running ntdll_winetest:om as well as failing tests. ROSTESTS-118 #resolve svn path=/trunk/; revision=66304
This commit is contained in:
parent
3ce6fcf3b2
commit
05b349a93c
3 changed files with 28 additions and 8 deletions
|
@ -132,6 +132,7 @@ ExpReleaseOrWaitForKeyedEvent(
|
|||
PLIST_ENTRY ListEntry, WaitListHead1, WaitListHead2;
|
||||
NTSTATUS Status;
|
||||
ULONG_PTR HashIndex;
|
||||
PVOID PreviousKeyedWaitValue;
|
||||
|
||||
/* Get the current process */
|
||||
CurrentProcess = KeGetCurrentProcess();
|
||||
|
@ -167,6 +168,7 @@ ExpReleaseOrWaitForKeyedEvent(
|
|||
be signaled by this thread or, when the wait is aborted due to thread
|
||||
termination, then it first needs to acquire the list lock. */
|
||||
Thread = CONTAINING_RECORD(ListEntry, ETHREAD, KeyedWaitChain);
|
||||
ListEntry = ListEntry->Flink;
|
||||
|
||||
/* Check if this thread is a correct waiter */
|
||||
if ((Thread->Tcb.Process == CurrentProcess) &&
|
||||
|
@ -179,7 +181,10 @@ ExpReleaseOrWaitForKeyedEvent(
|
|||
InitializeListHead(&Thread->KeyedWaitChain);
|
||||
|
||||
/* Wake the thread */
|
||||
KeReleaseSemaphore(&Thread->KeyedWaitSemaphore, 0, 1, FALSE);
|
||||
KeReleaseSemaphore(&Thread->KeyedWaitSemaphore,
|
||||
IO_NO_INCREMENT,
|
||||
1,
|
||||
FALSE);
|
||||
Thread = NULL;
|
||||
|
||||
/* Unlock the list. After this it is not safe to access Thread */
|
||||
|
@ -193,7 +198,8 @@ ExpReleaseOrWaitForKeyedEvent(
|
|||
/* Get the current thread */
|
||||
CurrentThread = PsGetCurrentThread();
|
||||
|
||||
/* Set the wait key */
|
||||
/* Set the wait key and remember the old value */
|
||||
PreviousKeyedWaitValue = CurrentThread->KeyedWaitValue;
|
||||
CurrentThread->KeyedWaitValue = KeyedWaitValue;
|
||||
|
||||
/* Initialize the wait semaphore */
|
||||
|
@ -221,10 +227,11 @@ ExpReleaseOrWaitForKeyedEvent(
|
|||
ExAcquirePushLockExclusive(&KeyedEvent->HashTable[HashIndex].Lock);
|
||||
|
||||
/* Check if the wait list entry is still in the list */
|
||||
if (CurrentThread->KeyedWaitChain.Flink != &CurrentThread->KeyedWaitChain)
|
||||
if (!IsListEmpty(&CurrentThread->KeyedWaitChain))
|
||||
{
|
||||
/* Remove the thread from the list */
|
||||
RemoveEntryList(&CurrentThread->KeyedWaitChain);
|
||||
InitializeListHead(&CurrentThread->KeyedWaitChain);
|
||||
}
|
||||
|
||||
/* Unlock the list */
|
||||
|
@ -232,6 +239,9 @@ ExpReleaseOrWaitForKeyedEvent(
|
|||
KeLeaveCriticalRegion();
|
||||
}
|
||||
|
||||
/* Restore the previous KeyedWaitValue, since this is a union member */
|
||||
CurrentThread->KeyedWaitValue = PreviousKeyedWaitValue;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -412,6 +422,12 @@ NtWaitForKeyedEvent(
|
|||
NTSTATUS Status;
|
||||
LARGE_INTEGER TimeoutCopy;
|
||||
|
||||
/* Key must always be two-byte aligned */
|
||||
if ((ULONG_PTR)Key & 1)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
/* Check if the caller passed a timeout value and this is from user mode */
|
||||
if ((Timeout != NULL) && (PreviousMode != KernelMode))
|
||||
{
|
||||
|
@ -472,6 +488,12 @@ NtReleaseKeyedEvent(
|
|||
NTSTATUS Status;
|
||||
LARGE_INTEGER TimeoutCopy;
|
||||
|
||||
/* Key must always be two-byte aligned */
|
||||
if ((ULONG_PTR)Key & 1)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
}
|
||||
|
||||
/* Check if the caller passed a timeout value and this is from user mode */
|
||||
if ((Timeout != NULL) && (PreviousMode != KernelMode))
|
||||
{
|
||||
|
|
|
@ -838,8 +838,9 @@ KeInitThread(IN OUT PKTHREAD Thread,
|
|||
TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
|
||||
TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
|
||||
|
||||
/* Set the TEB */
|
||||
/* Set the TEB and process */
|
||||
Thread->Teb = Teb;
|
||||
Thread->Process = Process;
|
||||
|
||||
/* Check if we have a kernel stack */
|
||||
if (!KernelStack)
|
||||
|
|
|
@ -1080,8 +1080,5 @@ START_TEST(om)
|
|||
test_query_object();
|
||||
test_type_mismatch();
|
||||
test_event();
|
||||
if (winetest_interactive)
|
||||
test_keyed_events();
|
||||
else
|
||||
skip("Skipping test_keyed_events(). ROSTESTS-118.\n");
|
||||
test_keyed_events();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue