From 698cb9b285c91eeae130e05718b83eda865a9f79 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 17 Oct 2024 14:54:54 -0700 Subject: [PATCH] Retrieve Mozc's installation dir from registry This is a preparation to switch Mozc's installation directory from %ProgramFiles(x86)%\Mozc into %ProgramFiles%\Mozc without user observable downtime (#1086). Currently the directory %ProgramFiles(x86)%\Mozc is effectively hard coded in 'mozc_tip{32,64}.dll'. This means if older versions of 'mozc_tip{32,64}.dll' continue assuming the previous installation directory until it is unloaded or the process is restarted. To avoid such mismatch, with this commit SystemUtil::GetServerDirectory() starts dynamically retrieving Mozc's installation directory from registry by checking COM entries of 'mozc_tip64.dll'. If it fails, we fall back to the previous behavior. Note that this is the first step of the migration and we cannot go to the next step until 'mozc_tip{32,64}.dll' with this commit is deployed to users. --- src/base/system_util.cc | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/base/system_util.cc b/src/base/system_util.cc index ffb3cfa7a..ec1b70e0f 100644 --- a/src/base/system_util.cc +++ b/src/base/system_util.cc @@ -409,11 +409,48 @@ class ProgramFilesX86Cache { HRESULT result_; std::string path_; }; + +constexpr wchar_t kMozcTipClsid[] = + L"SOFTWARE\\Classes\\CLSID\\" +#ifdef GOOGLE_JAPANESE_INPUT_BUILD + L"{D5A86FD5-5308-47EA-AD16-9C4EB160EC3C}" +#else // GOOGLE_JAPANESE_INPUT_BUILD + L"{10A67BC8-22FA-4A59-90DC-2546652C56BF}" +#endif // GOOGLE_JAPANESE_INPUT_BUILD + L"\\InprocServer32"; + +std::string GetMozcInstallDirFromRegistry() { + // TSF requires the path of "mozc_tip64.dll" to be registered in the registry, + // which tells us Mozc's installation directory. + HKEY key = nullptr; + LSTATUS result =::RegOpenKeyExW( + HKEY_LOCAL_MACHINE, kMozcTipClsid, 0, KEY_READ | KEY_WOW64_64KEY, &key); + if (result != ERROR_SUCCESS) { + return ""; + } + + DWORD type = 0; + wchar_t buffer[MAX_PATH] = {}; + DWORD buffer_size = sizeof(buffer); + result = ::RegQueryValueExW( + key, nullptr, nullptr, &type, reinterpret_cast(buffer), + &buffer_size); + ::RegCloseKey(key); + if (result != ERROR_SUCCESS || type != REG_SZ) { + return ""; + } + return FileUtil::Dirname(win32::WideToUtf8(buffer)); +} + } // namespace #endif // _WIN32 std::string SystemUtil::GetServerDirectory() { #ifdef _WIN32 + const std::string install_dir_from_registry = GetMozcInstallDirFromRegistry(); + if (!install_dir_from_registry.empty()) { + return install_dir_from_registry; + } DCHECK(SUCCEEDED(Singleton::get()->result())); #if defined(GOOGLE_JAPANESE_INPUT_BUILD) return FileUtil::JoinPath(