Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions src/win32/base/tsf_registrar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ constexpr wchar_t kTipInProcServer32[] = L"InProcServer32";
constexpr wchar_t kTipThreadingModel[] = L"ThreadingModel";
constexpr wchar_t kTipTextServiceModel[] = L"Apartment";

constexpr REGSAM AdjustRegFlagBitness(REGSAM base_flags,
COMServerBitness bitness) {
REGSAM flags = base_flags;
switch (bitness) {
case COMServerBitness::k32bit:
flags |= KEY_WOW64_32KEY;
flags &= ~KEY_WOW64_64KEY;
break;
case COMServerBitness::k64bit:
flags |= KEY_WOW64_64KEY;
flags &= ~KEY_WOW64_32KEY;
break;
}
return flags;
}

// The categories this text service is registered under.
// This needs to be const as the included constants are defined as const.
const GUID kCategories[] = {
Expand All @@ -78,10 +94,12 @@ const GUID kCategories[] = {
// * The description of this module;
// * The path to this module, and;
// * The type of this module (threading moddel).
HRESULT TsfRegistrar::RegisterCOMServer(const wchar_t* path, DWORD length) {
HRESULT TsfRegistrar::RegisterCOMServer(const wchar_t* path, DWORD length,
COMServerBitness bitness) {
if (length == 0) {
return E_OUTOFMEMORY;
}
const REGSAM reg_flags = AdjustRegFlagBitness(KEY_READ | KEY_WRITE, bitness);
// Open the registry key "HKEY_CLASSES_ROOT\CLSID", which stores information
// of all COM modules installed in this PC.
// To register a COM module to Windows, we should create a key of its GUID
Expand All @@ -92,7 +110,7 @@ HRESULT TsfRegistrar::RegisterCOMServer(const wchar_t* path, DWORD length) {
// * The threading model of this module.
ATL::CRegKey parent;
LONG result = parent.Open(HKEY_CLASSES_ROOT, &kTipInfoKeyPrefix[0],
KEY_READ | KEY_WRITE);
reg_flags);
if (result != ERROR_SUCCESS) {
return HRESULT_FROM_WIN32(result);
}
Expand All @@ -107,7 +125,7 @@ HRESULT TsfRegistrar::RegisterCOMServer(const wchar_t* path, DWORD length) {

ATL::CRegKey key;
result = key.Create(parent, &ime_key[0], REG_NONE, REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE, nullptr, nullptr);
reg_flags, nullptr, nullptr);
if (result != ERROR_SUCCESS) {
return HRESULT_FROM_WIN32(result);
}
Expand Down Expand Up @@ -138,7 +156,7 @@ HRESULT TsfRegistrar::RegisterCOMServer(const wchar_t* path, DWORD length) {
// Unregisters this module from Windows.
// This function just deletes the all registry keys under
// "HKCR\CLSID\{xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx}".
void TsfRegistrar::UnregisterCOMServer() {
void TsfRegistrar::UnregisterCOMServer(COMServerBitness bitness) {
// Create the registry key for this COM server.
// Only Administrators can create keys under HKEY_CLASSES_ROOT.
wchar_t ime_key[64] = {};
Expand All @@ -147,9 +165,10 @@ void TsfRegistrar::UnregisterCOMServer() {
return;
}

const REGSAM reg_flags = AdjustRegFlagBitness(KEY_READ | KEY_WRITE, bitness);
ATL::CRegKey key;
HRESULT result =
key.Open(HKEY_CLASSES_ROOT, &kTipInfoKeyPrefix[0], KEY_READ | KEY_WRITE);
HRESULT result = key.Open(HKEY_CLASSES_ROOT, &kTipInfoKeyPrefix[0],
reg_flags);
if (result != ERROR_SUCCESS) {
return;
}
Expand Down
13 changes: 11 additions & 2 deletions src/win32/base/tsf_registrar.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
namespace mozc {
namespace win32 {

enum class COMServerBitness {
k64bit,
k32bit,
};

// Registers Mozc as a text input processor or unregister.
class TsfRegistrar {
public:
Expand All @@ -45,10 +50,14 @@ class TsfRegistrar {
TsfRegistrar& operator=(const TsfRegistrar&) = delete;

// Registers the DLL specified with |path| as a COM server.
static HRESULT RegisterCOMServer(const wchar_t* path, DWORD length);
// |bitness| specifies which registry view to use: k64bit for the native
// 64-bit view, k32bit for the WOW6432Node (32-bit) view.
static HRESULT RegisterCOMServer(const wchar_t* path, DWORD length,
COMServerBitness bitness);

// Unregisters the DLL from registry.
static void UnregisterCOMServer();
// |bitness| specifies which registry view to unregister from.
static void UnregisterCOMServer(COMServerBitness bitness);

// Registers this COM server to the profile store for input processors.
// The caller is responsible for initializing COM before call this function.
Expand Down
4 changes: 0 additions & 4 deletions src/win32/custom_action/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ mozc_win32_cc_prod_binary(
"custom_action.h",
"resource.h",
],
defines = select({
"//:enable_win_universal_installer": ["MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER"],
"//conditions:default": [],
}),
executable_name_map = {
"Mozc": "mozc_installer_helper.dll",
"GoogleJapaneseInput": "GoogleIMEJaInstallerHelper.dll",
Expand Down
59 changes: 26 additions & 33 deletions src/win32/custom_action/custom_action.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,8 @@
#include <windows.h>
#include <atlbase.h>
#include <msiquery.h>
// clang-format on

#if defined(MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER)
#include <wow64apiset.h>
#endif // defined(MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER)
// clang-format on

#undef StrCat // NOLINT: TODO: triggers clang-tidy, defined by windows.h.

Expand Down Expand Up @@ -457,44 +454,43 @@ UINT __stdcall RegisterTIP(MSIHANDLE msi_handle) {
mozc::ScopedCOMInitializer com_initializer;
HRESULT result = S_OK;

#if defined(MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER)
// Register 64-bit TIP COM server.
// Unlike 32-bit TIP DLL, which is always x86, the expected 64-bit TIP DLL
// can be x64 or ARM64X depending on the target environment. This is why
// only 64-bit TIP DLL is dynamically registered here.

// |IsWow64Process2| is added in Windows 10 1709 / Windows Server 1709. Let's
// check if the API is available before calling it.
// TODO: Directly call |IsWow64Process2| after we stop supporting Windows 10.
// can be x64 or ARM64X depending on the target environment.
USHORT process_machine = IMAGE_FILE_MACHINE_UNKNOWN;
USHORT native_machine = IMAGE_FILE_MACHINE_UNKNOWN;
auto IsWow64Process2Func = reinterpret_cast<decltype(&::IsWow64Process2)>(
::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "IsWow64Process2"));
if (IsWow64Process2Func != nullptr) [[likely]] {
result = IsWow64Process2Func(::GetCurrentProcess(), &process_machine,
&native_machine);
} else {
// Fallback to x64.
result = E_NOTIMPL;
}
result = IsWow64Process2(::GetCurrentProcess(), &process_machine,
&native_machine);
const bool is_arm64_machine =
SUCCEEDED(result) && native_machine == IMAGE_FILE_MACHINE_ARM64;
const std::wstring& tip64_path = GetMozcComponentPath(
const std::wstring tip64_path = GetMozcComponentPath(
is_arm64_machine ? mozc::kMozcTIP64X : mozc::kMozcTIP64);

result = mozc::win32::TsfRegistrar::RegisterCOMServer(tip64_path.c_str(),
tip64_path.length());
result = mozc::win32::TsfRegistrar::RegisterCOMServer(
tip64_path.c_str(), tip64_path.length(),
mozc::win32::COMServerBitness::k64bit);
if (FAILED(result)) {
LOG_ERROR_FOR_OMAHA();
UnregisterTIP(msi_handle);
return ERROR_INSTALL_FAILURE;
}
#endif // defined(MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER)

// Register 32-bit TIP COM server.
const std::wstring tip32_path = GetMozcComponentPath(mozc::kMozcTIP32);
result = mozc::win32::TsfRegistrar::RegisterCOMServer(
tip32_path.c_str(), tip32_path.length(),
mozc::win32::COMServerBitness::k32bit);
if (FAILED(result)) {
LOG_ERROR_FOR_OMAHA();
UnregisterTIP(msi_handle);
return ERROR_INSTALL_FAILURE;
}

// Register profiles and categories.
// The path here is to retrieve Win32 resources such as icon and product name,
// which does not need to match the native CPU architecture. Here we use
// 32-bit TIP DLL as it is always installed even on an ARM64 target.
const std::wstring resource_dll_path = GetMozcComponentPath(mozc::kMozcTIP32);
result = mozc::win32::TsfRegistrar::RegisterProfiles(resource_dll_path);
result = mozc::win32::TsfRegistrar::RegisterProfiles(tip32_path);
if (FAILED(result)) {
LOG_ERROR_FOR_OMAHA();
UnregisterTIP(msi_handle);
Expand Down Expand Up @@ -523,13 +519,10 @@ UINT __stdcall UnregisterTIP(MSIHANDLE msi_handle) {

mozc::win32::TsfRegistrar::UnregisterCategories();
mozc::win32::TsfRegistrar::UnregisterProfiles();

#if defined(MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER)
// Unlike 32-bit TIP DLL, which is always x86, the expected 64-bit TIP DLL
// can be x64 or ARM64X depending on the target environment. This is why
// only 64-bit TIP DLL is dynamically unregistered here.
mozc::win32::TsfRegistrar::UnregisterCOMServer();
#endif // defined(MOZC_ENABLE_WIN_UNIVERSAL_INSTALLER)
mozc::win32::TsfRegistrar::UnregisterCOMServer(
mozc::win32::COMServerBitness::k64bit);
mozc::win32::TsfRegistrar::UnregisterCOMServer(
mozc::win32::COMServerBitness::k32bit);

return ERROR_SUCCESS;
}
Expand Down
16 changes: 3 additions & 13 deletions src/win32/installer/installer_64bit.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -296,27 +296,17 @@
<ServiceControl Id="StopGoogleIMEJaCacheService" Name="GoogleIMEJaCacheService" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
<Component Id="GIMEJaTIP32" Permanent="no" Bitness="always32">
<File Id="GoogleIMEJaTIP32.dll" Name="GoogleIMEJaTIP32.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP32Path)" Vital="yes">
<Class Context="InprocServer32" ThreadingModel="apartment" Description="Google Japanese Input" Id="D5A86FD5-5308-47EA-AD16-9C4EB160EC3C" />
</File>
<File Id="GoogleIMEJaTIP32.dll" Name="GoogleIMEJaTIP32.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP32Path)" Vital="yes" />
</Component>
<Component Id="GIMEJaTIP64" Permanent="no" Bitness="always64">
<File Id="GoogleIMEJaTIP64.dll" Name="GoogleIMEJaTIP64.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64Path)" Vital="yes">
<?if $(var.MozcTIP64ArmPath) == "" and $(var.MozcTIP64XPath) == "" and $(var.MozcUniversalInstaller) == "" ?>
<Class Context="InprocServer32" ThreadingModel="apartment" Description="Google Japanese Input" Id="D5A86FD5-5308-47EA-AD16-9C4EB160EC3C" />
<?endif?>
</File>
<File Id="GoogleIMEJaTIP64.dll" Name="GoogleIMEJaTIP64.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64Path)" Vital="yes" />
</Component>
<?if $(var.MozcTIP64ArmPath) != "" and $(var.MozcTIP64XPath) != "" ?>
<Component Id="GIMEJaTIP64Arm" Permanent="no" Bitness="always64">
<File Id="GoogleIMEJaTIP64Arm.dll" Name="GoogleIMEJaTIP64Arm.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64ArmPath)" Vital="yes" />
</Component>
<Component Id="GIMEJaTIP64X" Permanent="no" Bitness="always64">
<File Id="GoogleIMEJaTIP64X.dll" Name="GoogleIMEJaTIP64X.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64XPath)" Vital="yes">
<?if $(var.MozcUniversalInstaller) == "" ?>
<Class Context="InprocServer32" ThreadingModel="apartment" Description="Google Japanese Input" Id="D5A86FD5-5308-47EA-AD16-9C4EB160EC3C" />
<?endif?>
</File>
<File Id="GoogleIMEJaTIP64X.dll" Name="GoogleIMEJaTIP64X.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64XPath)" Vital="yes" />
</Component>
<?endif?>
<Component Id="GIMEJaBroker" Permanent="no">
Expand Down
16 changes: 3 additions & 13 deletions src/win32/installer/installer_oss_64bit.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -271,27 +271,17 @@
<ServiceControl Id="StopMozcCacheService" Name="MozcCacheService" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
<Component Id="MozcTIP32" Permanent="no" Bitness="always32">
<File Id="mozc_tip32.dll" Name="mozc_tip32.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP32Path)" Vital="yes">
<Class Context="InprocServer32" ThreadingModel="apartment" Description="Mozc" Id="10A67BC8-22FA-4A59-90DC-2546652C56BF" />
</File>
<File Id="mozc_tip32.dll" Name="mozc_tip32.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP32Path)" Vital="yes" />
</Component>
<Component Id="MozcTIP64" Permanent="no" Bitness="always64">
<File Id="mozc_tip64.dll" Name="mozc_tip64.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64Path)" Vital="yes">
<?if $(var.MozcTIP64ArmPath) == "" and $(var.MozcTIP64XPath) == "" and $(var.MozcUniversalInstaller) == "" ?>
<Class Context="InprocServer32" ThreadingModel="apartment" Description="Mozc" Id="10A67BC8-22FA-4A59-90DC-2546652C56BF" />
<?endif?>
</File>
<File Id="mozc_tip64.dll" Name="mozc_tip64.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64Path)" Vital="yes" />
</Component>
<?if $(var.MozcTIP64ArmPath) != "" and $(var.MozcTIP64XPath) != "" ?>
<Component Id="MozcTIP64Arm" Permanent="no" Bitness="always64">
<File Id="mozc_tip64arm.dll" Name="mozc_tip64arm.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64ArmPath)" Vital="yes" />
</Component>
<Component Id="MozcTIP64X" Permanent="no" Bitness="always64">
<File Id="mozc_tip64x.dll" Name="mozc_tip64x.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64XPath)" Vital="yes">
<?if $(var.MozcUniversalInstaller) == "" ?>
<Class Context="InprocServer32" ThreadingModel="apartment" Description="Mozc" Id="10A67BC8-22FA-4A59-90DC-2546652C56BF" />
<?endif?>
</File>
<File Id="mozc_tip64x.dll" Name="mozc_tip64x.dll" DiskId="1" Checksum="yes" Source="$(var.MozcTIP64XPath)" Vital="yes" />
</Component>
<?endif?>
<Component Id="MozcBroker" Permanent="no">
Expand Down