Reactos
at master 890 lines 23 kB view raw
1/* 2 * PROJECT: ReactOS CTF 3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) 4 * PURPOSE: Text Framework Services 5 * COPYRIGHT: Copyright 2023-2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8#include "precomp.h" 9 10#include <sddl.h> 11#include <imm.h> 12#include <ctffunc.h> 13#include <shlwapi.h> 14 15#include <cicmutex.h> 16#include <cicfmap.h> 17 18#include "mlng.h" 19 20#include <wine/debug.h> 21WINE_DEFAULT_DEBUG_CHANNEL(msctf); 22 23BOOL gf_CRT_INIT = FALSE; 24BOOL g_fDllProcessDetached = FALSE; 25CRITICAL_SECTION g_cs; 26CRITICAL_SECTION g_csInDllMain; 27CRITICAL_SECTION g_csDelayLoad; 28HINSTANCE g_hInst = NULL; 29BOOL g_bOnWow64 = FALSE; 30UINT g_uACP = CP_ACP; // Active Code Page 31DWORD g_dwOSInfo = 0; // See cicGetOSInfo 32HKL g_hklDefault = NULL; 33DWORD g_dwTLSIndex = (DWORD)-1; 34BOOL gfSharedMemory = FALSE; 35LONG g_cRefDll = -1; 36BOOL g_fCUAS = FALSE; 37TCHAR g_szCUASImeFile[16] = { 0 }; 38DWORD g_dwAppCompatibility = 0; 39BOOL g_fNoITextStoreAnchor = TRUE; 40 41// Messages 42UINT g_msgPrivate = 0; 43UINT g_msgSetFocus = 0; 44UINT g_msgThreadTerminate = 0; 45UINT g_msgThreadItemChange = 0; 46UINT g_msgLBarModal = 0; 47UINT g_msgRpcSendReceive = 0; 48UINT g_msgThreadMarshal = 0; 49UINT g_msgCheckThreadInputIdel = 0; 50UINT g_msgStubCleanUp = 0; 51UINT g_msgShowFloating = 0; 52UINT g_msgLBUpdate = 0; 53UINT g_msgNuiMgrDirtyUpdate = 0; 54 55// Unique names 56BOOL g_fUserSidString = FALSE; 57TCHAR g_szUserSidString[MAX_PATH] = { 0 }; 58TCHAR g_szUserUnique[MAX_PATH] = { 0 }; 59TCHAR g_szAsmListCache[MAX_PATH] = { 0 }; 60TCHAR g_szTimListCache[MAX_PATH] = { 0 }; 61TCHAR g_szLayoutsCache[MAX_PATH] = { 0 }; 62 63// Mutexes 64CicMutex g_mutexLBES; 65CicMutex g_mutexCompart; 66CicMutex g_mutexAsm; 67CicMutex g_mutexLayouts; 68CicMutex g_mutexTMD; 69 70// File mapping 71CicFileMappingStatic g_SharedMemory; 72 73// Hot-Keys 74UINT g_uLangHotKeyModifiers = 0; 75UINT g_uLangHotKeyVKey = 0; 76UINT g_uLangHotKeyVKey2 = 0; 77UINT g_uKeyTipHotKeyModifiers = 0; 78UINT g_uKeyTipHotKeyVKey = 0; 79UINT g_uKeyTipHotKeyVKey2 = 0; 80 81// Handle pure virtual function call errors 82extern "C" void __cxa_pure_virtual(void) 83{ 84 ERR("__cxa_pure_virtual\n"); 85 DebugBreak(); 86} 87 88/** 89 * @implemented 90 */ 91LPTSTR GetUserSIDString(void) 92{ 93 HANDLE hToken = NULL; 94 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken); 95 if (!hToken) 96 return NULL; 97 98 DWORD dwLengthNeeded = 0; 99 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLengthNeeded); 100 PTOKEN_USER pTokenUser = (PTOKEN_USER)cicMemAllocClear(dwLengthNeeded); 101 if (!pTokenUser) 102 { 103 CloseHandle(hToken); 104 return NULL; 105 } 106 107 LPTSTR StringSid = NULL; 108 if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwLengthNeeded, &dwLengthNeeded) || 109 !ConvertSidToStringSid(pTokenUser->User.Sid, &StringSid)) 110 { 111 if (StringSid) 112 { 113 LocalFree(StringSid); 114 StringSid = NULL; 115 } 116 } 117 118 cicMemFree(pTokenUser); 119 CloseHandle(hToken); 120 return StringSid; 121} 122 123/** 124 * @implemented 125 */ 126BOOL InitUserSidString(void) 127{ 128 if (g_fUserSidString) 129 return TRUE; 130 131 LPTSTR pszUserSID = GetUserSIDString(); 132 if (!pszUserSID) 133 return FALSE; 134 135 StringCchCopy(g_szUserSidString, _countof(g_szUserSidString), pszUserSID); 136 g_fUserSidString = TRUE; 137 LocalFree(pszUserSID); 138 return TRUE; 139} 140 141/** 142 * @implemented 143 */ 144BOOL InitUniqueString(void) 145{ 146 g_szUserUnique[0] = TEXT('\0'); 147 148 DWORD dwThreadId = GetCurrentThreadId(); 149 HDESK hDesk = GetThreadDesktop(dwThreadId); 150 151 DWORD nLengthNeeded; 152 TCHAR szName[MAX_PATH]; 153 if (hDesk && GetUserObjectInformation(hDesk, UOI_NAME, szName, _countof(szName), &nLengthNeeded)) 154 StringCchCat(g_szUserUnique, _countof(g_szUserUnique), szName); 155 156 if (!InitUserSidString()) 157 return FALSE; 158 159 StringCchCat(g_szUserUnique, _countof(g_szUserUnique), g_szUserSidString); 160 return TRUE; 161} 162 163void 164GetDesktopUniqueName( 165 _In_ LPCTSTR pszName, 166 _Out_ LPTSTR pszBuff, 167 _In_ UINT cchBuff) 168{ 169 StringCchCopy(pszBuff, cchBuff, pszName); 170 StringCchCat(pszBuff, cchBuff, g_szUserUnique); 171} 172 173BOOL StringFromGUID2A(REFGUID rguid, LPSTR pszGUID, INT cchGUID) 174{ 175 pszGUID[0] = ANSI_NULL; 176 177 WCHAR szWide[40]; 178 szWide[0] = UNICODE_NULL; 179 BOOL ret = StringFromGUID2(rguid, szWide, _countof(szWide)); 180 ::WideCharToMultiByte(CP_ACP, 0, szWide, -1, pszGUID, cchGUID, NULL, NULL); 181 return ret; 182} 183 184#ifdef UNICODE 185 #define StringFromGUID2T StringFromGUID2 186 #define debugstr_t debugstr_w 187#else 188 #define StringFromGUID2T StringFromGUID2A 189 #define debugstr_t debugstr_a 190#endif 191 192BOOL FullPathExec(LPCTSTR pszExeFile, LPCTSTR pszCmdLine, UINT nCmdShow, BOOL bSysWinDir) 193{ 194 STARTUPINFO si; 195 PROCESS_INFORMATION pi; 196 CicSystemModulePath ModPath; 197 TCHAR szCommandLine[2 * MAX_PATH]; 198 199 ModPath.Init(pszExeFile, bSysWinDir); 200 if (!ModPath.m_cchPath) 201 { 202 ERR("%s\n", debugstr_t(pszExeFile)); 203 return FALSE; 204 } 205 206 StringCchCopy(szCommandLine, _countof(szCommandLine), pszCmdLine); 207 208 ZeroMemory(&si, sizeof(si)); 209 si.cb = sizeof(si); 210 si.wShowWindow = nCmdShow; 211 si.dwFlags = STARTF_USESHOWWINDOW; 212 if (!CreateProcess(ModPath.m_szPath, szCommandLine, NULL, NULL, FALSE, 213 NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)) 214 { 215 ERR("%s, %s\n", debugstr_t(ModPath.m_szPath), debugstr_t(szCommandLine)); 216 return FALSE; 217 } 218 219 CloseHandle(pi.hProcess); 220 CloseHandle(pi.hThread); 221 return TRUE; 222} 223 224static inline BOOL 225RunCPLSetting(LPCTSTR pszCmdLine) 226{ 227 if (!pszCmdLine) 228 return FALSE; 229 230 return FullPathExec(TEXT("rundll32.exe"), pszCmdLine, SW_SHOWMINNOACTIVE, FALSE); 231} 232 233/*********************************************************************** 234 * TF_GetThreadFlags (MSCTF.@) 235 * 236 * @unimplemented 237 */ 238EXTERN_C BOOL WINAPI 239TF_GetThreadFlags( 240 _In_ DWORD dwThreadId, 241 _Out_ LPDWORD pdwFlags1, 242 _Out_ LPDWORD pdwFlags2, 243 _Out_ LPDWORD pdwFlags3) 244{ 245 FIXME("(%lu, %p, %p, %p)\n", dwThreadId, pdwFlags1, pdwFlags2, pdwFlags3); 246 *pdwFlags1 = *pdwFlags2 = *pdwFlags3 = 0; 247 return FALSE; 248} 249 250/*********************************************************************** 251 * TF_CreateCategoryMgr (MSCTF.@) 252 * 253 * @implemented 254 */ 255EXTERN_C HRESULT WINAPI 256TF_CreateCategoryMgr(_Out_ ITfCategoryMgr **ppcat) 257{ 258 TRACE("(%p)\n", ppcat); 259 return CategoryMgr_Constructor(NULL, (IUnknown **)ppcat); 260} 261 262/*********************************************************************** 263 * TF_CreateCicLoadMutex (MSCTF.@) 264 * 265 * @unimplemented 266 */ 267EXTERN_C HANDLE WINAPI 268TF_CreateCicLoadMutex(_Out_ LPBOOL pfWinLogon) 269{ 270 FIXME("(%p)\n", pfWinLogon); 271 if (!pfWinLogon) 272 return NULL; 273 *pfWinLogon = FALSE; 274 return NULL; 275} 276 277/*********************************************************************** 278 * TF_CreateDisplayAttributeMgr (MSCTF.@) 279 * 280 * @implemented 281 */ 282EXTERN_C HRESULT WINAPI 283TF_CreateDisplayAttributeMgr(_Out_ ITfDisplayAttributeMgr **ppdam) 284{ 285 TRACE("(%p)\n", ppdam); 286 return DisplayAttributeMgr_Constructor(NULL, (IUnknown **)ppdam); 287} 288 289/*********************************************************************** 290 * TF_DllDetachInOther (MSCTF.@) 291 * 292 * @unimplemented 293 */ 294EXTERN_C BOOL WINAPI 295TF_DllDetachInOther(VOID) 296{ 297 FIXME("()\n"); 298 return TRUE; 299} 300 301/*********************************************************************** 302 * TF_GetGlobalCompartment (MSCTF.@) 303 * 304 * @unimplemented 305 */ 306EXTERN_C HRESULT WINAPI 307TF_GetGlobalCompartment(_Out_ ITfCompartmentMgr **ppCompMgr) 308{ 309 FIXME("(%p)\n", ppCompMgr); 310 *ppCompMgr = NULL; 311 return E_NOTIMPL; 312} 313 314/*********************************************************************** 315 * TF_GetLangIcon (MSCTF.@) 316 * 317 * @unimplemented 318 */ 319EXTERN_C HICON WINAPI 320TF_GetLangIcon(_In_ LANGID LangID, _Out_ PWSTR pszText, _In_ INT cchText) 321{ 322 FIXME("(0x%X, %p, %d)\n", LangID, pszText, cchText); 323 return NULL; 324} 325 326/*********************************************************************** 327 * TF_IsFullScreenWindowAcitvated (MSCTF.@) 328 * 329 * Yes, this function name is misspelled by MS. 330 * @unimplemented 331 */ 332EXTERN_C BOOL WINAPI 333TF_IsFullScreenWindowAcitvated(VOID) 334{ 335 FIXME("()\n"); 336 return FALSE; 337} 338 339/*********************************************************************** 340 * TF_GetInputScope (MSCTF.@) 341 * 342 * @unimplemented 343 */ 344EXTERN_C HRESULT WINAPI 345TF_GetInputScope(_In_opt_ HWND hWnd, _Out_ ITfInputScope **ppInputScope) 346{ 347 FIXME("(%p, %p)\n", hWnd, ppInputScope); 348 *ppInputScope = NULL; 349 return E_NOTIMPL; 350} 351 352/*********************************************************************** 353 * SetInputScopeXML (MSCTF.@) 354 * 355 * @unimplemented 356 */ 357EXTERN_C HRESULT WINAPI 358SetInputScopeXML(_In_opt_ HWND hwnd, _In_opt_ PCWSTR pszXML) 359{ 360 FIXME("(%p, %p)\n", hwnd, pszXML); 361 return E_NOTIMPL; 362} 363 364/*********************************************************************** 365 * TF_CUASAppFix (MSCTF.@) 366 * 367 * @implemented 368 */ 369EXTERN_C HRESULT WINAPI 370TF_CUASAppFix(_In_ LPCSTR pszName) 371{ 372 if (!pszName || lstrcmpiA(pszName, "DelayFirstActivateKeyboardLayout") != 0) 373 return E_INVALIDARG; 374 g_dwAppCompatibility |= CTF_COMPAT_DELAY_FIRST_ACTIVATE; 375 return S_OK; 376} 377 378/*********************************************************************** 379 * TF_CheckThreadInputIdle (MSCTF.@) 380 * 381 * @unimplemented 382 */ 383EXTERN_C LONG WINAPI 384TF_CheckThreadInputIdle(_In_ DWORD dwThreadId, _In_ DWORD dwMilliseconds) 385{ 386 FIXME("(%lu, %lu)\n", dwThreadId, dwMilliseconds); 387 return -1; 388} 389 390/*********************************************************************** 391 * TF_ClearLangBarAddIns (MSCTF.@) 392 * 393 * @unimplemented 394 */ 395EXTERN_C HRESULT WINAPI 396TF_ClearLangBarAddIns(_In_ REFGUID guid) 397{ 398 FIXME("(%p)\n", guid); 399 return E_NOTIMPL; 400} 401 402/*********************************************************************** 403 * TF_InvalidAssemblyListCache (MSCTF.@) 404 * 405 * @unimplemented 406 */ 407EXTERN_C HRESULT WINAPI 408TF_InvalidAssemblyListCache(VOID) 409{ 410 FIXME("()\n"); 411 return E_NOTIMPL; 412} 413 414/*********************************************************************** 415 * TF_IsInMarshaling (MSCTF.@) 416 * 417 * @unimplemented 418 */ 419EXTERN_C BOOL WINAPI 420TF_IsInMarshaling(_In_ DWORD dwThreadId) 421{ 422 FIXME("(%lu)\n", dwThreadId); 423 return FALSE; 424} 425 426/*********************************************************************** 427 * TF_PostAllThreadMsg (MSCTF.@) 428 * 429 * @unimplemented 430 */ 431EXTERN_C HRESULT WINAPI 432TF_PostAllThreadMsg(_In_opt_ WPARAM wParam, _In_ DWORD dwFlags) 433{ 434 FIXME("(%p, 0x%X)\n", wParam, dwFlags); 435 return E_NOTIMPL; 436} 437 438/*********************************************************************** 439 * TF_InitSystem (MSCTF.@) 440 * 441 * @unimplemented 442 */ 443EXTERN_C BOOL WINAPI 444TF_InitSystem(VOID) 445{ 446 FIXME("()\n"); 447 return FALSE; 448} 449 450/*********************************************************************** 451 * TF_UninitSystem (MSCTF.@) 452 * 453 * @unimplemented 454 */ 455EXTERN_C BOOL WINAPI 456TF_UninitSystem(VOID) 457{ 458 FIXME("()\n"); 459 return FALSE; 460} 461 462/*********************************************************************** 463 * TF_RegisterLangBarAddIn (MSCTF.@) 464 * 465 * @implemented 466 */ 467EXTERN_C HRESULT WINAPI 468TF_RegisterLangBarAddIn( 469 _In_ REFGUID rguid, 470 _In_ LPCWSTR pszFilePath, 471 _In_ DWORD dwFlags) 472{ 473 TRACE("(%s, %s, 0x%lX)\n", debugstr_guid(&rguid), debugstr_w(pszFilePath), dwFlags); 474 475 if (!pszFilePath || rguid == GUID_NULL) 476 { 477 ERR("E_INVALIDARG\n"); 478 return E_INVALIDARG; 479 } 480 481 TCHAR szBuff[MAX_PATH], szGUID[40]; 482 StringCchCopy(szBuff, _countof(szBuff), TEXT("SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\")); 483 StringFromGUID2T(rguid, szGUID, _countof(szGUID)); 484 StringCchCat(szBuff, _countof(szBuff), szGUID); 485 486 CicRegKey regKey; 487 HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); 488 LSTATUS error = regKey.Create(hBaseKey, szBuff); 489 if (error == ERROR_SUCCESS) 490 { 491 error = regKey.SetSzW(L"FilePath", pszFilePath); 492 if (error == ERROR_SUCCESS) 493 error = regKey.SetDword(TEXT("Enable"), !!(dwFlags & 4)); 494 } 495 496 return ((error == ERROR_SUCCESS) ? S_OK : E_FAIL); 497} 498 499/*********************************************************************** 500 * TF_UnregisterLangBarAddIn (MSCTF.@) 501 * 502 * @implemented 503 */ 504EXTERN_C HRESULT WINAPI 505TF_UnregisterLangBarAddIn( 506 _In_ REFGUID rguid, 507 _In_ DWORD dwFlags) 508{ 509 TRACE("(%s, 0x%lX)\n", debugstr_guid(&rguid), dwFlags); 510 511 if (rguid == GUID_NULL) 512 { 513 ERR("E_INVALIDARG\n"); 514 return E_INVALIDARG; 515 } 516 517 TCHAR szSubKey[MAX_PATH]; 518 StringCchCopy(szSubKey, _countof(szSubKey), TEXT("SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\")); 519 520 CicRegKey regKey; 521 HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); 522 LSTATUS error = regKey.Open(hBaseKey, szSubKey, KEY_ALL_ACCESS); 523 HRESULT hr = E_FAIL; 524 if (error == ERROR_SUCCESS) 525 { 526 TCHAR szGUID[40]; 527 StringFromGUID2T(rguid, szGUID, _countof(szGUID)); 528 regKey.RecurseDeleteKey(szGUID); 529 hr = S_OK; 530 } 531 532 return hr; 533} 534 535/*********************************************************************** 536 * TF_RunInputCPL (MSCTF.@) 537 * 538 * @implemented 539 */ 540EXTERN_C HRESULT WINAPI 541TF_RunInputCPL(VOID) 542{ 543 CicSystemModulePath ModPath; 544 TCHAR szCmdLine[2 * MAX_PATH]; 545 546 TRACE("()\n"); 547 548 // NOTE: We don't support Win95/98/Me 549 if (g_dwOSInfo & CIC_OSINFO_XPPLUS) 550 ModPath.Init(TEXT("input.dll"), FALSE); 551 else 552 ModPath.Init(TEXT("input.cpl"), FALSE); 553 554 if (!ModPath.m_cchPath) 555 return E_FAIL; 556 557 StringCchPrintf(szCmdLine, _countof(szCmdLine), 558 TEXT("rundll32.exe shell32.dll,Control_RunDLL %s"), ModPath.m_szPath); 559 if (!RunCPLSetting(szCmdLine)) 560 return E_FAIL; 561 562 return S_OK; 563} 564 565/*********************************************************************** 566 * TF_IsCtfmonRunning (MSCTF.@) 567 * 568 * @implemented 569 */ 570EXTERN_C BOOL WINAPI 571TF_IsCtfmonRunning(VOID) 572{ 573 TCHAR szName[MAX_PATH]; 574 GetDesktopUniqueName(TEXT("CtfmonInstMutex"), szName, _countof(szName)); 575 576 HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, szName); 577 if (!hMutex) 578 return FALSE; 579 580 ::CloseHandle(hMutex); 581 return TRUE; 582} 583 584/** 585 * @implemented 586 */ 587BOOL InitLangChangeHotKey(VOID) 588{ 589 CicRegKey regKey; 590 TCHAR szLanguage[2], szLayout[2]; 591 LSTATUS error; 592 593 szLanguage[0] = szLayout[0] = TEXT('3'); 594 szLanguage[1] = szLayout[1] = TEXT('\0'); 595 596 error = regKey.Open(HKEY_CURRENT_USER, TEXT("Keyboard Layout\\Toggle")); 597 if (error == ERROR_SUCCESS) 598 { 599 error = regKey.QuerySz(TEXT("Language Hotkey"), szLanguage, _countof(szLanguage)); 600 if (error != ERROR_SUCCESS) 601 { 602 if (g_dwOSInfo & CIC_OSINFO_NT) 603 { 604 error = regKey.QuerySz(TEXT("Hotkey"), szLanguage, _countof(szLanguage)); 605 if (error != ERROR_SUCCESS) 606 szLanguage[0] = TEXT('1'); 607 } 608 else 609 { 610 error = regKey.QuerySz(NULL, szLanguage, _countof(szLanguage)); 611 if (error != ERROR_SUCCESS) 612 szLanguage[0] = TEXT('1'); 613 } 614 615 if (PRIMARYLANGID(GetSystemDefaultLCID()) == LANG_CHINESE) 616 szLanguage[0] = TEXT('1'); 617 } 618 619 error = regKey.QuerySz(TEXT("Layout Hotkey"), szLayout, _countof(szLayout)); 620 if (error != ERROR_SUCCESS) 621 { 622 szLayout[0] = TEXT('1'); 623 if (szLanguage[0] != TEXT('2')) 624 szLayout[0] = TEXT('2'); 625 if (GetSystemMetrics(SM_MIDEASTENABLED)) 626 szLayout[0] = TEXT('3'); 627 } 628 629 szLanguage[1] = TEXT('\0'); 630 szLayout[1] = TEXT('\0'); 631 } 632 633 if (szLanguage[0] == szLayout[0]) 634 { 635 if (szLanguage[0] == TEXT('1')) 636 szLayout[0] = TEXT('2'); 637 else if (szLanguage[0] == TEXT('2')) 638 szLayout[0] = TEXT('1'); 639 else 640 szLayout[0] = TEXT('3'); 641 } 642 643 ::EnterCriticalSection(&g_csInDllMain); 644 645 switch (szLanguage[0]) 646 { 647 case TEXT('2'): 648 g_uLangHotKeyModifiers = MOD_SHIFT | MOD_CONTROL; 649 g_uLangHotKeyVKey2 = VK_CONTROL; 650 g_uLangHotKeyVKey = VK_SHIFT; 651 break; 652 653 case TEXT('3'): 654 g_uLangHotKeyVKey = 0; 655 g_uLangHotKeyModifiers = 0; 656 g_uLangHotKeyVKey2 = 0; 657 break; 658 659 case TEXT('4'): 660 g_uLangHotKeyVKey = VK_NUMPAD0; 661 g_uLangHotKeyModifiers = 0; 662 g_uLangHotKeyVKey2 = 0; 663 break; 664 665 case TEXT('1'): 666 default: 667 g_uLangHotKeyModifiers = MOD_SHIFT | MOD_ALT; 668 g_uLangHotKeyVKey2 = VK_MENU; 669 g_uLangHotKeyVKey = VK_SHIFT; 670 break; 671 } 672 673 switch (szLayout[0]) 674 { 675 case TEXT('2'): 676 g_uKeyTipHotKeyModifiers = MOD_SHIFT | MOD_CONTROL; 677 g_uKeyTipHotKeyVKey = VK_SHIFT; 678 g_uKeyTipHotKeyVKey2 = VK_CONTROL; 679 break; 680 681 case TEXT('3'): 682 g_uKeyTipHotKeyModifiers = 0; 683 g_uKeyTipHotKeyVKey = 0; 684 g_uKeyTipHotKeyVKey2 = 0; 685 break; 686 687 case TEXT('4'): 688 g_uKeyTipHotKeyModifiers = 0; 689 g_uKeyTipHotKeyVKey = VK_OEM_3; 690 g_uKeyTipHotKeyVKey2 = 0; 691 break; 692 693 case TEXT('1'): 694 default: 695 g_uKeyTipHotKeyModifiers = 0x40 | MOD_SHIFT; 696 g_uKeyTipHotKeyVKey = VK_SHIFT; 697 g_uKeyTipHotKeyVKey2 = VK_MENU; 698 break; 699 } 700 701 ::LeaveCriticalSection(&g_csInDllMain); 702 703 TRACE("HotKey: %c, %c\n", szLanguage[0], szLayout[0]); 704 return TRUE; 705} 706 707/** 708 * @implemented 709 */ 710VOID CheckAnchorStores(VOID) 711{ 712 HKEY hKey; 713 LSTATUS error; 714 error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\CTF"), 0, KEY_READ, &hKey); 715 if (error != ERROR_SUCCESS) 716 return; 717 718 DWORD dwData = 0, cbData = sizeof(dwData); 719 error = RegQueryValueEx(hKey, TEXT("EnableAnchorContext"), NULL, NULL, (PBYTE)&dwData, &cbData); 720 if (error == ERROR_SUCCESS && cbData == sizeof(DWORD) && dwData == 1) 721 g_fNoITextStoreAnchor = FALSE; 722 723 RegCloseKey(hKey); 724} 725 726VOID InitCUASFlag(VOID) 727{ 728 CicRegKey regKey1; 729 LSTATUS error; 730 731 error = regKey1.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\CTF\\SystemShared\\")); 732 if (error == ERROR_SUCCESS) 733 { 734 DWORD dwValue; 735 error = regKey1.QueryDword(TEXT("CUAS"), &dwValue); 736 if (error == ERROR_SUCCESS) 737 g_fCUAS = !!dwValue; 738 } 739 740 g_szCUASImeFile[0] = TEXT('\0'); 741 742 if (!g_fCUAS) 743 return; 744 745 TCHAR szImeFile[16]; 746 CicRegKey regKey2; 747 error = regKey2.Open(HKEY_LOCAL_MACHINE, 748 TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM")); 749 if (error == ERROR_SUCCESS) 750 { 751 error = regKey2.QuerySz(TEXT("IME File"), szImeFile, _countof(szImeFile)); 752 if (error == ERROR_SUCCESS) 753 { 754 g_szCUASImeFile[_countof(g_szCUASImeFile) - 1] = TEXT('\0'); // Avoid buffer overrun 755 StringCchCopy(g_szCUASImeFile, _countof(g_szCUASImeFile), szImeFile); 756 } 757 } 758} 759 760EXTERN_C VOID TFUninitLib(VOID) 761{ 762 // Do nothing 763} 764 765/// @unimplemented 766BOOL ProcessAttach(HINSTANCE hinstDLL) 767{ 768 gf_CRT_INIT = TRUE; 769 770 ::InitializeCriticalSectionAndSpinCount(&g_cs, 0); 771 ::InitializeCriticalSectionAndSpinCount(&g_csInDllMain, 0); 772 ::InitializeCriticalSectionAndSpinCount(&g_csDelayLoad, 0); 773 774 g_bOnWow64 = cicIsWow64(); 775 g_hInst = hinstDLL; 776 g_hklDefault = ::GetKeyboardLayout(0); 777 g_dwTLSIndex = ::TlsAlloc(); 778 if (g_dwTLSIndex == (DWORD)-1) 779 return FALSE; 780 781 g_msgPrivate = ::RegisterWindowMessageA("MSUIM.Msg.Private"); 782 g_msgSetFocus = ::RegisterWindowMessageA("MSUIM.Msg.SetFocus"); 783 g_msgThreadTerminate = ::RegisterWindowMessageA("MSUIM.Msg.ThreadTerminate"); 784 g_msgThreadItemChange = ::RegisterWindowMessageA("MSUIM.Msg.ThreadItemChange"); 785 g_msgLBarModal = ::RegisterWindowMessageA("MSUIM.Msg.LangBarModal"); 786 g_msgRpcSendReceive = ::RegisterWindowMessageA("MSUIM.Msg.RpcSendReceive"); 787 g_msgThreadMarshal = ::RegisterWindowMessageA("MSUIM.Msg.ThreadMarshal"); 788 g_msgCheckThreadInputIdel = ::RegisterWindowMessageA("MSUIM.Msg.CheckThreadInputIdel"); 789 g_msgStubCleanUp = ::RegisterWindowMessageA("MSUIM.Msg.StubCleanUp"); 790 g_msgShowFloating = ::RegisterWindowMessageA("MSUIM.Msg.ShowFloating"); 791 g_msgLBUpdate = ::RegisterWindowMessageA("MSUIM.Msg.LBUpdate"); 792 g_msgNuiMgrDirtyUpdate = ::RegisterWindowMessageA("MSUIM.Msg.MuiMgrDirtyUpdate"); 793 if (!g_msgPrivate || 794 !g_msgSetFocus || 795 !g_msgThreadTerminate || 796 !g_msgThreadItemChange || 797 !g_msgLBarModal || 798 !g_msgRpcSendReceive || 799 !g_msgThreadMarshal || 800 !g_msgCheckThreadInputIdel || 801 !g_msgStubCleanUp || 802 !g_msgShowFloating || 803 !g_msgLBUpdate || 804 !g_msgNuiMgrDirtyUpdate) 805 { 806 return FALSE; 807 } 808 809 cicGetOSInfo(&g_uACP, &g_dwOSInfo); 810 TRACE("cicGetOSInfo: %u, 0x%lX\n", g_uACP, g_dwOSInfo); 811 812 InitUniqueString(); 813 814 //FIXME 815 816 gfSharedMemory = TRUE; 817 818 //FIXME 819 820 InitCUASFlag(); 821 822 //FIXME 823 824 GetDesktopUniqueName(TEXT("CTF.AsmListCache.FMP"), g_szAsmListCache, _countof(g_szAsmListCache)); 825 GetDesktopUniqueName(TEXT("CTF.TimListCache.FMP"), g_szTimListCache, _countof(g_szTimListCache)); 826 GetDesktopUniqueName(TEXT("CTF.LayoutsCache.FMP"), g_szLayoutsCache, _countof(g_szLayoutsCache)); 827 828 //FIXME 829 830 InitLangChangeHotKey(); 831 832 //FIXME 833 834 CheckAnchorStores(); 835 836 return TRUE; 837} 838 839/// @unimplemented 840VOID ProcessDetach(HINSTANCE hinstDLL) 841{ 842 if (!gf_CRT_INIT) 843 { 844 g_fDllProcessDetached = TRUE; 845 return; 846 } 847 848 if (gfSharedMemory) 849 { 850 if (g_cRefDll != -1 ) 851 TFUninitLib(); 852 //FIXME 853 } 854 855 UninitINAT(); 856 857 //FIXME 858 859 //TF_UninitThreadSystem(); 860 861 //FIXME 862 863 if (g_dwTLSIndex != (DWORD)-1) 864 { 865 ::TlsFree(g_dwTLSIndex); 866 g_dwTLSIndex = (DWORD)-1; 867 } 868 869 //FIXME 870 871 if (gfSharedMemory) 872 { 873 g_mutexLBES.Uninit(); 874 g_mutexCompart.Uninit(); 875 g_mutexAsm.Uninit(); 876 //FIXME 877 g_mutexLayouts.Uninit(); 878 g_mutexTMD.Uninit(); 879 //FIXME 880 g_SharedMemory.Close(); 881 } 882 883 g_SharedMemory.Finalize(); 884 885 ::DeleteCriticalSection(&g_cs); 886 ::DeleteCriticalSection(&g_csInDllMain); 887 ::DeleteCriticalSection(&g_csDelayLoad); 888 889 g_fDllProcessDetached = TRUE; 890}