[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:
RtlDeleteCriticalSection(&g_csImeDpi);
TRACE("imm32.dll is unloaded\n");
break;
}

View file

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

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

View file

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

View file

@ -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;
}

View file

@ -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