Fix the USER32 DLL initialization and cleanup routines to prevent memory/resource...
[reactos.git] / reactos / lib / user32 / windows / message.c
index eb1e463..3169308 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/message.c
@@ -9,14 +8,12 @@
  *      06-06-2001  CSH  Created
  */
 
-#include "user32.h"
-#include <string.h>
+#include <user32.h>
+#define NDEBUG
 #include <debug.h>
-#include <user32/callback.h>
-#include <message.h>
 
 /* DDE message exchange
- * 
+ *
  * - Session initialization
  *   Client sends a WM_DDE_INITIATE message, usually a broadcast message. lParam of
  *   this message contains a pair of global atoms, the Application and Topic atoms.
@@ -92,7 +89,7 @@ DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
         }
       else
         {
-          New = HeapAlloc(GetProcessHeap(), 0, 
+          New = HeapAlloc(GetProcessHeap(), 0,
                           (DdeNumAlloc + GROWBY) * sizeof(DDEPAIR));
         }
 
@@ -196,7 +193,7 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
           SIZE_T Size;
           PKMDDEEXECUTEDATA KMDdeExecuteData;
           PVOID Data;
-          
+
           Size = GlobalSize((HGLOBAL) UMMsg->lParam);
           Data = GlobalLock((HGLOBAL) UMMsg->lParam);
           if (NULL == Data)
@@ -236,7 +233,7 @@ MsgiUMToKMMessage(PMSG UMMsg, PMSG KMMsg, BOOL Posted)
           pKMCopyData->cbData = pUMCopyData->cbData;
           pKMCopyData->lpData = pKMCopyData + 1;
 
-          RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData, 
+          RtlCopyMemory(pKMCopyData + 1, pUMCopyData->lpData,
                         pUMCopyData->cbData);
 
           KMMsg->lParam = (LPARAM)pKMCopyData;
@@ -760,7 +757,7 @@ MsgConversionAdd(PMSGCONVERSION Conversion)
         }
       else
         {
-          New = HeapAlloc(GetProcessHeap(), 0, 
+          New = HeapAlloc(GetProcessHeap(), 0,
                           (MsgConversionNumAlloc + GROWBY) * sizeof(MSGCONVERSION));
         }
 
@@ -966,7 +963,7 @@ IntCallWindowProcW(BOOL IsAnsiProc,
     }
 }
 
-STATIC LRESULT FASTCALL
+static LRESULT FASTCALL
 IntCallWindowProcA(BOOL IsAnsiProc,
                    WNDPROC WndProc,
                    HWND hWnd,
@@ -1632,7 +1629,7 @@ SendMessageTimeoutW(
   LRESULT Result;
 
   Info.Ansi = FALSE;
-  Result = NtUserSendMessageTimeout(hWnd, Msg, wParam, lParam, fuFlags, uTimeout, 
+  Result = NtUserSendMessageTimeout(hWnd, Msg, wParam, lParam, fuFlags, uTimeout,
                                     lpdwResult, &Info);
   if (! Info.HandledByKernel)
     {
@@ -1780,7 +1777,7 @@ STDCALL
 RealGetQueueStatus(UINT flags)
 {
    DWORD ret;
-   WORD changed_bits, wake_bits; 
+   WORD changed_bits, wake_bits;
 
 #if 0 /* wine stuff. don't know what it does... */
 
@@ -1806,7 +1803,7 @@ BOOL STDCALL GetInputState(VOID)
    DWORD ret;
    WORD  wake_bits;
 
-#if 0 /* wine stuff. don't know what it does... */ 
+#if 0 /* wine stuff. don't know what it does... */
 
    /* check for pending X events */
    if (USER_Driver.pMsgWaitForMultipleObjectsEx)
@@ -1814,7 +1811,7 @@ BOOL STDCALL GetInputState(VOID)
 #endif
 
    ret = NtUserGetQueueStatus(FALSE /*ClearChanges*/);
-   
+
    wake_bits = HIWORD(ret);
 
    return wake_bits & (QS_KEY | QS_MOUSEBUTTON);
@@ -1923,7 +1920,7 @@ BOOL WINAPI IsInsideMessagePumpHook()
 {
        if(!gfMessagePumpHook)
                return FALSE;
-       
+
     /* This code checks if we're inside SendMessage. */
 #if 0
        /* Since our TEB doesnt match that of real windows, testing this value is useless until we know what it does
@@ -2038,7 +2035,7 @@ RealMsgWaitForMultipleObjectsEx(
    LPHANDLE RealHandles;
    HANDLE MessageQueueHandle;
    DWORD Result;
-   
+
    if (dwFlags & ~(MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE))
    {
       SetLastError(ERROR_INVALID_PARAMETER);
@@ -2067,7 +2064,7 @@ RealMsgWaitForMultipleObjectsEx(
       return WAIT_FAILED;
    }
 
-   RtlCopyMemory(RealHandles, pHandles, nCount);
+   RtlCopyMemory(RealHandles, pHandles, nCount * sizeof(HANDLE));
    RealHandles[nCount] = MessageQueueHandle;
 
    Result = WaitForMultipleObjectsEx(nCount + 1, RealHandles,
@@ -2110,10 +2107,70 @@ MsgWaitForMultipleObjects(
 }
 
 
-BOOL FASTCALL MessageInit()
+BOOL FASTCALL MessageInit(VOID)
 {
   InitializeCriticalSection(&DdeCrst);
   InitializeCriticalSection(&MsgConversionCrst);
+  InitializeCriticalSection(&gcsMPH);
 
   return TRUE;
 }
+
+VOID FASTCALL MessageCleanup(VOID)
+{
+  DeleteCriticalSection(&DdeCrst);
+  DeleteCriticalSection(&MsgConversionCrst);
+  DeleteCriticalSection(&gcsMPH);
+}
+
+/***********************************************************************
+ *             map_wparam_AtoW
+ *
+ * Convert the wparam of an ASCII message to Unicode.
+ */
+static WPARAM
+map_wparam_AtoW( UINT message, WPARAM wparam )
+{
+    switch(message)
+    {
+    case WM_CHARTOITEM:
+    case EM_SETPASSWORDCHAR:
+    case WM_CHAR:
+    case WM_DEADCHAR:
+    case WM_SYSCHAR:
+    case WM_SYSDEADCHAR:
+    case WM_MENUCHAR:
+        {
+            char ch[2];
+            WCHAR wch[2];
+            ch[0] = (wparam & 0xff);
+            ch[1] = (wparam >> 8);
+            MultiByteToWideChar(CP_ACP, 0, ch, 2, wch, 2);
+            wparam = MAKEWPARAM(wch[0], wch[1]);
+        }
+        break;
+    case WM_IME_CHAR:
+        {
+            char ch[2];
+            WCHAR wch;
+            ch[0] = (wparam >> 8);
+            ch[1] = (wparam & 0xff);
+            if (ch[0]) MultiByteToWideChar(CP_ACP, 0, ch, 2, &wch, 1);
+            else MultiByteToWideChar(CP_ACP, 0, &ch[1], 1, &wch, 1);
+            wparam = MAKEWPARAM( wch, HIWORD(wparam) );
+        }
+        break;
+    }
+    return wparam;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+IsDialogMessageA( HWND hwndDlg, LPMSG pmsg )
+{
+    MSG msg = *pmsg;
+    msg.wParam = map_wparam_AtoW( msg.message, msg.wParam );
+    return IsDialogMessageW( hwndDlg, &msg );
+}