Index: ntoskrnl/mm/ARM3/pool.c =================================================================== --- ntoskrnl/mm/ARM3/pool.c (revision 66849) +++ ntoskrnl/mm/ARM3/pool.c (working copy) @@ -24,7 +24,7 @@ KGUARDED_MUTEX MmPagedPoolMutex; MM_PAGED_POOL_INFO MmPagedPoolInfo; SIZE_T MmAllocatedNonPagedPool; -ULONG MmSpecialPoolTag; +ULONG MmSpecialPoolTag = 'nevE'; ULONG MmConsumedPoolPercentage; BOOLEAN MmProtectFreedNonPagedPool; SLIST_HEADER MiNonPagedPoolSListHead; Index: win32ss/user/ntuser/msgqueue.c =================================================================== --- win32ss/user/ntuser/msgqueue.c (revision 66849) +++ win32ss/user/ntuser/msgqueue.c (working copy) @@ -1026,12 +1026,13 @@ { PTHREADINFO pti; PUSER_SENT_MESSAGE Message; - KEVENT CompletionEvent; + PKEVENT CompletionEvent; NTSTATUS WaitStatus; LARGE_INTEGER Timeout; PLIST_ENTRY Entry; PWND pWnd; LRESULT Result = 0; //// Result could be trashed. //// + BOOLEAN CleanedMessage; pti = PsGetCurrentThreadWin32Thread(); ASSERT(pti != ptirec); @@ -1098,7 +1099,8 @@ return STATUS_INSUFFICIENT_RESOURCES; } - KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); + CompletionEvent = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), 'nevE'); + KeInitializeEvent(CompletionEvent, NotificationEvent, FALSE); Timeout.QuadPart = Int32x32To64(-10000,uTimeout); // Pass SMTO test with a TO of 0x80000000. TRACE("Timeout val %lld\n",Timeout.QuadPart) @@ -1109,7 +1111,7 @@ Message->Msg.message = Msg; Message->Msg.wParam = wParam; Message->Msg.lParam = lParam; - Message->CompletionEvent = &CompletionEvent; + Message->CompletionEvent = CompletionEvent; Message->Result = &Result; Message->lResult = 0; Message->QS_Flags = 0; @@ -1121,6 +1123,8 @@ Message->HookMessage = HookMessage; Message->HasPackedLParam = FALSE; + CleanedMessage = FALSE; + /* Add it to the list of pending messages */ InsertTailList(&pti->DispatchingMessagesHead, &Message->DispatchingListEntry); @@ -1136,7 +1140,7 @@ { PVOID WaitObjects[2]; - WaitObjects[0] = &CompletionEvent; // Wait 0 + WaitObjects[0] = CompletionEvent; // Wait 0 WaitObjects[1] = ptirec->pEThread; // Wait 1 UserLeaveCo(); @@ -1163,6 +1167,7 @@ RemoveEntryList(&Message->DispatchingListEntry); ClearMsgBitsMask(ptirec, Message->QS_Flags); ExFreePoolWithTag(Message, TAG_USRMSG); + CleanedMessage = TRUE; break; } Entry = Entry->Flink; @@ -1183,11 +1188,16 @@ Message->Result = NULL; RemoveEntryList(&Message->DispatchingListEntry); InitializeListHead(&Message->DispatchingListEntry); + CleanedMessage = TRUE; break; } Entry = Entry->Flink; } } + else + { + CleanedMessage = TRUE; + } while (co_MsqDispatchOneSentMessage(pti)) ; } @@ -1195,7 +1205,7 @@ { PVOID WaitObjects[3]; - WaitObjects[0] = &CompletionEvent; // Wait 0 + WaitObjects[0] = CompletionEvent; // Wait 0 WaitObjects[1] = pti->pEventQueueServer; // Wait 1 WaitObjects[2] = ptirec->pEThread; // Wait 2 @@ -1226,6 +1236,7 @@ InitializeListHead(&Message->DispatchingListEntry); ClearMsgBitsMask(ptirec, Message->QS_Flags); ExFreePoolWithTag(Message, TAG_USRMSG); + CleanedMessage = TRUE; break; } Entry = Entry->Flink; @@ -1248,11 +1259,16 @@ Message->Result = NULL; RemoveEntryList(&Message->DispatchingListEntry); InitializeListHead(&Message->DispatchingListEntry); + CleanedMessage = TRUE; break; } Entry = Entry->Flink; } } + else + { + CleanedMessage = TRUE; + } if (WaitStatus == STATUS_USER_APC) break; @@ -1269,6 +1285,15 @@ ERR("User APC Returned\n"); // Should not see this message. } + /* If we're not sure the message was cleaned up yet, we must wait before + letting the stack event go out of scope */ + if (!CleanedMessage) + { + UserLeaveCo(); + KeWaitForSingleObject(CompletionEvent, Executive, KernelMode, FALSE, NULL); + UserEnterCo(); + } + if (WaitStatus != STATUS_TIMEOUT) { if (uResult) @@ -1277,6 +1302,8 @@ } } + ExFreePoolWithTag(CompletionEvent, 'nevE'); + return WaitStatus; }