Skip to content

Commit f470414

Browse files
committed
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
1 parent a93dd6e commit f470414

10 files changed

Lines changed: 219 additions & 416 deletions

src/mozc_version_template.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MAJOR=2
22
MINOR=17
3-
BUILD=2096
3+
BUILD=2097
44
REVISION=102
55
# NACL_DICTIONARY_VERSION is the target version of the system dictionary to be
66
# downloaded by NaCl Mozc.

src/win32/base/imm_util.cc

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,12 @@ const wchar_t kCUASValueName[] = L"CUAS";
7070
const uint32 kWaitForAsmCacheReadyEventTimeout = 4500; // 4.5 sec.
7171

7272
bool GetDefaultLayout(LAYOUTORTIPPROFILE *profile) {
73-
if (!InputDll::EnsureInitialized()) {
74-
return false;
75-
}
76-
77-
if (InputDll::enum_enabled_layout_or_tip() == nullptr) {
78-
return false;
79-
}
80-
81-
const UINT num_element = InputDll::enum_enabled_layout_or_tip()(
73+
const UINT num_element = ::EnumEnabledLayoutOrTip(
8274
nullptr, nullptr, nullptr, nullptr, 0);
8375

8476
unique_ptr<LAYOUTORTIPPROFILE[]> buffer(new LAYOUTORTIPPROFILE[num_element]);
8577

86-
const UINT num_copied = InputDll::enum_enabled_layout_or_tip()(
78+
const UINT num_copied =::EnumEnabledLayoutOrTip(
8779
nullptr, nullptr, nullptr, buffer.get(), num_element);
8880

8981
for (size_t i = 0; i < num_copied; ++i) {
@@ -140,12 +132,6 @@ bool IsDefaultWin8() {
140132
}
141133

142134
bool SetDefaultWin8() {
143-
if (!InputDll::EnsureInitialized()) {
144-
return false;
145-
}
146-
if (InputDll::set_default_layout_or_tip() == nullptr) {
147-
return false;
148-
}
149135
wchar_t clsid[64] = {};
150136
if (!::StringFromGUID2(TsfProfile::GetTextServiceGuid(), clsid,
151137
arraysize(clsid))) {
@@ -158,11 +144,11 @@ bool SetDefaultWin8() {
158144
}
159145

160146
const wstring &profile = wstring(L"0x0411:") + clsid + profile_id;
161-
if (!InputDll::install_layout_or_tip()(profile.c_str(), 0)) {
147+
if (!::InstallLayoutOrTip(profile.c_str(), 0)) {
162148
DLOG(ERROR) << "InstallLayoutOrTip failed";
163149
return false;
164150
}
165-
if (!InputDll::set_default_layout_or_tip()(profile.c_str(), 0)) {
151+
if (!::SetDefaultLayoutOrTip(profile.c_str(), 0)) {
166152
DLOG(ERROR) << "SetDefaultLayoutOrTip failed";
167153
return false;
168154
}
@@ -262,29 +248,10 @@ bool ImeUtil::SetDefault() {
262248
return false;
263249
}
264250

265-
if (InputDll::EnsureInitialized() &&
266-
InputDll::set_default_layout_or_tip() != nullptr) {
267-
// In most cases, we can use this method on Vista or later.
268-
const wstring &profile_list = L"0x0411:0x" + mozc_klid.ToString();
269-
if (!InputDll::set_default_layout_or_tip()(profile_list.c_str(), 0)) {
270-
DLOG(ERROR) << "SetDefaultLayoutOrTip failed";
271-
return false;
272-
}
273-
} else {
274-
// We cannot use const HKL because |&mozc_hkl| will be cast into PVOID.
275-
HKL hkl = ::LoadKeyboardLayout(mozc_klid.ToString().c_str(), KLF_ACTIVATE);
276-
if (0 == ::SystemParametersInfo(SPI_SETDEFAULTINPUTLANG,
277-
0,
278-
&hkl,
279-
SPIF_SENDCHANGE)) {
280-
LOG(ERROR) << "SystemParameterInfo failed: " << GetLastError();
281-
return false;
282-
}
283-
284-
if (S_OK != ImmRegistrar::MovePreloadValueToTop(mozc_klid)) {
285-
LOG(ERROR) << "MovePreloadValueToTop failed";
286-
return false;
287-
}
251+
const wstring &profile_list = L"0x0411:0x" + mozc_klid.ToString();
252+
if (!::SetDefaultLayoutOrTip(profile_list.c_str(), 0)) {
253+
DLOG(ERROR) << "SetDefaultLayoutOrTip failed";
254+
return false;
288255
}
289256

290257
if (!ActivateForCurrentSession()) {

src/win32/base/input_dll.cc

Lines changed: 55 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -27,123 +27,70 @@
2727
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929

30-
#include "win32/base/input_dll.h"
30+
// This file will be used to create an import library. Functions in this
31+
// file must not be called directly.
3132

32-
#include "base/logging.h"
33-
#include "base/util.h"
34-
#include "base/win_util.h"
35-
36-
namespace mozc {
37-
namespace win32 {
38-
39-
const wchar_t kInputDllName[] = L"input.dll";
40-
41-
const char kEnumEnabledLayoutOrTipName[] = "EnumEnabledLayoutOrTip";
42-
const char kEnumLayoutOrTipForSetup[] = "EnumLayoutOrTipForSetup";
43-
const char kInstallLayoutOrTipName[] = "InstallLayoutOrTip";
44-
const char kInstallLayoutOrTipUserRegName[] = "InstallLayoutOrTipUserReg";
45-
const char kSetDefaultLayoutOrTipName[] = "SetDefaultLayoutOrTip";
46-
47-
bool InputDll::EnsureInitialized() {
48-
if (not_found_) {
49-
// Previous trial was not successful. give up.
50-
return false;
51-
}
52-
53-
if (module_ != nullptr) {
54-
// Already initialized.
55-
return true;
56-
}
57-
58-
bool lock_held = false;
59-
if (!WinUtil::IsDLLSynchronizationHeld(&lock_held)) {
60-
LOG(ERROR) << "IsDLLSynchronizationHeld failed.";
61-
return false;
62-
}
63-
if (lock_held) {
64-
LOG(INFO) << "This thread has loader lock. "
65-
<< "LoadLibrary should not be called.";
66-
return false;
67-
}
68-
69-
const HMODULE input_dll = WinUtil::LoadSystemLibrary(kInputDllName);
70-
if (input_dll == nullptr) {
71-
const int last_error = ::GetLastError();
72-
DLOG(INFO) << "LoadSystemLibrary(\"" << kInputDllName << "\") failed. "
73-
<< "error = " << last_error;
74-
if (last_error == ERROR_MOD_NOT_FOUND) {
75-
not_found_ = true;
76-
}
77-
return false;
78-
}
79-
80-
enum_enabled_layout_or_tip_ =
81-
reinterpret_cast<FPEnumEnabledLayoutOrTip>(
82-
::GetProcAddress(input_dll, kEnumEnabledLayoutOrTipName));
83-
84-
enum_layout_or_tip_for_setup_ =
85-
reinterpret_cast<FPEnumLayoutOrTipForSetup>(
86-
::GetProcAddress(input_dll, kEnumLayoutOrTipForSetup));
33+
#include <windows.h>
8734

88-
install_layout_or_tip_ =
89-
reinterpret_cast<FPInstallLayoutOrTip>(
90-
::GetProcAddress(input_dll, kInstallLayoutOrTipName));
91-
92-
install_layout_or_tip_user_reg_ =
93-
reinterpret_cast<FPInstallLayoutOrTipUserReg>(
94-
::GetProcAddress(input_dll, kInstallLayoutOrTipUserRegName));
95-
96-
set_default_layout_or_tip_ =
97-
reinterpret_cast<FPSetDefaultLayoutOrTip>(
98-
::GetProcAddress(input_dll, kSetDefaultLayoutOrTipName));
99-
100-
// Other threads may load the same DLL concurrently.
101-
// Check if this thread is the first thread which updated the |module_|.
102-
const HMODULE original = static_cast<HMODULE>(
103-
::InterlockedCompareExchangePointer(
104-
reinterpret_cast<volatile PVOID *>(&module_), input_dll, nullptr));
105-
if (original == nullptr) {
106-
// This is the first thread which updated the |module_| with valid handle.
107-
// Do not call FreeLibrary to keep the reference count positive.
108-
} else {
109-
// |module_| has already been updated by another thread. Call FreeLibrary
110-
// to decrement the reference count which this thread owns.
111-
::FreeLibrary(input_dll);
112-
}
113-
114-
return true;
115-
}
35+
#include "base/logging.h"
11636

117-
InputDll::FPEnumEnabledLayoutOrTip InputDll::enum_enabled_layout_or_tip() {
118-
return enum_enabled_layout_or_tip_;
37+
struct LAYOUTORTIPPROFILE;
38+
struct LAYOUTORTIP;
39+
40+
extern "C"
41+
UINT WINAPI EnumEnabledLayoutOrTip(
42+
__in_opt LPCWSTR pszUserReg,
43+
__in_opt LPCWSTR pszSystemReg,
44+
__in_opt LPCWSTR pszSoftwareReg,
45+
__out LAYOUTORTIPPROFILE *pLayoutOrTipProfile,
46+
__in UINT uBufLength) {
47+
CHECK(false)
48+
<< "This is a stub function to create an import library. "
49+
<< "Shouldn't be called from anywhere.";
50+
return 0;
11951
}
12052

121-
InputDll::FPEnumLayoutOrTipForSetup InputDll::enum_layout_or_tip_for_setup() {
122-
return enum_layout_or_tip_for_setup_;
53+
extern "C"
54+
UINT WINAPI EnumLayoutOrTipForSetup(
55+
__in LANGID langid,
56+
__out_ecount(uBufLength) LAYOUTORTIP *pLayoutOrTip,
57+
__in UINT uBufLength,
58+
__in DWORD dwFlags) {
59+
CHECK(false)
60+
<< "This is a stub function to create an import library. "
61+
<< "Shouldn't be called from anywhere.";
62+
return 0;
12363
}
12464

125-
InputDll::FPInstallLayoutOrTip InputDll::install_layout_or_tip() {
126-
return install_layout_or_tip_;
65+
extern "C"
66+
BOOL WINAPI InstallLayoutOrTip(
67+
__in LPCWSTR psz,
68+
__in DWORD dwFlags) {
69+
CHECK(false)
70+
<< "This is a stub function to create an import library. "
71+
<< "Shouldn't be called from anywhere.";
72+
return FALSE;
12773
}
12874

129-
InputDll::FPInstallLayoutOrTipUserReg
130-
InputDll::install_layout_or_tip_user_reg() {
131-
return install_layout_or_tip_user_reg_;
75+
extern "C"
76+
BOOL WINAPI InstallLayoutOrTipUserReg(
77+
__in_opt LPCWSTR pszUserReg,
78+
__in_opt LPCWSTR pszSystemReg,
79+
__in_opt LPCWSTR pszSoftwareReg,
80+
__in LPCWSTR psz,
81+
__in DWORD dwFlags) {
82+
CHECK(false)
83+
<< "This is a stub function to create an import library. "
84+
<< "Shouldn't be called from anywhere.";
85+
return FALSE;
13286
}
13387

134-
InputDll::FPSetDefaultLayoutOrTip InputDll::set_default_layout_or_tip() {
135-
return set_default_layout_or_tip_;
88+
extern "C"
89+
BOOL WINAPI SetDefaultLayoutOrTip(
90+
__in LPCWSTR psz,
91+
DWORD dwFlags) {
92+
CHECK(false)
93+
<< "This is a stub function to create an import library. "
94+
<< "Shouldn't be called from anywhere.";
95+
return FALSE;
13696
}
137-
138-
bool InputDll::not_found_;
139-
140-
volatile HMODULE InputDll::module_;
141-
InputDll::FPEnumEnabledLayoutOrTip InputDll::enum_enabled_layout_or_tip_;
142-
InputDll::FPEnumLayoutOrTipForSetup InputDll::enum_layout_or_tip_for_setup_;
143-
InputDll::FPInstallLayoutOrTip InputDll::install_layout_or_tip_;
144-
InputDll::FPInstallLayoutOrTipUserReg
145-
InputDll::install_layout_or_tip_user_reg_;
146-
InputDll::FPSetDefaultLayoutOrTip InputDll::set_default_layout_or_tip_;
147-
148-
} // namespace win32
149-
} // namespace mozc

src/win32/base/input_dll.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
LIBRARY input.dll
2+
3+
EXPORTS
4+
EnumEnabledLayoutOrTip
5+
EnumLayoutOrTipForSetup
6+
InstallLayoutOrTip
7+
InstallLayoutOrTipUserReg
8+
SetDefaultLayoutOrTip

0 commit comments

Comments
 (0)