diff --git a/src/mozc_version_template.txt b/src/mozc_version_template.txt index 1160a21db..01e955d91 100644 --- a/src/mozc_version_template.txt +++ b/src/mozc_version_template.txt @@ -1,6 +1,6 @@ MAJOR=2 MINOR=17 -BUILD=2096 +BUILD=2097 REVISION=102 # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be # downloaded by NaCl Mozc. diff --git a/src/win32/base/imm_util.cc b/src/win32/base/imm_util.cc index b90307335..ce50feee5 100644 --- a/src/win32/base/imm_util.cc +++ b/src/win32/base/imm_util.cc @@ -70,20 +70,12 @@ const wchar_t kCUASValueName[] = L"CUAS"; const uint32 kWaitForAsmCacheReadyEventTimeout = 4500; // 4.5 sec. bool GetDefaultLayout(LAYOUTORTIPPROFILE *profile) { - if (!InputDll::EnsureInitialized()) { - return false; - } - - if (InputDll::enum_enabled_layout_or_tip() == nullptr) { - return false; - } - - const UINT num_element = InputDll::enum_enabled_layout_or_tip()( + const UINT num_element = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, nullptr, 0); unique_ptr buffer(new LAYOUTORTIPPROFILE[num_element]); - const UINT num_copied = InputDll::enum_enabled_layout_or_tip()( + const UINT num_copied =::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, buffer.get(), num_element); for (size_t i = 0; i < num_copied; ++i) { @@ -140,12 +132,6 @@ bool IsDefaultWin8() { } bool SetDefaultWin8() { - if (!InputDll::EnsureInitialized()) { - return false; - } - if (InputDll::set_default_layout_or_tip() == nullptr) { - return false; - } wchar_t clsid[64] = {}; if (!::StringFromGUID2(TsfProfile::GetTextServiceGuid(), clsid, arraysize(clsid))) { @@ -158,11 +144,11 @@ bool SetDefaultWin8() { } const wstring &profile = wstring(L"0x0411:") + clsid + profile_id; - if (!InputDll::install_layout_or_tip()(profile.c_str(), 0)) { + if (!::InstallLayoutOrTip(profile.c_str(), 0)) { DLOG(ERROR) << "InstallLayoutOrTip failed"; return false; } - if (!InputDll::set_default_layout_or_tip()(profile.c_str(), 0)) { + if (!::SetDefaultLayoutOrTip(profile.c_str(), 0)) { DLOG(ERROR) << "SetDefaultLayoutOrTip failed"; return false; } @@ -262,29 +248,10 @@ bool ImeUtil::SetDefault() { return false; } - if (InputDll::EnsureInitialized() && - InputDll::set_default_layout_or_tip() != nullptr) { - // In most cases, we can use this method on Vista or later. - const wstring &profile_list = L"0x0411:0x" + mozc_klid.ToString(); - if (!InputDll::set_default_layout_or_tip()(profile_list.c_str(), 0)) { - DLOG(ERROR) << "SetDefaultLayoutOrTip failed"; - return false; - } - } else { - // We cannot use const HKL because |&mozc_hkl| will be cast into PVOID. - HKL hkl = ::LoadKeyboardLayout(mozc_klid.ToString().c_str(), KLF_ACTIVATE); - if (0 == ::SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, - 0, - &hkl, - SPIF_SENDCHANGE)) { - LOG(ERROR) << "SystemParameterInfo failed: " << GetLastError(); - return false; - } - - if (S_OK != ImmRegistrar::MovePreloadValueToTop(mozc_klid)) { - LOG(ERROR) << "MovePreloadValueToTop failed"; - return false; - } + const wstring &profile_list = L"0x0411:0x" + mozc_klid.ToString(); + if (!::SetDefaultLayoutOrTip(profile_list.c_str(), 0)) { + DLOG(ERROR) << "SetDefaultLayoutOrTip failed"; + return false; } if (!ActivateForCurrentSession()) { diff --git a/src/win32/base/input_dll.cc b/src/win32/base/input_dll.cc index f7ea76a3c..c24a6c96c 100644 --- a/src/win32/base/input_dll.cc +++ b/src/win32/base/input_dll.cc @@ -27,123 +27,70 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "win32/base/input_dll.h" +// This file will be used to create an import library. Functions in this +// file must not be called directly. -#include "base/logging.h" -#include "base/util.h" -#include "base/win_util.h" - -namespace mozc { -namespace win32 { - -const wchar_t kInputDllName[] = L"input.dll"; - -const char kEnumEnabledLayoutOrTipName[] = "EnumEnabledLayoutOrTip"; -const char kEnumLayoutOrTipForSetup[] = "EnumLayoutOrTipForSetup"; -const char kInstallLayoutOrTipName[] = "InstallLayoutOrTip"; -const char kInstallLayoutOrTipUserRegName[] = "InstallLayoutOrTipUserReg"; -const char kSetDefaultLayoutOrTipName[] = "SetDefaultLayoutOrTip"; - -bool InputDll::EnsureInitialized() { - if (not_found_) { - // Previous trial was not successful. give up. - return false; - } - - if (module_ != nullptr) { - // Already initialized. - return true; - } - - bool lock_held = false; - if (!WinUtil::IsDLLSynchronizationHeld(&lock_held)) { - LOG(ERROR) << "IsDLLSynchronizationHeld failed."; - return false; - } - if (lock_held) { - LOG(INFO) << "This thread has loader lock. " - << "LoadLibrary should not be called."; - return false; - } - - const HMODULE input_dll = WinUtil::LoadSystemLibrary(kInputDllName); - if (input_dll == nullptr) { - const int last_error = ::GetLastError(); - DLOG(INFO) << "LoadSystemLibrary(\"" << kInputDllName << "\") failed. " - << "error = " << last_error; - if (last_error == ERROR_MOD_NOT_FOUND) { - not_found_ = true; - } - return false; - } - - enum_enabled_layout_or_tip_ = - reinterpret_cast( - ::GetProcAddress(input_dll, kEnumEnabledLayoutOrTipName)); - - enum_layout_or_tip_for_setup_ = - reinterpret_cast( - ::GetProcAddress(input_dll, kEnumLayoutOrTipForSetup)); +#include - install_layout_or_tip_ = - reinterpret_cast( - ::GetProcAddress(input_dll, kInstallLayoutOrTipName)); - - install_layout_or_tip_user_reg_ = - reinterpret_cast( - ::GetProcAddress(input_dll, kInstallLayoutOrTipUserRegName)); - - set_default_layout_or_tip_ = - reinterpret_cast( - ::GetProcAddress(input_dll, kSetDefaultLayoutOrTipName)); - - // Other threads may load the same DLL concurrently. - // Check if this thread is the first thread which updated the |module_|. - const HMODULE original = static_cast( - ::InterlockedCompareExchangePointer( - reinterpret_cast(&module_), input_dll, nullptr)); - if (original == nullptr) { - // This is the first thread which updated the |module_| with valid handle. - // Do not call FreeLibrary to keep the reference count positive. - } else { - // |module_| has already been updated by another thread. Call FreeLibrary - // to decrement the reference count which this thread owns. - ::FreeLibrary(input_dll); - } - - return true; -} +#include "base/logging.h" -InputDll::FPEnumEnabledLayoutOrTip InputDll::enum_enabled_layout_or_tip() { - return enum_enabled_layout_or_tip_; +struct LAYOUTORTIPPROFILE; +struct LAYOUTORTIP; + +extern "C" +UINT WINAPI EnumEnabledLayoutOrTip( + __in_opt LPCWSTR pszUserReg, + __in_opt LPCWSTR pszSystemReg, + __in_opt LPCWSTR pszSoftwareReg, + __out LAYOUTORTIPPROFILE *pLayoutOrTipProfile, + __in UINT uBufLength) { + CHECK(false) + << "This is a stub function to create an import library. " + << "Shouldn't be called from anywhere."; + return 0; } -InputDll::FPEnumLayoutOrTipForSetup InputDll::enum_layout_or_tip_for_setup() { - return enum_layout_or_tip_for_setup_; +extern "C" +UINT WINAPI EnumLayoutOrTipForSetup( + __in LANGID langid, + __out_ecount(uBufLength) LAYOUTORTIP *pLayoutOrTip, + __in UINT uBufLength, + __in DWORD dwFlags) { + CHECK(false) + << "This is a stub function to create an import library. " + << "Shouldn't be called from anywhere."; + return 0; } -InputDll::FPInstallLayoutOrTip InputDll::install_layout_or_tip() { - return install_layout_or_tip_; +extern "C" +BOOL WINAPI InstallLayoutOrTip( + __in LPCWSTR psz, + __in DWORD dwFlags) { + CHECK(false) + << "This is a stub function to create an import library. " + << "Shouldn't be called from anywhere."; + return FALSE; } -InputDll::FPInstallLayoutOrTipUserReg - InputDll::install_layout_or_tip_user_reg() { - return install_layout_or_tip_user_reg_; +extern "C" +BOOL WINAPI InstallLayoutOrTipUserReg( + __in_opt LPCWSTR pszUserReg, + __in_opt LPCWSTR pszSystemReg, + __in_opt LPCWSTR pszSoftwareReg, + __in LPCWSTR psz, + __in DWORD dwFlags) { + CHECK(false) + << "This is a stub function to create an import library. " + << "Shouldn't be called from anywhere."; + return FALSE; } -InputDll::FPSetDefaultLayoutOrTip InputDll::set_default_layout_or_tip() { - return set_default_layout_or_tip_; +extern "C" +BOOL WINAPI SetDefaultLayoutOrTip( + __in LPCWSTR psz, + DWORD dwFlags) { + CHECK(false) + << "This is a stub function to create an import library. " + << "Shouldn't be called from anywhere."; + return FALSE; } - -bool InputDll::not_found_; - -volatile HMODULE InputDll::module_; -InputDll::FPEnumEnabledLayoutOrTip InputDll::enum_enabled_layout_or_tip_; -InputDll::FPEnumLayoutOrTipForSetup InputDll::enum_layout_or_tip_for_setup_; -InputDll::FPInstallLayoutOrTip InputDll::install_layout_or_tip_; -InputDll::FPInstallLayoutOrTipUserReg -InputDll::install_layout_or_tip_user_reg_; -InputDll::FPSetDefaultLayoutOrTip InputDll::set_default_layout_or_tip_; - -} // namespace win32 -} // namespace mozc diff --git a/src/win32/base/input_dll.def b/src/win32/base/input_dll.def new file mode 100644 index 000000000..8c1c7062c --- /dev/null +++ b/src/win32/base/input_dll.def @@ -0,0 +1,8 @@ +LIBRARY input.dll + +EXPORTS + EnumEnabledLayoutOrTip + EnumLayoutOrTipForSetup + InstallLayoutOrTip + InstallLayoutOrTipUserReg + SetDefaultLayoutOrTip diff --git a/src/win32/base/input_dll.h b/src/win32/base/input_dll.h index 20937c168..208d9d1b6 100644 --- a/src/win32/base/input_dll.h +++ b/src/win32/base/input_dll.h @@ -32,10 +32,6 @@ #include -#include "base/port.h" -#include "testing/base/public/gunit_prod.h" -// for FRIEND_TEST() - // Structures and flags bellow have not been included header files in Windows // SDK. You can see the original source of this information at the following // page. @@ -81,166 +77,131 @@ typedef struct tagLAYOUTORTIPPROFILE { WCHAR szId[MAX_PATH]; } LAYOUTORTIPPROFILE; -namespace mozc { -namespace win32 { - -// With these function, you no longer need to manipulate undocumented registry -// entries such as "Keyboard Layout/Preload". -// TODO(yukawa): Add mock injection mechanism to support unit tests. -class InputDll { - public: - // Ensures input.dll is loaded into the process so that its export functions - // become available. When this method returns true, the returned value of - // each accessor method like |set_default_layout_or_tip()| is the same to - // the returned address of GetProcAddress API. If |EnsureInitialized()| - // returns true but the accessor method returns nullptr, it means that the DLL - // exists on the system but the expected function is not exported. - // You can call this method multiple times from multiple threads. In other - // words, you can use this method like 'IsInizialized'. - // This method fails if input.dll is not available on the system. This - // method also fails if the caller thread owns loader lock. - static bool EnsureInitialized(); - - // Returns a function pointer to the EnumEnabledLayoutOrTip API, which - // is available on Vista or later via input.dll to enumerates all enabled - // keyboard layouts or text services of the specified user setting. - // - // EnumEnabledLayoutOrTip: - // URL: - // http://msdn.microsoft.com/en-us/library/bb847907.aspx - // Return Value: - // TRUE: The function was successful. - // FALSE: An unspecified error occurred. - typedef UINT (CALLBACK *FPEnumEnabledLayoutOrTip)( - __in_opt LPCWSTR pszUserReg, - __in_opt LPCWSTR pszSystemReg, - __in_opt LPCWSTR pszSoftwareReg, - __out LAYOUTORTIPPROFILE *pLayoutOrTipProfile, - __in UINT uBufLength); - static FPEnumEnabledLayoutOrTip enum_enabled_layout_or_tip(); +// Returns a function pointer to the EnumEnabledLayoutOrTip API, which +// is available on Vista or later via input.dll to enumerates all enabled +// keyboard layouts or text services of the specified user setting. +// +// EnumEnabledLayoutOrTip: +// URL: +// http://msdn.microsoft.com/en-us/library/bb847907.aspx +// Return Value: +// TRUE: The function was successful. +// FALSE: An unspecified error occurred. +extern "C" __declspec(dllimport) +UINT WINAPI EnumEnabledLayoutOrTip( + __in_opt LPCWSTR pszUserReg, + __in_opt LPCWSTR pszSystemReg, + __in_opt LPCWSTR pszSoftwareReg, + __out LAYOUTORTIPPROFILE *pLayoutOrTipProfile, + __in UINT uBufLength); - // Returns a function pointer to the EnumEnabledLayoutOrTip API, which - // is available on Vista or later via input.dll to enumerates the installed - // keyboard layouts and text services. - // - // EnumLayoutOrTipForSetup: - // URL: - // http://msdn.microsoft.com/en-us/library/bb847908.aspx - // Return Value: - // |pLayoutOrTip == nullptr| - // The number of elements to be returned. - // |pLayoutOrTip != nullptr| - // The number of elements actually copied to |pLayoutOrTip|. - typedef UINT (CALLBACK *FPEnumLayoutOrTipForSetup)( +// Returns a function pointer to the EnumEnabledLayoutOrTip API, which +// is available on Vista or later via input.dll to enumerates the installed +// keyboard layouts and text services. +// +// EnumLayoutOrTipForSetup: +// URL: +// http://msdn.microsoft.com/en-us/library/bb847908.aspx +// Return Value: +// |pLayoutOrTip == nullptr| +// The number of elements to be returned. +// |pLayoutOrTip != nullptr| +// The number of elements actually copied to |pLayoutOrTip|. +extern "C" __declspec(dllimport) +UINT WINAPI EnumLayoutOrTipForSetup( __in LANGID langid, __out_ecount(uBufLength) LAYOUTORTIP *pLayoutOrTip, __in UINT uBufLength, __in DWORD dwFlags); - static FPEnumLayoutOrTipForSetup enum_layout_or_tip_for_setup(); - // Returns a function pointer to the InstallLayoutOrTip API, which is - // available on Vista or later via input.dll to enable the specified - // keyboard layouts or text services for the current user. - // - // InstallLayoutOrTip: - // URL: - // http://msdn.microsoft.com/en-us/library/bb847909.aspx - // Remarks: - // The string format of the layout list is: - // :;[...: - // The string format of the text service profile list is: - // :{CLSID of TIP}{GUID of LanguageProfile}; - // where GUID should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. - // This format seems to be corresponding to the registry key, e.g. - // HKLM\SOFTWARE\Microsoft\CTF\TIP\{CLSID of TIP}\LanguageProfile\ - // {Land ID}\{GUID of LanguageProfile} - // Return Value: - // TRUE: The function was successful. - // FALSE: An unspecified error occurred. - typedef BOOL (CALLBACK *FPInstallLayoutOrTip)( +// Returns a function pointer to the InstallLayoutOrTip API, which is +// available on Vista or later via input.dll to enable the specified +// keyboard layouts or text services for the current user. +// +// InstallLayoutOrTip: +// URL: +// http://msdn.microsoft.com/en-us/library/bb847909.aspx +// Remarks: +// The string format of the layout list is: +// :;[...: +// The string format of the text service profile list is: +// :{CLSID of TIP}{GUID of LanguageProfile}; +// where GUID should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. +// This format seems to be corresponding to the registry key, e.g. +// HKLM\SOFTWARE\Microsoft\CTF\TIP\{CLSID of TIP}\LanguageProfile\ +// {Land ID}\{GUID of LanguageProfile} +// Return Value: +// TRUE: The function was successful. +// FALSE: An unspecified error occurred. +extern "C" __declspec(dllimport) +BOOL WINAPI InstallLayoutOrTip( __in LPCWSTR psz, __in DWORD dwFlags); - static FPInstallLayoutOrTip install_layout_or_tip(); - // Returns a function pointer to the InstallLayoutOrTipUserReg API, which - // is available on Vista or later via input.dll to enable the specified - // keyboard layouts or text services for the specified user. - // - // InstallLayoutOrTipUserReg: - // URL: - // http://msdn.microsoft.com/en-us/library/bb847910.aspx - // Remarks: - // The string format of the layout list is: - // :;[...: - // The string format of the text service profile list is: - // :{CLSID of TIP}{GUID of LanguageProfile}; - // where GUID should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. - // This format seems to be corresponding to the registry key, e.g. - // HKLM\SOFTWARE\Microsoft\CTF\TIP\{CLSID of TIP}\LanguageProfile\ - // {Land ID}\{GUID of LanguageProfile} - // Return Value: - // TRUE: The function was successful. - // FALSE: An unspecified error occurred. - // Observational Facts: - // Like ImmInstallIME API, calling InstallLayoutOrTipUserReg from 32-bit - // process to install x64 binaries is not recommended. Otherwise, we - // will see some weird issues like b/2931871. - typedef BOOL (CALLBACK *FPInstallLayoutOrTipUserReg)( +// Returns a function pointer to the InstallLayoutOrTipUserReg API, which +// is available on Vista or later via input.dll to enable the specified +// keyboard layouts or text services for the specified user. +// +// InstallLayoutOrTipUserReg: +// URL: +// http://msdn.microsoft.com/en-us/library/bb847910.aspx +// Remarks: +// The string format of the layout list is: +// :;[...: +// The string format of the text service profile list is: +// :{CLSID of TIP}{GUID of LanguageProfile}; +// where GUID should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. +// This format seems to be corresponding to the registry key, e.g. +// HKLM\SOFTWARE\Microsoft\CTF\TIP\{CLSID of TIP}\LanguageProfile\ +// {Land ID}\{GUID of LanguageProfile} +// Return Value: +// TRUE: The function was successful. +// FALSE: An unspecified error occurred. +// Observational Facts: +// Like ImmInstallIME API, calling InstallLayoutOrTipUserReg from 32-bit +// process to install x64 binaries is not recommended. Otherwise, we +// will see some weird issues like b/2931871. +extern "C" __declspec(dllimport) +BOOL WINAPI InstallLayoutOrTipUserReg( __in_opt LPCWSTR pszUserReg, __in_opt LPCWSTR pszSystemReg, __in_opt LPCWSTR pszSoftwareReg, __in LPCWSTR psz, __in DWORD dwFlags); - static FPInstallLayoutOrTipUserReg install_layout_or_tip_user_reg(); - // Returns a function pointer to the SetDefaultLayoutOrTip API, which sets - // the specified keyboard layout or a text service as the default input item - // of the current user. - // - // SetDefaultLayoutOrTip: - // URL: - // http://msdn.microsoft.com/en-us/library/bb847915.aspx - // Remarks: - // The string format of the layout list is: - // :;[...: - // The string format of the text service profile list is: - // :{CLSID of TIP}{GUID of LanguageProfile}; - // where GUID should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. - // This format seems to be corresponding to the registry key, e.g. - // HKLM\SOFTWARE\Microsoft\CTF\TIP\{CLSID of TIP}\LanguageProfile\ - // {Land ID}\{GUID of LanguageProfile} - // Return Value: - // TRUE: The function was successful. - // FALSE: An unspecified error occurred. - // Observational Facts: - // This API seems to be designed to modify per user settings, like HKCU, - // so that the current user can modify it with his/her privileges. In - // oother words, no administrative privilege is required. - // SetDefaultLayoutOrTipUserReg might be a phantom, which only exists in - // MSDN Library. - // This function returns fail if it is called to install an IME which is - // not enabled (if we use undocumented terms to explain the condition, - // "The IME is not listed in the Preload key"). It seems that the caller - // is responsible to enable (e.g. calling InstallLayoutOrTipUserReg) - // the target IME before call this function to set the IME default. - typedef BOOL (CALLBACK *FPSetDefaultLayoutOrTip)( - __in LPCWSTR psz, - DWORD dwFlags); - static FPSetDefaultLayoutOrTip set_default_layout_or_tip(); - - private: - static volatile HMODULE module_; - static bool not_found_; - static FPEnumEnabledLayoutOrTip enum_enabled_layout_or_tip_; - static FPEnumLayoutOrTipForSetup enum_layout_or_tip_for_setup_; - static FPInstallLayoutOrTip install_layout_or_tip_; - static FPInstallLayoutOrTipUserReg install_layout_or_tip_user_reg_; - static FPSetDefaultLayoutOrTip set_default_layout_or_tip_; - - FRIEND_TEST(InputDllTest, EnsureInitializedTest); +// Returns a function pointer to the SetDefaultLayoutOrTip API, which sets +// the specified keyboard layout or a text service as the default input item +// of the current user. +// +// SetDefaultLayoutOrTip: +// URL: +// http://msdn.microsoft.com/en-us/library/bb847915.aspx +// Remarks: +// The string format of the layout list is: +// :;[...: +// The string format of the text service profile list is: +// :{CLSID of TIP}{GUID of LanguageProfile}; +// where GUID should be like {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. +// This format seems to be corresponding to the registry key, e.g. +// HKLM\SOFTWARE\Microsoft\CTF\TIP\{CLSID of TIP}\LanguageProfile\ +// {Land ID}\{GUID of LanguageProfile} +// Return Value: +// TRUE: The function was successful. +// FALSE: An unspecified error occurred. +// Observational Facts: +// This API seems to be designed to modify per user settings, like HKCU, +// so that the current user can modify it with his/her privileges. In +// oother words, no administrative privilege is required. +// SetDefaultLayoutOrTipUserReg might be a phantom, which only exists in +// MSDN Library. +// This function returns fail if it is called to install an IME which is +// not enabled (if we use undocumented terms to explain the condition, +// "The IME is not listed in the Preload key"). It seems that the caller +// is responsible to enable (e.g. calling InstallLayoutOrTipUserReg) +// the target IME before call this function to set the IME default. +extern "C" __declspec(dllimport) +BOOL WINAPI SetDefaultLayoutOrTip( + __in LPCWSTR psz, + DWORD dwFlags); - DISALLOW_IMPLICIT_CONSTRUCTORS(InputDll); -}; -} // namespace win32 -} // namespace mozc #endif // MOZC_WIN32_BASE_INPUT_DLL_H_ diff --git a/src/win32/base/input_dll_test.cc b/src/win32/base/input_dll_test.cc index 0507c9cbb..bbed53c1e 100644 --- a/src/win32/base/input_dll_test.cc +++ b/src/win32/base/input_dll_test.cc @@ -27,79 +27,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include "win32/base/input_dll.h" #include "testing/base/public/googletest.h" #include "testing/base/public/gunit.h" -#include "win32/base/input_dll.h" - -namespace mozc { -namespace win32 { - -class InputDllTest : public testing::Test { - public: - protected: - InputDllTest() {} - - virtual ~InputDllTest() {} - - virtual void SetUp() { - // TODO(yukawa): Implement injection mechanism to ::LoadLibrary API - // TODO(yukawa): Inject custom LoadLibrary to make this test independent - // of test environment. - } - - virtual void TearDown() { - // TODO(yukawa): Implement injection mechanism to ::LoadLibrary API - // TODO(yukawa): Remove custom LoadLibrary injection not to affect - // subsequent tests. - } - - private: - DISALLOW_COPY_AND_ASSIGN(InputDllTest); -}; - -// Currently this test is not independent of test environment. -// TODO(yukawa): Implement injection mechanism to ::LoadLibrary API to make -// the code flow predictable. -TEST_F(InputDllTest, EnsureInitializedTest) { - if (InputDll::EnsureInitialized()) { - // Check internal status. - EXPECT_FALSE(InputDll::not_found_); - // gtest will cause compilation error if we use here. - // Use instead. - EXPECT_NE(nullptr, static_cast(InputDll::module_)); - - // Actually input.dll exists on Windows XP. However, it does not always - // mean that input.dll exports the functions in which we are interested. - - // Assume that the following funcsions are available on Vista and later. - EXPECT_NE(nullptr, InputDll::enum_enabled_layout_or_tip()); - EXPECT_NE(nullptr, InputDll::enum_layout_or_tip_for_setup()); - EXPECT_NE(nullptr, InputDll::install_layout_or_tip()); - EXPECT_NE(nullptr, InputDll::install_layout_or_tip_user_reg()); - EXPECT_NE(nullptr, InputDll::set_default_layout_or_tip()); - - // Check the consistency of the retuls of second call. - EXPECT_TRUE(InputDll::EnsureInitialized()); - return; - } - - // Check internal status. - EXPECT_TRUE(InputDll::not_found_); - // gtest will cause compilation error if we use here. - // Use instead. - EXPECT_EQ(nullptr, static_cast(InputDll::module_)); - EXPECT_EQ(nullptr, InputDll::enum_enabled_layout_or_tip()); - EXPECT_EQ(nullptr, InputDll::enum_layout_or_tip_for_setup()); - EXPECT_EQ(nullptr, InputDll::install_layout_or_tip()); - EXPECT_EQ(nullptr, InputDll::install_layout_or_tip_user_reg()); - EXPECT_EQ(nullptr, InputDll::set_default_layout_or_tip()); +namespace { - // Check the consistency of the retuls of second call. - EXPECT_FALSE(InputDll::EnsureInitialized()); +TEST(InputDllTest, EnumEnabledLayoutOrTipTest) { + const UINT num_element = ::EnumEnabledLayoutOrTip( + nullptr, nullptr, nullptr, nullptr, 0); + EXPECT_LT(0, num_element); } -} // namespace win32 -} // namespace mozc +} // namespace diff --git a/src/win32/base/migration_util.cc b/src/win32/base/migration_util.cc index c21baf6b0..d9baacb5a 100644 --- a/src/win32/base/migration_util.cc +++ b/src/win32/base/migration_util.cc @@ -134,18 +134,12 @@ bool MigrationUtil::DisableLegacyMozcForCurrentUserOnWin8() { return true; } - if (!InputDll::EnsureInitialized()) { - return false; - } - if (InputDll::enum_enabled_layout_or_tip() == nullptr) { - return false; - } - const UINT num_element = InputDll::enum_enabled_layout_or_tip()( + const UINT num_element = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, nullptr, 0); unique_ptr buffer(new LAYOUTORTIPPROFILE[num_element]); - const UINT num_copied = InputDll::enum_enabled_layout_or_tip()( + const UINT num_copied = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, buffer.get(), num_element); // Look up IMM32 Mozc from |buffer|. @@ -202,7 +196,7 @@ bool MigrationUtil::DisableLegacyMozcForCurrentUserOnWin8() { } const wstring &profile = wstring(L"0x0411:") + clsid + profile_id; - if (!InputDll::set_default_layout_or_tip()(profile.c_str(), 0)) { + if (!::SetDefaultLayoutOrTip(profile.c_str(), 0)) { DLOG(ERROR) << "SetDefaultLayoutOrTip failed"; return false; } @@ -216,7 +210,7 @@ bool MigrationUtil::DisableLegacyMozcForCurrentUserOnWin8() { klid.ToString().c_str()))) { return false; } - if (!InputDll::install_layout_or_tip()(profile_str, ILOT_DISABLED)) { + if (!::InstallLayoutOrTip(profile_str, ILOT_DISABLED)) { DLOG(ERROR) << "InstallLayoutOrTip failed"; return false; } diff --git a/src/win32/base/tsf_registrar.cc b/src/win32/base/tsf_registrar.cc index 673f3ec7f..0154fb37a 100644 --- a/src/win32/base/tsf_registrar.cc +++ b/src/win32/base/tsf_registrar.cc @@ -312,18 +312,11 @@ HRESULT TsfRegistrar::GetProfileEnabled(BOOL *enabled) { } *enabled = FALSE; - // Check if input.dll is exporting EnumEnabledLayoutOrTIP API, which is the - // best way to enumerate enabled profiles for the current user. - if (InputDll::EnsureInitialized() || - (InputDll::enum_enabled_layout_or_tip() == nullptr)) { - return E_FAIL; - } - - const int num_profiles = InputDll::enum_enabled_layout_or_tip()( + const int num_profiles = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, nullptr, 0); unique_ptr profiles( new LAYOUTORTIPPROFILE[num_profiles]); - const int num_copied = InputDll::enum_enabled_layout_or_tip()( + const int num_copied = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, profiles.get(), num_profiles); for (size_t i = 0; i < num_copied; ++i) { diff --git a/src/win32/base/uninstall_helper.cc b/src/win32/base/uninstall_helper.cc index eb3afbd1b..0b7786d68 100644 --- a/src/win32/base/uninstall_helper.cc +++ b/src/win32/base/uninstall_helper.cc @@ -816,24 +816,17 @@ bool UninstallHelper::GetCurrentProfilesForVista( } current_profiles->clear(); - if (!InputDll::EnsureInitialized()) { - return false; - } - if (InputDll::enum_enabled_layout_or_tip() == nullptr) { - return false; - } - map keyboard_layouts; if (!GenerateKeyboardLayoutMap(&keyboard_layouts)) { return false; } { - const UINT num_element = InputDll::enum_enabled_layout_or_tip()( + const UINT num_element = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, nullptr, 0); unique_ptr buffer( new LAYOUTORTIPPROFILE[num_element]); - const UINT num_copied = InputDll::enum_enabled_layout_or_tip()( + const UINT num_copied = ::EnumEnabledLayoutOrTip( nullptr, nullptr, nullptr, buffer.get(), num_element); for (size_t i = 0; i < num_copied; ++i) { @@ -892,17 +885,10 @@ bool UninstallHelper::RemoveProfilesForVista( return true; } - if (!InputDll::EnsureInitialized()) { - return false; - } - if (InputDll::install_layout_or_tip_user_reg() == nullptr) { - return false; - } - const wstring &profile_string = ComposeProfileStringForVista( profiles_to_be_removed); - const BOOL result = InputDll::install_layout_or_tip_user_reg()( + const BOOL result = ::InstallLayoutOrTipUserReg( nullptr, nullptr, nullptr, profile_string.c_str(), ILOT_UNINSTALL); return result != FALSE; @@ -946,14 +932,6 @@ bool UninstallHelper::SetDefaultForVista( return true; } - if (!InputDll::EnsureInitialized()) { - return false; - } - - if (InputDll::set_default_layout_or_tip() == nullptr) { - return false; - } - if (!EnableAndBroadcastNewLayout(new_default, broadcast_change)) { // We do not return false here because the main task of this function is // setting the specified profile to default. @@ -974,8 +952,7 @@ bool UninstallHelper::SetDefaultForVista( flag = SDLOT_NOAPPLYTOCURRENTSESSION; } - if (InputDll::set_default_layout_or_tip()(profile_string.c_str(), flag) == - FALSE) { + if (!::SetDefaultLayoutOrTip(profile_string.c_str(), flag)) { DLOG(ERROR) << "SetDefaultLayoutOrTip failed"; return false; } diff --git a/src/win32/base/win32_base.gyp b/src/win32/base/win32_base.gyp index 17f57e9de..9c1a943f8 100644 --- a/src/win32/base/win32_base.gyp +++ b/src/win32/base/win32_base.gyp @@ -47,6 +47,24 @@ # TODO(yukawa): Refactor following targets when the implementation of # TSF Mozc is completed. 'targets': [ + { + 'target_name': 'input_dll_import_lib', + 'type': 'shared_library', + 'sources': [ + 'input_dll.cc', + 'input_dll.def', + ], + 'dependencies': [ + '../../base/base.gyp:base', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'AdditionalOptions': [ + '/ignore:4070', + ], + }, + }, + }, { 'target_name': 'imframework_util', 'type': 'static_library', @@ -54,13 +72,13 @@ 'imm_reconvert_string.cc', 'imm_registrar.cc', 'imm_util.cc', - 'input_dll.cc', 'keyboard_layout_id.cc', 'tsf_profile.cc', 'tsf_registrar.cc', ], 'dependencies': [ '../../base/base.gyp:base', + 'input_dll_import_lib', ], }, {