Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891/* * PROJECT: ReactOS CTF * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) * PURPOSE: Text Framework Services * COPYRIGHT: Copyright 2023-2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> */
#include "precomp.h"
#include <sddl.h>#include <imm.h>#include <ctffunc.h>#include <shlwapi.h>
#include <cicmutex.h>#include <cicfmap.h>
#include "mlng.h"
#include <wine/debug.h>WINE_DEFAULT_DEBUG_CHANNEL(msctf);
BOOL gf_CRT_INIT = FALSE;BOOL g_fDllProcessDetached = FALSE;CRITICAL_SECTION g_cs;CRITICAL_SECTION g_csInDllMain;CRITICAL_SECTION g_csDelayLoad;HINSTANCE g_hInst = NULL;BOOL g_bOnWow64 = FALSE;UINT g_uACP = CP_ACP; // Active Code PageDWORD g_dwOSInfo = 0; // See cicGetOSInfoHKL g_hklDefault = NULL;DWORD g_dwTLSIndex = (DWORD)-1;BOOL gfSharedMemory = FALSE;LONG g_cRefDll = -1;BOOL g_fCUAS = FALSE;TCHAR g_szCUASImeFile[16] = { 0 };DWORD g_dwAppCompatibility = 0;BOOL g_fNoITextStoreAnchor = TRUE;
// MessagesUINT g_msgPrivate = 0;UINT g_msgSetFocus = 0;UINT g_msgThreadTerminate = 0;UINT g_msgThreadItemChange = 0;UINT g_msgLBarModal = 0;UINT g_msgRpcSendReceive = 0;UINT g_msgThreadMarshal = 0;UINT g_msgCheckThreadInputIdel = 0;UINT g_msgStubCleanUp = 0;UINT g_msgShowFloating = 0;UINT g_msgLBUpdate = 0;UINT g_msgNuiMgrDirtyUpdate = 0;
// Unique namesBOOL g_fUserSidString = FALSE;TCHAR g_szUserSidString[MAX_PATH] = { 0 };TCHAR g_szUserUnique[MAX_PATH] = { 0 };TCHAR g_szAsmListCache[MAX_PATH] = { 0 };TCHAR g_szTimListCache[MAX_PATH] = { 0 };TCHAR g_szLayoutsCache[MAX_PATH] = { 0 };
// MutexesCicMutex g_mutexLBES;CicMutex g_mutexCompart;CicMutex g_mutexAsm;CicMutex g_mutexLayouts;CicMutex g_mutexTMD;
// File mappingCicFileMappingStatic g_SharedMemory;
// Hot-KeysUINT g_uLangHotKeyModifiers = 0;UINT g_uLangHotKeyVKey = 0;UINT g_uLangHotKeyVKey2 = 0;UINT g_uKeyTipHotKeyModifiers = 0;UINT g_uKeyTipHotKeyVKey = 0;UINT g_uKeyTipHotKeyVKey2 = 0;
// Handle pure virtual function call errorsextern "C" void __cxa_pure_virtual(void){ ERR("__cxa_pure_virtual\n"); DebugBreak();}
/** * @implemented */LPTSTR GetUserSIDString(void){ HANDLE hToken = NULL; OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); if (!hToken) return NULL;
DWORD dwLengthNeeded = 0; GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLengthNeeded); PTOKEN_USER pTokenUser = (PTOKEN_USER)cicMemAllocClear(dwLengthNeeded); if (!pTokenUser) { CloseHandle(hToken); return NULL; }
LPTSTR StringSid = NULL; if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwLengthNeeded, &dwLengthNeeded) || !ConvertSidToStringSid(pTokenUser->User.Sid, &StringSid)) { if (StringSid) { LocalFree(StringSid); StringSid = NULL; } }
cicMemFree(pTokenUser); CloseHandle(hToken); return StringSid;}
/** * @implemented */BOOL InitUserSidString(void){ if (g_fUserSidString) return TRUE;
LPTSTR pszUserSID = GetUserSIDString(); if (!pszUserSID) return FALSE;
StringCchCopy(g_szUserSidString, _countof(g_szUserSidString), pszUserSID); g_fUserSidString = TRUE; LocalFree(pszUserSID); return TRUE;}
/** * @implemented */BOOL InitUniqueString(void){ g_szUserUnique[0] = TEXT('\0');
DWORD dwThreadId = GetCurrentThreadId(); HDESK hDesk = GetThreadDesktop(dwThreadId);
DWORD nLengthNeeded; TCHAR szName[MAX_PATH]; if (hDesk && GetUserObjectInformation(hDesk, UOI_NAME, szName, _countof(szName), &nLengthNeeded)) StringCchCat(g_szUserUnique, _countof(g_szUserUnique), szName);
if (!InitUserSidString()) return FALSE;
StringCchCat(g_szUserUnique, _countof(g_szUserUnique), g_szUserSidString); return TRUE;}
voidGetDesktopUniqueName( _In_ LPCTSTR pszName, _Out_ LPTSTR pszBuff, _In_ UINT cchBuff){ StringCchCopy(pszBuff, cchBuff, pszName); StringCchCat(pszBuff, cchBuff, g_szUserUnique);}
BOOL StringFromGUID2A(REFGUID rguid, LPSTR pszGUID, INT cchGUID){ pszGUID[0] = ANSI_NULL;
WCHAR szWide[40]; szWide[0] = UNICODE_NULL; BOOL ret = StringFromGUID2(rguid, szWide, _countof(szWide)); ::WideCharToMultiByte(CP_ACP, 0, szWide, -1, pszGUID, cchGUID, NULL, NULL); return ret;}
#ifdef UNICODE #define StringFromGUID2T StringFromGUID2 #define debugstr_t debugstr_w#else #define StringFromGUID2T StringFromGUID2A #define debugstr_t debugstr_a#endif
BOOL FullPathExec(LPCTSTR pszExeFile, LPCTSTR pszCmdLine, UINT nCmdShow, BOOL bSysWinDir){ STARTUPINFO si; PROCESS_INFORMATION pi; CicSystemModulePath ModPath; TCHAR szCommandLine[2 * MAX_PATH];
ModPath.Init(pszExeFile, bSysWinDir); if (!ModPath.m_cchPath) { ERR("%s\n", debugstr_t(pszExeFile)); return FALSE; }
StringCchCopy(szCommandLine, _countof(szCommandLine), pszCmdLine);
ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.wShowWindow = nCmdShow; si.dwFlags = STARTF_USESHOWWINDOW; if (!CreateProcess(ModPath.m_szPath, szCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) { ERR("%s, %s\n", debugstr_t(ModPath.m_szPath), debugstr_t(szCommandLine)); return FALSE; }
CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return TRUE;}
static inline BOOLRunCPLSetting(LPCTSTR pszCmdLine){ if (!pszCmdLine) return FALSE;
return FullPathExec(TEXT("rundll32.exe"), pszCmdLine, SW_SHOWMINNOACTIVE, FALSE);}
/*********************************************************************** * TF_GetThreadFlags (MSCTF.@) * * @unimplemented */EXTERN_C BOOL WINAPITF_GetThreadFlags( _In_ DWORD dwThreadId, _Out_ LPDWORD pdwFlags1, _Out_ LPDWORD pdwFlags2, _Out_ LPDWORD pdwFlags3){ FIXME("(%lu, %p, %p, %p)\n", dwThreadId, pdwFlags1, pdwFlags2, pdwFlags3); *pdwFlags1 = *pdwFlags2 = *pdwFlags3 = 0; return FALSE;}
/*********************************************************************** * TF_CreateCategoryMgr (MSCTF.@) * * @implemented */EXTERN_C HRESULT WINAPITF_CreateCategoryMgr(_Out_ ITfCategoryMgr **ppcat){ TRACE("(%p)\n", ppcat); return CategoryMgr_Constructor(NULL, (IUnknown **)ppcat);}
/*********************************************************************** * TF_CreateCicLoadMutex (MSCTF.@) * * @unimplemented */EXTERN_C HANDLE WINAPITF_CreateCicLoadMutex(_Out_ LPBOOL pfWinLogon){ FIXME("(%p)\n", pfWinLogon); if (!pfWinLogon) return NULL; *pfWinLogon = FALSE; return NULL;}
/*********************************************************************** * TF_CreateDisplayAttributeMgr (MSCTF.@) * * @implemented */EXTERN_C HRESULT WINAPITF_CreateDisplayAttributeMgr(_Out_ ITfDisplayAttributeMgr **ppdam){ TRACE("(%p)\n", ppdam); return DisplayAttributeMgr_Constructor(NULL, (IUnknown **)ppdam);}
/*********************************************************************** * TF_DllDetachInOther (MSCTF.@) * * @unimplemented */EXTERN_C BOOL WINAPITF_DllDetachInOther(VOID){ FIXME("()\n"); return TRUE;}
/*********************************************************************** * TF_GetGlobalCompartment (MSCTF.@) * * @unimplemented */EXTERN_C HRESULT WINAPITF_GetGlobalCompartment(_Out_ ITfCompartmentMgr **ppCompMgr){ FIXME("(%p)\n", ppCompMgr); *ppCompMgr = NULL; return E_NOTIMPL;}
/*********************************************************************** * TF_GetLangIcon (MSCTF.@) * * @unimplemented */EXTERN_C HICON WINAPITF_GetLangIcon(_In_ LANGID LangID, _Out_ PWSTR pszText, _In_ INT cchText){ FIXME("(0x%X, %p, %d)\n", LangID, pszText, cchText); return NULL;}
/*********************************************************************** * TF_IsFullScreenWindowAcitvated (MSCTF.@) * * Yes, this function name is misspelled by MS. * @unimplemented */EXTERN_C BOOL WINAPITF_IsFullScreenWindowAcitvated(VOID){ FIXME("()\n"); return FALSE;}
/*********************************************************************** * TF_GetInputScope (MSCTF.@) * * @unimplemented */EXTERN_C HRESULT WINAPITF_GetInputScope(_In_opt_ HWND hWnd, _Out_ ITfInputScope **ppInputScope){ FIXME("(%p, %p)\n", hWnd, ppInputScope); *ppInputScope = NULL; return E_NOTIMPL;}
/*********************************************************************** * SetInputScopeXML (MSCTF.@) * * @unimplemented */EXTERN_C HRESULT WINAPISetInputScopeXML(_In_opt_ HWND hwnd, _In_opt_ PCWSTR pszXML){ FIXME("(%p, %p)\n", hwnd, pszXML); return E_NOTIMPL;}
/*********************************************************************** * TF_CUASAppFix (MSCTF.@) * * @implemented */EXTERN_C HRESULT WINAPITF_CUASAppFix(_In_ LPCSTR pszName){ if (!pszName || lstrcmpiA(pszName, "DelayFirstActivateKeyboardLayout") != 0) return E_INVALIDARG; g_dwAppCompatibility |= CTF_COMPAT_DELAY_FIRST_ACTIVATE; return S_OK;}
/*********************************************************************** * TF_CheckThreadInputIdle (MSCTF.@) * * @unimplemented */EXTERN_C LONG WINAPITF_CheckThreadInputIdle(_In_ DWORD dwThreadId, _In_ DWORD dwMilliseconds){ FIXME("(%lu, %lu)\n", dwThreadId, dwMilliseconds); return -1;}
/*********************************************************************** * TF_ClearLangBarAddIns (MSCTF.@) * * @unimplemented */EXTERN_C HRESULT WINAPITF_ClearLangBarAddIns(_In_ REFGUID guid){ FIXME("(%p)\n", guid); return E_NOTIMPL;}
/*********************************************************************** * TF_InvalidAssemblyListCache (MSCTF.@) * * @unimplemented */EXTERN_C HRESULT WINAPITF_InvalidAssemblyListCache(VOID){ FIXME("()\n"); return E_NOTIMPL;}
/*********************************************************************** * TF_IsInMarshaling (MSCTF.@) * * @unimplemented */EXTERN_C BOOL WINAPITF_IsInMarshaling(_In_ DWORD dwThreadId){ FIXME("(%lu)\n", dwThreadId); return FALSE;}
/*********************************************************************** * TF_PostAllThreadMsg (MSCTF.@) * * @unimplemented */EXTERN_C HRESULT WINAPITF_PostAllThreadMsg(_In_opt_ WPARAM wParam, _In_ DWORD dwFlags){ FIXME("(%p, 0x%X)\n", wParam, dwFlags); return E_NOTIMPL;}
/*********************************************************************** * TF_InitSystem (MSCTF.@) * * @unimplemented */EXTERN_C BOOL WINAPITF_InitSystem(VOID){ FIXME("()\n"); return FALSE;}
/*********************************************************************** * TF_UninitSystem (MSCTF.@) * * @unimplemented */EXTERN_C BOOL WINAPITF_UninitSystem(VOID){ FIXME("()\n"); return FALSE;}
/*********************************************************************** * TF_RegisterLangBarAddIn (MSCTF.@) * * @implemented */EXTERN_C HRESULT WINAPITF_RegisterLangBarAddIn( _In_ REFGUID rguid, _In_ LPCWSTR pszFilePath, _In_ DWORD dwFlags){ TRACE("(%s, %s, 0x%lX)\n", debugstr_guid(&rguid), debugstr_w(pszFilePath), dwFlags);
if (!pszFilePath || rguid == GUID_NULL) { ERR("E_INVALIDARG\n"); return E_INVALIDARG; }
TCHAR szBuff[MAX_PATH], szGUID[40]; StringCchCopy(szBuff, _countof(szBuff), TEXT("SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\")); StringFromGUID2T(rguid, szGUID, _countof(szGUID)); StringCchCat(szBuff, _countof(szBuff), szGUID);
CicRegKey regKey; HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); LSTATUS error = regKey.Create(hBaseKey, szBuff); if (error == ERROR_SUCCESS) { error = regKey.SetSzW(L"FilePath", pszFilePath); if (error == ERROR_SUCCESS) error = regKey.SetDword(TEXT("Enable"), !!(dwFlags & 4)); }
return ((error == ERROR_SUCCESS) ? S_OK : E_FAIL);}
/*********************************************************************** * TF_UnregisterLangBarAddIn (MSCTF.@) * * @implemented */EXTERN_C HRESULT WINAPITF_UnregisterLangBarAddIn( _In_ REFGUID rguid, _In_ DWORD dwFlags){ TRACE("(%s, 0x%lX)\n", debugstr_guid(&rguid), dwFlags);
if (rguid == GUID_NULL) { ERR("E_INVALIDARG\n"); return E_INVALIDARG; }
TCHAR szSubKey[MAX_PATH]; StringCchCopy(szSubKey, _countof(szSubKey), TEXT("SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\"));
CicRegKey regKey; HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); LSTATUS error = regKey.Open(hBaseKey, szSubKey, KEY_ALL_ACCESS); HRESULT hr = E_FAIL; if (error == ERROR_SUCCESS) { TCHAR szGUID[40]; StringFromGUID2T(rguid, szGUID, _countof(szGUID)); regKey.RecurseDeleteKey(szGUID); hr = S_OK; }
return hr;}
/*********************************************************************** * TF_RunInputCPL (MSCTF.@) * * @implemented */EXTERN_C HRESULT WINAPITF_RunInputCPL(VOID){ CicSystemModulePath ModPath; TCHAR szCmdLine[2 * MAX_PATH];
TRACE("()\n");
// NOTE: We don't support Win95/98/Me if (g_dwOSInfo & CIC_OSINFO_XPPLUS) ModPath.Init(TEXT("input.dll"), FALSE); else ModPath.Init(TEXT("input.cpl"), FALSE);
if (!ModPath.m_cchPath) return E_FAIL;
StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("rundll32.exe shell32.dll,Control_RunDLL %s"), ModPath.m_szPath); if (!RunCPLSetting(szCmdLine)) return E_FAIL;
return S_OK;}
/*********************************************************************** * TF_IsCtfmonRunning (MSCTF.@) * * @implemented */EXTERN_C BOOL WINAPITF_IsCtfmonRunning(VOID){ TCHAR szName[MAX_PATH]; GetDesktopUniqueName(TEXT("CtfmonInstMutex"), szName, _countof(szName));
HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, szName); if (!hMutex) return FALSE;
::CloseHandle(hMutex); return TRUE;}
/** * @implemented */BOOL InitLangChangeHotKey(VOID){ CicRegKey regKey; TCHAR szLanguage[2], szLayout[2]; LSTATUS error;
szLanguage[0] = szLayout[0] = TEXT('3'); szLanguage[1] = szLayout[1] = TEXT('\0');
error = regKey.Open(HKEY_CURRENT_USER, TEXT("Keyboard Layout\\Toggle")); if (error == ERROR_SUCCESS) { error = regKey.QuerySz(TEXT("Language Hotkey"), szLanguage, _countof(szLanguage)); if (error != ERROR_SUCCESS) { if (g_dwOSInfo & CIC_OSINFO_NT) { error = regKey.QuerySz(TEXT("Hotkey"), szLanguage, _countof(szLanguage)); if (error != ERROR_SUCCESS) szLanguage[0] = TEXT('1'); } else { error = regKey.QuerySz(NULL, szLanguage, _countof(szLanguage)); if (error != ERROR_SUCCESS) szLanguage[0] = TEXT('1'); }
if (PRIMARYLANGID(GetSystemDefaultLCID()) == LANG_CHINESE) szLanguage[0] = TEXT('1'); }
error = regKey.QuerySz(TEXT("Layout Hotkey"), szLayout, _countof(szLayout)); if (error != ERROR_SUCCESS) { szLayout[0] = TEXT('1'); if (szLanguage[0] != TEXT('2')) szLayout[0] = TEXT('2'); if (GetSystemMetrics(SM_MIDEASTENABLED)) szLayout[0] = TEXT('3'); }
szLanguage[1] = TEXT('\0'); szLayout[1] = TEXT('\0'); }
if (szLanguage[0] == szLayout[0]) { if (szLanguage[0] == TEXT('1')) szLayout[0] = TEXT('2'); else if (szLanguage[0] == TEXT('2')) szLayout[0] = TEXT('1'); else szLayout[0] = TEXT('3'); }
::EnterCriticalSection(&g_csInDllMain);
switch (szLanguage[0]) { case TEXT('2'): g_uLangHotKeyModifiers = MOD_SHIFT | MOD_CONTROL; g_uLangHotKeyVKey2 = VK_CONTROL; g_uLangHotKeyVKey = VK_SHIFT; break;
case TEXT('3'): g_uLangHotKeyVKey = 0; g_uLangHotKeyModifiers = 0; g_uLangHotKeyVKey2 = 0; break;
case TEXT('4'): g_uLangHotKeyVKey = VK_NUMPAD0; g_uLangHotKeyModifiers = 0; g_uLangHotKeyVKey2 = 0; break;
case TEXT('1'): default: g_uLangHotKeyModifiers = MOD_SHIFT | MOD_ALT; g_uLangHotKeyVKey2 = VK_MENU; g_uLangHotKeyVKey = VK_SHIFT; break; }
switch (szLayout[0]) { case TEXT('2'): g_uKeyTipHotKeyModifiers = MOD_SHIFT | MOD_CONTROL; g_uKeyTipHotKeyVKey = VK_SHIFT; g_uKeyTipHotKeyVKey2 = VK_CONTROL; break;
case TEXT('3'): g_uKeyTipHotKeyModifiers = 0; g_uKeyTipHotKeyVKey = 0; g_uKeyTipHotKeyVKey2 = 0; break;
case TEXT('4'): g_uKeyTipHotKeyModifiers = 0; g_uKeyTipHotKeyVKey = VK_OEM_3; g_uKeyTipHotKeyVKey2 = 0; break;
case TEXT('1'): default: g_uKeyTipHotKeyModifiers = 0x40 | MOD_SHIFT; g_uKeyTipHotKeyVKey = VK_SHIFT; g_uKeyTipHotKeyVKey2 = VK_MENU; break; }
::LeaveCriticalSection(&g_csInDllMain);
TRACE("HotKey: %c, %c\n", szLanguage[0], szLayout[0]); return TRUE;}
/** * @implemented */VOID CheckAnchorStores(VOID){ HKEY hKey; LSTATUS error; error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\CTF"), 0, KEY_READ, &hKey); if (error != ERROR_SUCCESS) return;
DWORD dwData = 0, cbData = sizeof(dwData); error = RegQueryValueEx(hKey, TEXT("EnableAnchorContext"), NULL, NULL, (PBYTE)&dwData, &cbData); if (error == ERROR_SUCCESS && cbData == sizeof(DWORD) && dwData == 1) g_fNoITextStoreAnchor = FALSE;
RegCloseKey(hKey);}
VOID InitCUASFlag(VOID){ CicRegKey regKey1; LSTATUS error;
error = regKey1.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\CTF\\SystemShared\\")); if (error == ERROR_SUCCESS) { DWORD dwValue; error = regKey1.QueryDword(TEXT("CUAS"), &dwValue); if (error == ERROR_SUCCESS) g_fCUAS = !!dwValue; }
g_szCUASImeFile[0] = TEXT('\0');
if (!g_fCUAS) return;
TCHAR szImeFile[16]; CicRegKey regKey2; error = regKey2.Open(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM")); if (error == ERROR_SUCCESS) { error = regKey2.QuerySz(TEXT("IME File"), szImeFile, _countof(szImeFile)); if (error == ERROR_SUCCESS) { g_szCUASImeFile[_countof(g_szCUASImeFile) - 1] = TEXT('\0'); // Avoid buffer overrun StringCchCopy(g_szCUASImeFile, _countof(g_szCUASImeFile), szImeFile); } }}
EXTERN_C VOID TFUninitLib(VOID){ // Do nothing}
/// @unimplementedBOOL ProcessAttach(HINSTANCE hinstDLL){ gf_CRT_INIT = TRUE;
::InitializeCriticalSectionAndSpinCount(&g_cs, 0); ::InitializeCriticalSectionAndSpinCount(&g_csInDllMain, 0); ::InitializeCriticalSectionAndSpinCount(&g_csDelayLoad, 0);
g_bOnWow64 = cicIsWow64(); g_hInst = hinstDLL; g_hklDefault = ::GetKeyboardLayout(0); g_dwTLSIndex = ::TlsAlloc(); if (g_dwTLSIndex == (DWORD)-1) return FALSE;
g_msgPrivate = ::RegisterWindowMessageA("MSUIM.Msg.Private"); g_msgSetFocus = ::RegisterWindowMessageA("MSUIM.Msg.SetFocus"); g_msgThreadTerminate = ::RegisterWindowMessageA("MSUIM.Msg.ThreadTerminate"); g_msgThreadItemChange = ::RegisterWindowMessageA("MSUIM.Msg.ThreadItemChange"); g_msgLBarModal = ::RegisterWindowMessageA("MSUIM.Msg.LangBarModal"); g_msgRpcSendReceive = ::RegisterWindowMessageA("MSUIM.Msg.RpcSendReceive"); g_msgThreadMarshal = ::RegisterWindowMessageA("MSUIM.Msg.ThreadMarshal"); g_msgCheckThreadInputIdel = ::RegisterWindowMessageA("MSUIM.Msg.CheckThreadInputIdel"); g_msgStubCleanUp = ::RegisterWindowMessageA("MSUIM.Msg.StubCleanUp"); g_msgShowFloating = ::RegisterWindowMessageA("MSUIM.Msg.ShowFloating"); g_msgLBUpdate = ::RegisterWindowMessageA("MSUIM.Msg.LBUpdate"); g_msgNuiMgrDirtyUpdate = ::RegisterWindowMessageA("MSUIM.Msg.MuiMgrDirtyUpdate"); if (!g_msgPrivate || !g_msgSetFocus || !g_msgThreadTerminate || !g_msgThreadItemChange || !g_msgLBarModal || !g_msgRpcSendReceive || !g_msgThreadMarshal || !g_msgCheckThreadInputIdel || !g_msgStubCleanUp || !g_msgShowFloating || !g_msgLBUpdate || !g_msgNuiMgrDirtyUpdate) { return FALSE; }
cicGetOSInfo(&g_uACP, &g_dwOSInfo); TRACE("cicGetOSInfo: %u, 0x%lX\n", g_uACP, g_dwOSInfo);
InitUniqueString();
//FIXME
gfSharedMemory = TRUE;
//FIXME
InitCUASFlag();
//FIXME
GetDesktopUniqueName(TEXT("CTF.AsmListCache.FMP"), g_szAsmListCache, _countof(g_szAsmListCache)); GetDesktopUniqueName(TEXT("CTF.TimListCache.FMP"), g_szTimListCache, _countof(g_szTimListCache)); GetDesktopUniqueName(TEXT("CTF.LayoutsCache.FMP"), g_szLayoutsCache, _countof(g_szLayoutsCache));
//FIXME
InitLangChangeHotKey();
//FIXME
CheckAnchorStores();
return TRUE;}
/// @unimplementedVOID ProcessDetach(HINSTANCE hinstDLL){ if (!gf_CRT_INIT) { g_fDllProcessDetached = TRUE; return; }
if (gfSharedMemory) { if (g_cRefDll != -1 ) TFUninitLib(); //FIXME }
UninitINAT();
//FIXME
//TF_UninitThreadSystem();
//FIXME
if (g_dwTLSIndex != (DWORD)-1) { ::TlsFree(g_dwTLSIndex); g_dwTLSIndex = (DWORD)-1; }
//FIXME
if (gfSharedMemory) { g_mutexLBES.Uninit(); g_mutexCompart.Uninit(); g_mutexAsm.Uninit(); //FIXME g_mutexLayouts.Uninit(); g_mutexTMD.Uninit(); //FIXME g_SharedMemory.Close(); }
g_SharedMemory.Finalize();
::DeleteCriticalSection(&g_cs); ::DeleteCriticalSection(&g_csInDllMain); ::DeleteCriticalSection(&g_csDelayLoad);
g_fDllProcessDetached = TRUE;}