Index: win32ss/user/ntuser/main.c
===================================================================
--- win32ss/user/ntuser/main.c	(revision 69652)
+++ win32ss/user/ntuser/main.c	(working copy)
@@ -518,6 +518,9 @@
         goto error;
     }
 
+    ptiCurrent->apEvent = ExAllocatePoolWithTag(NonPagedPool, MAX_KEVENT_COUNT * sizeof(PKEVENT), USERTAG_EVENT);
+    RtlZeroMemory(ptiCurrent->apEvent, MAX_KEVENT_COUNT * sizeof(PKEVENT));
+
     KeQueryTickCount(&LargeTickCount);
     ptiCurrent->timeLast = LargeTickCount.u.LowPart;
 
@@ -778,6 +781,8 @@
         }
     }
 
+    if (ptiCurrent->apEvent) ExFreePoolWithTag(ptiCurrent->apEvent, USERTAG_EVENT);
+
     /* Find the THREADINFO in the PROCESSINFO's list */
     ppti = &ppiCurrent->ptiList;
     while (*ppti != NULL && *ppti != ptiCurrent)
Index: win32ss/user/ntuser/msgqueue.c
===================================================================
--- win32ss/user/ntuser/msgqueue.c	(revision 69652)
+++ win32ss/user/ntuser/msgqueue.c	(working copy)
@@ -1032,11 +1032,13 @@
 {
    PTHREADINFO pti;
    PUSER_SENT_MESSAGE Message;
-   KEVENT CompletionEvent;
+   //KEVENT CompletionEvent;
+   INT cEvent;
    NTSTATUS WaitStatus;
    LARGE_INTEGER Timeout;
    PLIST_ENTRY Entry;
    PWND pWnd;
+   BOOLEAN SwapStateEnable;
    LRESULT Result = 0;   //// Result could be trashed. ////
 
    pti = PsGetCurrentThreadWin32Thread();
@@ -1111,7 +1113,21 @@
       return STATUS_INSUFFICIENT_RESOURCES;
    }
 
-   KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
+   cEvent = pti->cEnterCount;
+   if (cEvent > MAX_KEVENT_COUNT)
+   {
+      ERR("This in no way can happen! Atleast 3 has been seen!\n");
+   }
+   if (pti->apEvent[cEvent] == 0)
+   {
+      pti->apEvent[cEvent] = ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), USERTAG_EVENT);
+      KeInitializeEvent(pti->apEvent[cEvent], NotificationEvent, FALSE);
+   }
+   else
+   {
+      KeClearEvent(pti->apEvent[cEvent]);
+   }
+   //KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
 
    Timeout.QuadPart = Int32x32To64(-10000,uTimeout); // Pass SMTO test with a TO of 0x80000000.
    TRACE("Timeout val %lld\n",Timeout.QuadPart)
@@ -1122,7 +1138,7 @@
    Message->Msg.message = Msg;
    Message->Msg.wParam = wParam;
    Message->Msg.lParam = lParam;
-   Message->CompletionEvent = &CompletionEvent;
+   Message->CompletionEvent = pti->apEvent[cEvent]; //&CompletionEvent;
    Message->Result = &Result;
    Message->lResult = 0;
    Message->QS_Flags = 0;
@@ -1143,6 +1159,13 @@
    Message->QS_Flags = QS_SENDMESSAGE;
    MsqWakeQueue(ptirec, QS_SENDMESSAGE, TRUE);
 
+   if (pti->cEnterCount == 0)
+   {
+      SwapStateEnable = KeSetKernelStackSwapEnable(FALSE);
+   }
+   pti->cEnterCount++;
+   ERR("coMSM entry count %d\n",pti->cEnterCount);
+
    /* We can't access the Message anymore since it could have already been deleted! */
 
    if (Block)
@@ -1149,7 +1172,7 @@
    {
       PVOID WaitObjects[2];
 
-      WaitObjects[0] = &CompletionEvent;       // Wait 0
+      WaitObjects[0] = pti->apEvent[cEvent]; //&CompletionEvent;       // Wait 0
       WaitObjects[1] = ptirec->pEThread;       // Wait 1
 
       UserLeaveCo();
@@ -1208,7 +1231,7 @@
    {
       PVOID WaitObjects[3];
 
-      WaitObjects[0] = &CompletionEvent;       // Wait 0
+      WaitObjects[0] = pti->apEvent[cEvent]; //&CompletionEvent;       // Wait 0
       WaitObjects[1] = pti->pEventQueueServer; // Wait 1
       WaitObjects[2] = ptirec->pEThread;       // Wait 2
 
@@ -1275,6 +1298,11 @@
       } while (WaitStatus == STATUS_WAIT_1);
    }
 
+   if (--pti->cEnterCount == 0 )
+   {
+      KeSetKernelStackSwapEnable(SwapStateEnable);
+   }
+
    if (WaitStatus == STATUS_USER_APC)
    {
      // The current thread is dying!
Index: win32ss/user/ntuser/win32.h
===================================================================
--- win32ss/user/ntuser/win32.h	(revision 69652)
+++ win32ss/user/ntuser/win32.h	(working copy)
@@ -34,6 +34,7 @@
 #define W32PF_APIHOOKLOADED          (0x08000000)
 
 #define QSIDCOUNTS 7
+#define MAX_KEVENT_COUNT 64
 
 typedef enum _QS_ROS_TYPES
 {
@@ -127,10 +128,12 @@
     INT                 iCursorLevel;
     POINT               ptLast;
 
+    INT                 cEnterCount;
     /* Queue of messages posted to the queue. */
     LIST_ENTRY          PostedMessagesListHead; // mlPost
     WORD                fsChangeBitsRemoved;
     WCHAR               wchInjected;
+    PKEVENT             *apEvent;
     UINT                cWindows;
     UINT                cVisWindows;
 #ifndef __cplusplus /// FIXME!
