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(