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