Permalink
Browse files

Implicitly link to input.dll on Windows.

Now that we we no longer support Windows XP, we can safely assume
that input.dll is always available and it's OK to implicitly link
to that rather than relying on LoadLibrary and GetProcAddress.

One tricky part is that Windows SDK does not provide the import
library for input.dll.  To work around this, we will create our own
import library as a part of build steps, by following this document.
http://support.microsoft.com/kb/131313/en-us

BUG=none
TEST=compile
  • Loading branch information...
1 parent a93dd6e commit f470414b26d0e0f13f2ec865e0f3a1d2046a5398 @yukawa yukawa committed May 23, 2015
@@ -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.
@@ -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<LAYOUTORTIPPROFILE[]> 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()) {
@@ -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<FPEnumEnabledLayoutOrTip>(
- ::GetProcAddress(input_dll, kEnumEnabledLayoutOrTipName));
-
- enum_layout_or_tip_for_setup_ =
- reinterpret_cast<FPEnumLayoutOrTipForSetup>(
- ::GetProcAddress(input_dll, kEnumLayoutOrTipForSetup));
+#include <windows.h>
- install_layout_or_tip_ =
- reinterpret_cast<FPInstallLayoutOrTip>(
- ::GetProcAddress(input_dll, kInstallLayoutOrTipName));
-
- install_layout_or_tip_user_reg_ =
- reinterpret_cast<FPInstallLayoutOrTipUserReg>(
- ::GetProcAddress(input_dll, kInstallLayoutOrTipUserRegName));
-
- set_default_layout_or_tip_ =
- reinterpret_cast<FPSetDefaultLayoutOrTip>(
- ::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<HMODULE>(
- ::InterlockedCompareExchangePointer(
- reinterpret_cast<volatile PVOID *>(&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
@@ -0,0 +1,8 @@
+LIBRARY input.dll
+
+EXPORTS
+ EnumEnabledLayoutOrTip
+ EnumLayoutOrTipForSetup
+ InstallLayoutOrTip
+ InstallLayoutOrTipUserReg
+ SetDefaultLayoutOrTip
Oops, something went wrong.

0 comments on commit f470414

Please sign in to comment.