[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
This commit is contained in:
Katayama Hirofumi MZ 2021-08-23 16:25:21 +09:00 committed by GitHub
parent 84f7bee18f
commit 2ab858c125
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 46 deletions

View file

@ -5154,6 +5154,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
RtlDeleteCriticalSection(&g_csImeDpi); RtlDeleteCriticalSection(&g_csImeDpi);
TRACE("imm32.dll is unloaded\n");
break; break;
} }

View file

@ -1,5 +1,9 @@
@ stdcall CtfImmIsCiceroEnabled() @ stdcall CtfImmIsCiceroEnabled()
@ stdcall CtfImmIsTextFrameServiceDisabled() @ 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 -stub ImmActivateLayout(long)
@ stdcall ImmAssociateContext(ptr ptr) @ stdcall ImmAssociateContext(ptr ptr)
@ stdcall ImmAssociateContextEx(ptr ptr long) @ stdcall ImmAssociateContextEx(ptr ptr long)

View file

@ -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, 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(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, 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)

View file

@ -72,4 +72,8 @@ typedef struct _PATRECT
HBRUSH hBrush; HBRUSH hBrush;
} PATRECT, * PPATRECT; } PATRECT, * PPATRECT;
HRESULT
GetImmFileName(_Out_ LPWSTR lpBuffer,
_In_ size_t cchBuffer);
#endif /* _USER32_PCH_ */ #endif /* _USER32_PCH_ */

View file

@ -1,6 +1,6 @@
#include <user32.h> #include <user32.h>
#include <ndk/cmfuncs.h> #include <ndk/cmfuncs.h>
#include <strsafe.h>
#define MAX_USER_MODE_DRV_BUFFER 526 #define MAX_USER_MODE_DRV_BUFFER 526
@ -438,6 +438,7 @@ Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/)
gHandleTable = SharedPtrToUser(UserCon->siClient.aheList); gHandleTable = SharedPtrToUser(UserCon->siClient.aheList);
gHandleEntries = SharedPtrToUser(gHandleTable->handles); gHandleEntries = SharedPtrToUser(gHandleTable->handles);
gSharedInfo = UserCon->siClient; gSharedInfo = UserCon->siClient;
gSharedInfo.psi = gpsi;
} }
// FIXME: Yet another hack... This call should normally not be done here, but // FIXME: Yet another hack... This call should normally not be done here, but
@ -544,18 +545,19 @@ DllMain(
if (!gfServerProcess) if (!gfServerProcess)
{ {
#if WIN32K_ISNT_BROKEN HINSTANCE hImm32 = NULL;
InitializeImmEntryTable();
#else if (gpsi && (gpsi->dwSRVIFlags & SRVINFO_IMM32))
/* imm32 takes a refcount and prevents us from unloading */ {
LoadLibraryW(L"user32"); WCHAR szImmFile[MAX_PATH];
#endif InitializeImmEntryTable();
// GetImmFileName(szImmFile, _countof(szImmFile));
// Wine is stub and throws an exception so save this for real Imm32.dll testing!!!! hImm32 = GetModuleHandleW(szImmFile);
// }
//gImmApiEntries.pImmRegisterClient(&gSharedInfo, ghImm32);
if (!IMM_FN(ImmRegisterClient)(&gSharedInfo, hImm32))
return FALSE;
} }
break; break;
} }

View file

@ -16,7 +16,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
#define IMM_INIT_MAGIC 0x19650412 #define IMM_INIT_MAGIC 0x19650412
/* Is != NULL when we have loaded the IMM ourselves */
HINSTANCE ghImm32 = NULL; HINSTANCE ghImm32 = NULL;
BOOL bImmInitializing = FALSE; BOOL bImmInitializing = FALSE;
/* define stub functions */ /* define stub functions */
@ -33,43 +35,50 @@ Imm32ApiTable gImmApiEntries = {
#include "immtable.h" #include "immtable.h"
}; };
HRESULT WINAPI GetImmFileName(PWSTR lpBuffer, UINT uSize) HRESULT
GetImmFileName(_Out_ LPWSTR lpBuffer,
_In_ size_t cchBuffer)
{ {
UINT length; UINT length = GetSystemDirectoryW(lpBuffer, cchBuffer);
STRSAFE_LPWSTR Safe = lpBuffer; if (length && length < cchBuffer)
{
length = GetSystemDirectoryW(lpBuffer, uSize); StringCchCatW(lpBuffer, cchBuffer, L"\\");
if ( length && length < uSize ) return StringCchCatW(lpBuffer, cchBuffer, L"imm32.dll");
{ }
StringCchCatW(Safe, uSize, L"\\"); return StringCchCopyW(lpBuffer, cchBuffer, L"imm32.dll");
return StringCchCatW(Safe, uSize, L"imm32.dll"); }
}
return StringCchCopyW(Safe, uSize, L"imm32.dll");
}
/* /*
* @unimplemented * @unimplemented
*/ */
BOOL WINAPI IntInitializeImmEntryTable(VOID) static BOOL IntInitializeImmEntryTable(VOID)
{ {
WCHAR ImmFile[MAX_PATH]; WCHAR ImmFile[MAX_PATH];
HMODULE imm32 = ghImm32; HMODULE imm32 = ghImm32;
GetImmFileName(ImmFile, sizeof(ImmFile)); /* Check whether the IMM table has already been initialized */
TRACE("File %ws\n",ImmFile); 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) 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) if (imm32 == NULL)
{ {
imm32 = ghImm32 = LoadLibraryW(ImmFile); imm32 = ghImm32 = LoadLibraryW(ImmFile);
if (imm32 == NULL) if (imm32 == NULL)
{ {
ERR("Did not load!\n"); ERR("Did not load imm32.dll!\n");
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
@ -79,9 +88,11 @@ BOOL WINAPI IntInitializeImmEntryTable(VOID)
#define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \ #define DEFINE_IMM_ENTRY(type, name, params, retval, retkind) \
do { \ do { \
FN_##name proc = (FN_##name)GetProcAddress(imm32, #name); \ FN_##name proc = (FN_##name)GetProcAddress(imm32, #name); \
if (proc) { \ if (!proc) { \
IMM_FN(name) = proc; \ ERR("Could not load %s\n", #name); \
return FALSE; \
} \ } \
IMM_FN(name) = proc; \
} while (0); } while (0);
#include "immtable.h" #include "immtable.h"
@ -90,8 +101,8 @@ BOOL WINAPI IntInitializeImmEntryTable(VOID)
BOOL WINAPI InitializeImmEntryTable(VOID) BOOL WINAPI InitializeImmEntryTable(VOID)
{ {
bImmInitializing = TRUE; bImmInitializing = TRUE;
return IntInitializeImmEntryTable(); return IntInitializeImmEntryTable();
} }
BOOL WINAPI User32InitializeImmEntryTable(DWORD magic) BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
@ -101,24 +112,25 @@ BOOL WINAPI User32InitializeImmEntryTable(DWORD magic)
if (magic != IMM_INIT_MAGIC) if (magic != IMM_INIT_MAGIC)
return FALSE; 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; return TRUE;
IntInitializeImmEntryTable(); IntInitializeImmEntryTable();
if (ghImm32 == NULL && !bImmInitializing) if (ghImm32 == NULL && !bImmInitializing)
{ {
WCHAR ImmFile[MAX_PATH]; WCHAR ImmFile[MAX_PATH];
GetImmFileName(ImmFile, sizeof(ImmFile)); GetImmFileName(ImmFile, _countof(ImmFile));
ghImm32 = LoadLibraryW(ImmFile); ghImm32 = LoadLibraryW(ImmFile);
if (ghImm32 == NULL) if (ghImm32 == NULL)
{ {
ERR("Did not load! 2\n"); ERR("Did not load imm32.dll!\n");
return FALSE; 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 LRESULT WINAPI ImeWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode ) // ReactOS