https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2ab858c125a6c01c03c99…
commit 2ab858c125a6c01c03c99ace13a880fca60f5c19
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Aug 23 16:25:21 2021 +0900
Commit:     GitHub <noreply(a)github.com>
CommitDate: Mon Aug 23 16:25:21 2021 +0900
    [USER32][IMM32] Improve User32InitializeImmEntryTable (#3918)
    - Improve User32InitializeImmEntryTable function and related.
    - Complete win32ss/user/user32/include/immtable.h table.
    - Delete a hack in user32.DllMain and apply my magical tricks. This will fix some
access violations in IMM32.
    - Add some stubs into IMM32.
    CORE-11700
---
 dll/win32/imm32/imm.c                  |  1 +
 dll/win32/imm32/imm32.spec             |  4 ++
 win32ss/user/user32/include/immtable.h |  4 ++
 win32ss/user/user32/include/user32.h   |  4 ++
 win32ss/user/user32/misc/dllmain.c     | 26 ++++++-----
 win32ss/user/user32/misc/imm.c         | 80 +++++++++++++++++++---------------
 6 files changed, 73 insertions(+), 46 deletions(-)
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 675f4d0c648..87097af5ad2 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -5154,6 +5154,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID
lpReserved)
         case DLL_PROCESS_DETACH:
             RtlDeleteCriticalSection(&g_csImeDpi);
+            TRACE("imm32.dll is unloaded\n");
             break;
     }
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec
index 7ff287d3657..ba038cbcfb2 100644
--- a/dll/win32/imm32/imm32.spec
+++ b/dll/win32/imm32/imm32.spec
@@ -1,5 +1,9 @@
 @ stdcall CtfImmIsCiceroEnabled()
 @ stdcall CtfImmIsTextFrameServiceDisabled()
+@ stdcall -stub CtfImmTIMActivate(ptr)
+@ stdcall -stub CtfImmRestoreToolbarWnd(long)
+@ stdcall -stub CtfImmHideToolbarWnd()
+@ stdcall -stub CtfImmDispatchDefImeMessage(ptr long ptr ptr)
 @ stdcall -stub ImmActivateLayout(long)
 @ stdcall ImmAssociateContext(ptr ptr)
 @ stdcall ImmAssociateContextEx(ptr ptr long)
diff --git a/win32ss/user/user32/include/immtable.h
b/win32ss/user/user32/include/immtable.h
index ca37779bdd2..4e194a02811 100644
--- a/win32ss/user/user32/include/immtable.h
+++ b/win32ss/user/user32/include/immtable.h
@@ -51,3 +51,7 @@ DEFINE_IMM_ENTRY(BOOL, ImmSetCompositionStringA, (HIMC hIMC, DWORD
dwIndex, LPCV
 DEFINE_IMM_ENTRY(BOOL, ImmSetCompositionStringW, (HIMC hIMC, DWORD dwIndex, LPCVOID
lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen), 0, NONVOID)
 DEFINE_IMM_ENTRY(BOOL, ImmEnumInputContext, (DWORD dwThreadID, IMCENUMPROC lpfn, LPARAM
lParam), 0, NONVOID)
 DEFINE_IMM_ENTRY(LRESULT, ImmSystemHandler, (HIMC hIMC, WPARAM wParam, LPARAM lParam), 0,
NONVOID)
+DEFINE_IMM_ENTRY(LRESULT, CtfImmTIMActivate, (HKL hKL), 0, NONVOID)
+DEFINE_IMM_ENTRY(VOID, CtfImmRestoreToolbarWnd, (DWORD dwStatus), 0, VOID)
+DEFINE_IMM_ENTRY(DWORD, CtfImmHideToolbarWnd, (VOID), 0, NONVOID)
+DEFINE_IMM_ENTRY(LRESULT, CtfImmDispatchDefImeMessage, (HWND hWnd, UINT uMsg, WPARAM
wParam, LPARAM lParam), 0, NONVOID)
diff --git a/win32ss/user/user32/include/user32.h b/win32ss/user/user32/include/user32.h
index 2615fb61549..8431d54f838 100644
--- a/win32ss/user/user32/include/user32.h
+++ b/win32ss/user/user32/include/user32.h
@@ -72,4 +72,8 @@ typedef struct _PATRECT
     HBRUSH hBrush;
 } PATRECT, * PPATRECT;
+HRESULT
+GetImmFileName(_Out_ LPWSTR lpBuffer,
+               _In_ size_t cchBuffer);
+
 #endif /* _USER32_PCH_ */
diff --git a/win32ss/user/user32/misc/dllmain.c b/win32ss/user/user32/misc/dllmain.c
index 6f43b9eeb6b..b757ea22e9d 100644
--- a/win32ss/user/user32/misc/dllmain.c
+++ b/win32ss/user/user32/misc/dllmain.c
@@ -1,6 +1,6 @@
 #include <user32.h>
-
 #include <ndk/cmfuncs.h>
+#include <strsafe.h>
 #define MAX_USER_MODE_DRV_BUFFER 526
@@ -438,6 +438,7 @@ Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/)
         gHandleTable = SharedPtrToUser(UserCon->siClient.aheList);
         gHandleEntries = SharedPtrToUser(gHandleTable->handles);
         gSharedInfo = UserCon->siClient;
+        gSharedInfo.psi = gpsi;
     }
     // FIXME: Yet another hack... This call should normally not be done here, but
@@ -544,18 +545,19 @@ DllMain(
             if (!gfServerProcess)
             {
-#if WIN32K_ISNT_BROKEN
-               InitializeImmEntryTable();
-#else
-               /* imm32 takes a refcount and prevents us from unloading */
-               LoadLibraryW(L"user32");
-#endif
-               //
-               // Wine is stub and throws an exception so save this for real Imm32.dll
testing!!!!
-               //
-               //gImmApiEntries.pImmRegisterClient(&gSharedInfo, ghImm32);
+                HINSTANCE hImm32 = NULL;
+
+                if (gpsi && (gpsi->dwSRVIFlags & SRVINFO_IMM32))
+                {
+                    WCHAR szImmFile[MAX_PATH];
+                    InitializeImmEntryTable();
+                    GetImmFileName(szImmFile, _countof(szImmFile));
+                    hImm32 = GetModuleHandleW(szImmFile);
+                }
+
+                if (!IMM_FN(ImmRegisterClient)(&gSharedInfo, hImm32))
+                    return FALSE;
             }
-
             break;
         }
diff --git a/win32ss/user/user32/misc/imm.c b/win32ss/user/user32/misc/imm.c
index ef821aea8fa..8f267df2983 100644
--- a/win32ss/user/user32/misc/imm.c
+++ b/win32ss/user/user32/misc/imm.c
@@ -16,7 +16,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
 #define IMM_INIT_MAGIC 0x19650412
+/* Is != NULL when we have loaded the IMM ourselves */
 HINSTANCE ghImm32 = NULL;
+
 BOOL bImmInitializing = FALSE;
 /* define stub functions */
@@ -33,43 +35,50 @@ Imm32ApiTable gImmApiEntries = {
 #include "immtable.h"
 };
-HRESULT WINAPI GetImmFileName(PWSTR lpBuffer, UINT uSize)
+HRESULT
+GetImmFileName(_Out_ LPWSTR lpBuffer,
+               _In_ size_t cchBuffer)
 {
-  UINT length;
-  STRSAFE_LPWSTR Safe = lpBuffer;
-
-  length = GetSystemDirectoryW(lpBuffer, uSize);
-  if ( length && length < uSize )
-  {
-    StringCchCatW(Safe, uSize, L"\\");
-    return StringCchCatW(Safe, uSize, L"imm32.dll");
-  }
-  return StringCchCopyW(Safe, uSize, L"imm32.dll");
-}
+    UINT length = GetSystemDirectoryW(lpBuffer, cchBuffer);
+    if (length && length < cchBuffer)
+    {
+        StringCchCatW(lpBuffer, cchBuffer, L"\\");
+        return StringCchCatW(lpBuffer, cchBuffer, L"imm32.dll");
+    }
+    return StringCchCopyW(lpBuffer, cchBuffer, L"imm32.dll");
+}
 /*
  * @unimplemented
  */
-BOOL WINAPI IntInitializeImmEntryTable(VOID)
+static BOOL IntInitializeImmEntryTable(VOID)
 {
     WCHAR ImmFile[MAX_PATH];
     HMODULE imm32 = ghImm32;
-    GetImmFileName(ImmFile, sizeof(ImmFile));
-    TRACE("File %ws\n",ImmFile);
+    /* Check whether the IMM table has already been initialized */
+    if (IMM_FN(ImmWINNLSEnableIME) != IMMSTUB_ImmWINNLSEnableIME)
+        return TRUE;
+    GetImmFileName(ImmFile, _countof(ImmFile));
+    TRACE("File %S\n", ImmFile);
+
+    /* If IMM32 is already loaded, use it without increasing reference count. */
     if (imm32 == NULL)
-    {
-       imm32 = GetModuleHandleW(ImmFile);
-    }
+        imm32 = GetModuleHandleW(ImmFile);
+    /*
+     * Loading imm32.dll will call imm32!DllMain function.
+     * imm32!DllMain calls User32InitializeImmEntryTable.
+     * Thus, if imm32.dll was loaded, the table has been loaded.
+     */
     if (imm32 == NULL)
     {
         imm32 = ghImm32 = LoadLibraryW(ImmFile);
         if (imm32 == NULL)
         {
-           ERR("Did not load!\n");
-           return FALSE;
+            ERR("Did not load imm32.dll!\n");
+            return FALSE;
         }
         return TRUE;
     }
@@ -79,9 +88,11 @@ BOOL WINAPI IntInitializeImmEntryTable(VOID)
 #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
     do { \
         FN_##name proc = (FN_##name)GetProcAddress(imm32, #name); \
-        if (proc) { \
-            IMM_FN(name) = proc; \
+        if (!proc) { \
+            ERR("Could not load %s\n", #name); \
+            return FALSE; \
         } \
+        IMM_FN(name) = proc; \
     } while (0);
 #include "immtable.h"
@@ -90,8 +101,8 @@ BOOL WINAPI IntInitializeImmEntryTable(VOID)
 BOOL WINAPI InitializeImmEntryTable(VOID)
 {
-  bImmInitializing = TRUE;
-  return IntInitializeImmEntryTable();
+    bImmInitializing = TRUE;
+    return IntInitializeImmEntryTable();
 }
 BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
@@ -101,24 +112,25 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
     if (magic != IMM_INIT_MAGIC)
         return FALSE;
-    if (IMM_FN(ImmIsIME) != IMMSTUB_ImmIsIME)
+    /* Check whether the IMM table has already been initialized */
+    if (IMM_FN(ImmWINNLSEnableIME) != IMMSTUB_ImmWINNLSEnableIME)
         return TRUE;
     IntInitializeImmEntryTable();
     if (ghImm32 == NULL && !bImmInitializing)
     {
-       WCHAR ImmFile[MAX_PATH];
-       GetImmFileName(ImmFile, sizeof(ImmFile));
-       ghImm32 = LoadLibraryW(ImmFile);
-       if (ghImm32 == NULL)
-       {
-          ERR("Did not load! 2\n");
-          return FALSE;
-       }
+        WCHAR ImmFile[MAX_PATH];
+        GetImmFileName(ImmFile, _countof(ImmFile));
+        ghImm32 = LoadLibraryW(ImmFile);
+        if (ghImm32 == NULL)
+        {
+            ERR("Did not load imm32.dll!\n");
+            return FALSE;
+        }
     }
-    return TRUE;
+    return IMM_FN(ImmRegisterClient)(&gSharedInfo, ghImm32);
 }
 LRESULT WINAPI ImeWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL
unicode ) // ReactOS