Now that CSRSS is getting unloaded we must unregister the primitive message queue when it's about to be destroyed.
Modified: trunk/reactos/subsys/win32k/include/input.h
Modified: trunk/reactos/subsys/win32k/ntuser/misc.c
Modified: trunk/reactos/subsys/win32k/ntuser/msgqueue.c

Modified: trunk/reactos/subsys/win32k/include/input.h
--- trunk/reactos/subsys/win32k/include/input.h	2005-03-17 02:11:04 UTC (rev 14158)
+++ trunk/reactos/subsys/win32k/include/input.h	2005-03-17 13:07:28 UTC (rev 14159)
@@ -8,6 +8,7 @@
 NTSTATUS FASTCALL
 InitKeyboardImpl(VOID);
 PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID);
+VOID W32kUnregisterPrimitiveMessageQueue(VOID);
 PKBDTABLES W32kGetDefaultKeyLayout(VOID);
 VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout);
 BOOL FASTCALL IntBlockInput(PW32THREAD W32Thread, BOOL BlockIt);

Modified: trunk/reactos/subsys/win32k/ntuser/misc.c
--- trunk/reactos/subsys/win32k/ntuser/misc.c	2005-03-17 02:11:04 UTC (rev 14158)
+++ trunk/reactos/subsys/win32k/ntuser/misc.c	2005-03-17 13:07:28 UTC (rev 14159)
@@ -17,13 +17,15 @@
 /* registered Logon process */
 PW32PROCESS LogonProcess = NULL;
 
-void W32kRegisterPrimitiveMessageQueue() {
+VOID W32kRegisterPrimitiveMessageQueue(VOID)
+{
   extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
   if( !pmPrimitiveMessageQueue ) {
     PW32THREAD pThread;
     pThread = PsGetWin32Thread();
     if( pThread && pThread->MessageQueue ) {
       pmPrimitiveMessageQueue = pThread->MessageQueue;
+      IntReferenceMessageQueue(pmPrimitiveMessageQueue);
       DPRINT( "Installed primitive input queue.\n" );
     }    
   } else {
@@ -31,8 +33,16 @@
   }
 }
 
-PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue() {
+VOID W32kUnregisterPrimitiveMessageQueue(VOID)
+{
   extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
+  IntDereferenceMessageQueue(pmPrimitiveMessageQueue);
+  pmPrimitiveMessageQueue = NULL;
+}
+
+PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue()
+{
+  extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
   return pmPrimitiveMessageQueue;
 }
 

Modified: trunk/reactos/subsys/win32k/ntuser/msgqueue.c
--- trunk/reactos/subsys/win32k/ntuser/msgqueue.c	2005-03-17 02:11:04 UTC (rev 14158)
+++ trunk/reactos/subsys/win32k/ntuser/msgqueue.c	2005-03-17 13:07:28 UTC (rev 14159)
@@ -1413,15 +1413,21 @@
 MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
 {
   PDESKTOP_OBJECT desk;
+
   /* remove the message queue from any desktops */
-  if((desk = (PDESKTOP_OBJECT)InterlockedExchange((LONG*)&MessageQueue->Desktop, 0)))
-  {
-    InterlockedExchange((LONG*)&desk->ActiveMessageQueue, 0);
-    IntDereferenceMessageQueue(MessageQueue);
-  }
+  if ((desk = (PDESKTOP_OBJECT)InterlockedExchange((LONG*)&MessageQueue->Desktop, 0)))
+    {
+      InterlockedExchange((LONG*)&desk->ActiveMessageQueue, 0);
+      IntDereferenceMessageQueue(MessageQueue);
+    }
   
+  /* if this is the primitive message queue, deregister it */
+  if (MessageQueue == W32kGetPrimitiveMessageQueue())
+    W32kUnregisterPrimitiveMessageQueue();
+
   /* clean it up */
   MsqCleanupMessageQueue(MessageQueue);
+
   /* decrease the reference counter, if it hits zero, the queue will be freed */
   IntDereferenceMessageQueue(MessageQueue);
 }