Index: win32ss/user/ntuser/callback.c
===================================================================
--- win32ss/user/ntuser/callback.c	(revision 60907)
+++ win32ss/user/ntuser/callback.c	(working copy)
@@ -334,7 +334,7 @@
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
-      ERR("Failed to copy result from user mode Message %d!\n", Message);
+      ERR("Failed to copy result from user mode, Message %d!\n", Message);
       Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;
@@ -356,9 +356,46 @@
 
    if (0 < lParamBufferSize)
    {
-      RtlMoveMemory((PVOID) lParam,
-                    (PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
-                    lParamBufferSize);
+      PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+      // Is this message being processed from inside kernel space?
+      BOOL InSendMessage = (pti->pcti->CTI_flags & CTI_INSENDMESSAGE);
+
+      TRACE("Copy lParam Message %d lParam %d!\n", Message, lParam);
+      switch (Message)
+      {
+          default:
+            TRACE("Don't copy lParam, Message %d Size %d lParam %d!\n", Message, lParamBufferSize, lParam);
+            break;
+          // Write back to user/kernel space. Also see g_MsgMemory.
+          case WM_CREATE:
+          case WM_GETMINMAXINFO:
+          case WM_GETTEXT:
+          case WM_NCCALCSIZE:
+          case WM_NCCREATE:
+          case WM_STYLECHANGING:
+          case WM_WINDOWPOSCHANGING:
+            TRACE("Copy lParam, Message %d Size %d lParam %d!\n", Message, lParamBufferSize, lParam);
+            if (InSendMessage)
+               // Copy into kernel space.
+               RtlMoveMemory((PVOID) lParam,
+                             (PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
+                              lParamBufferSize);
+            else
+            {
+             _SEH2_TRY
+             { // Copy into user space.
+               RtlMoveMemory((PVOID) lParam,
+                             (PVOID) ((char *) Arguments + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)),
+                              lParamBufferSize);
+             }
+             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+             {
+                ERR("Failed to copy lParam to user space, Message %d!\n", Message);
+             }
+             _SEH2_END
+            }
+            break;
+      }
       IntCbFreeMemory(Arguments);
    }
 
Index: win32ss/user/ntuser/desktop.c
===================================================================
--- win32ss/user/ntuser/desktop.c	(revision 60907)
+++ win32ss/user/ntuser/desktop.c	(working copy)
@@ -847,10 +847,14 @@
       for (; *cursor; cursor++)
       {
          TRACE("Sending notify\n");
-         co_IntPostOrSendMessage(*cursor,
+         UserPostMessage(*cursor,
+                          gpsi->uiShellMsg,
+                          Message,
+                         (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
+/*         co_IntPostOrSendMessage(*cursor,
                                  gpsi->uiShellMsg,
                                  Message,
-                                 (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
+                                 (Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );*/
       }
 
       ExFreePoolWithTag(HwndList, USERTAG_WINDOWLIST);
Index: win32ss/user/ntuser/focus.c
===================================================================
--- win32ss/user/ntuser/focus.c	(revision 60907)
+++ win32ss/user/ntuser/focus.c	(working copy)
@@ -112,7 +112,8 @@
 
       /* Send palette messages */
       if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
-          co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
+          //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
+          co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
       {
          UserSendNotifyMessage( HWND_BROADCAST,
                                 WM_PALETTEISCHANGING,
@@ -184,7 +185,7 @@
                   }
                }
             }
-            ExFreePool(List);//ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+            ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
          }
       }
       if (WindowPrev)
@@ -251,12 +252,14 @@
    {
       if (pWndPrev)
       {
-         co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
+         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
+         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
       }
       if (ThreadQueue->spwndFocus == pWnd)
       {
          IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
-         co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
+         //co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
+         co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
       }
    }
    else
@@ -264,7 +267,8 @@
       if (pWndPrev)
       {
          IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
-         co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
+         //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
+         co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
       }
    }
 }
@@ -933,7 +937,8 @@
    {
       if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
 
-      co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
+      //co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
+      co_IntSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
 
       ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
    }
Index: win32ss/user/ntuser/message.c
===================================================================
--- win32ss/user/ntuser/message.c	(revision 60907)
+++ win32ss/user/ntuser/message.c	(working copy)
@@ -128,7 +128,7 @@
     { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
     { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
     { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
-    { WM_SETTINGCHANGE, MMS_SIZE_LPARAMSZ, MMS_FLAG_READWRITE },
+    { WM_SETTINGCHANGE, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
     { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
     { WM_COPYGLOBALDATA, MMS_SIZE_WPARAM, MMS_FLAG_READ },
     { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
@@ -447,7 +447,7 @@
             Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
             if (! NT_SUCCESS(Status))
             {
-                ERR("Failed to copy message to kernel: invalid usermode buffer\n");
+                ERR("Failed to copy message to kernel: invalid usermode lParam buffer\n");
                 ExFreePoolWithTag(KernelMem, TAG_MSG);
                 return Status;
             }
@@ -492,7 +492,7 @@
             Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
             if (! NT_SUCCESS(Status))
             {
-                ERR("Failed to copy message from kernel: invalid usermode buffer\n");
+                ERR("Failed to copy message from kernel: invalid usermode lParam buffer\n");
                 ExFreePool((PVOID) KernelModeMsg->lParam);
                 return Status;
             }
@@ -1100,12 +1100,13 @@
 {
    if ( ptiCur )
    {
-      if ( Window->head.pti->MessageQueue == ptiCur->MessageQueue )
+      if (!Window ||
+           Window->head.pti->MessageQueue == ptiCur->MessageQueue )
       {
          return NULL;
       }
    }
-   return Window->head.pti;
+   return Window ? Window->head.pti : NULL;
 }
 
 BOOL FASTCALL
@@ -1718,20 +1719,19 @@
     return (LRESULT)Result;
 }
 
-LRESULT FASTCALL
+static LRESULT FASTCALL
 co_IntDoSendMessage( HWND hWnd,
                      UINT Msg,
                      WPARAM wParam,
                      LPARAM lParam,
                      PDOSENDMESSAGE dsm)
 {
-    //PTHREADINFO pti;
     LRESULT Result = TRUE;
     NTSTATUS Status;
     PWND Window = NULL;
-    MSG UserModeMsg;
-    MSG KernelModeMsg;
+    MSG UserModeMsg, KernelModeMsg;
     PMSGMEMORY MsgMemoryEntry;
+    PTHREADINFO ptiSendTo;
 
     if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
     {
@@ -1748,21 +1748,31 @@
         ERR("co_IntDoSendMessage Window Exiting!\n");
     }
 
-    /* See if the current thread can handle the message */
-    //pti = PsGetCurrentThreadWin32Thread();
+    /* See if the current thread can handle this message */
+    ptiSendTo = IntSendTo(Window, gptiCurrent, Msg);
 
-    UserModeMsg.hwnd = hWnd;
-    UserModeMsg.message = Msg;
-    UserModeMsg.wParam = wParam;
-    UserModeMsg.lParam = lParam;
-    MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
-
-    Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
-    if (! NT_SUCCESS(Status))
+    // If broadcasting or sending to another thread, save the users data.
+    if (!Window || ptiSendTo )
     {
-       EngSetLastError(ERROR_INVALID_PARAMETER);
-       return (dsm ? 0 : -1);
+       UserModeMsg.hwnd    = hWnd;
+       UserModeMsg.message = Msg;
+       UserModeMsg.wParam  = wParam;
+       UserModeMsg.lParam  = lParam;
+       MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
+       Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
+       if (!NT_SUCCESS(Status))
+       {
+          EngSetLastError(ERROR_INVALID_PARAMETER);
+          return (dsm ? 0 : -1);
+       }
     }
+    else
+    {
+       KernelModeMsg.hwnd    = hWnd;
+       KernelModeMsg.message = Msg;
+       KernelModeMsg.wParam  = wParam;
+       KernelModeMsg.lParam  = lParam;
+    }
 
     if (!dsm)
     {
@@ -1782,11 +1792,14 @@
                                          &dsm->Result );
     }
 
-    Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
-    if (! NT_SUCCESS(Status))
+    if (!Window || ptiSendTo )
     {
-       EngSetLastError(ERROR_INVALID_PARAMETER);
-       return(dsm ? 0 : -1);
+       Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
+       if (!NT_SUCCESS(Status))
+       {
+          EngSetLastError(ERROR_INVALID_PARAMETER);
+          return(dsm ? 0 : -1);
+       }
     }
 
     return (LRESULT)Result;
