diff --git a/WeaselSetup/TSFRegister.cpp b/WeaselSetup/TSFRegister.cpp index 71ea1d848..f0003a5d4 100644 --- a/WeaselSetup/TSFRegister.cpp +++ b/WeaselSetup/TSFRegister.cpp @@ -198,7 +198,7 @@ BOOL RegisterServer(std::wstring filename, bool wow64) char achIMEKey[ARRAYSIZE(c_szInfoKeyPrefix) + CLSID_STRLEN]; DWORD flags = KEY_WRITE; if (wow64) { - flags |= KEY_WOW64_32KEY; + flags |= KEY_WOW64_64KEY; } //TCHAR achFileName[MAX_PATH]; diff --git a/WeaselSetup/WeaselSetup.cpp b/WeaselSetup/WeaselSetup.cpp index ff26b3bdd..8ef0d4ed1 100644 --- a/WeaselSetup/WeaselSetup.cpp +++ b/WeaselSetup/WeaselSetup.cpp @@ -94,7 +94,7 @@ static int CustomInstall(bool installing) return 1; ret = RegCreateKeyEx(HKEY_CURRENT_USER, KEY, - 0, NULL, 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY, 0, &hKey, NULL); + 0, NULL, 0, KEY_ALL_ACCESS, 0, &hKey, NULL); if (FAILED(HRESULT_FROM_WIN32(ret))) { MessageBox(NULL, KEY, L"安裝失敗", MB_ICONERROR | MB_OK); diff --git a/WeaselSetup/WeaselSetup.vcxproj b/WeaselSetup/WeaselSetup.vcxproj index 3265865ed..d5fab430a 100644 --- a/WeaselSetup/WeaselSetup.vcxproj +++ b/WeaselSetup/WeaselSetup.vcxproj @@ -5,18 +5,10 @@ Debug Win32 - - Debug - x64 - Release Win32 - - Release - x64 - {04B795DB-A22B-4657-9350-29F04B8FB8F6} @@ -31,12 +23,6 @@ Unicode $(PLATFORM_TOOLSET) - - Application - true - Unicode - $(PLATFORM_TOOLSET) - Application false @@ -44,44 +30,23 @@ Unicode $(PLATFORM_TOOLSET) - - Application - false - true - Unicode - $(PLATFORM_TOOLSET) - - - - - - - true - - true - false $(SolutionDir)output\ - - false - $(SolutionDir)output\ - $(ProjectName)$(Platform) - Use @@ -99,23 +64,6 @@ RequireAdministrator - - - Use - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - $(SolutionDir)\include;$(BOOST_ROOT) - MultiThreadedDebug - /Zc:threadSafeInit- %(AdditionalOptions) - - - Windows - true - $(SolutionDir)\lib;$(BOOST_ROOT)\stage\lib - RequireAdministrator - - Level3 @@ -139,29 +87,6 @@ RequireAdministrator - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - $(SolutionDir)\include;$(BOOST_ROOT) - MultiThreaded - /Zc:threadSafeInit- %(AdditionalOptions) - - - Windows - true - true - true - $(SolutionDir)\lib;$(BOOST_ROOT)\stage_x64\lib - imm32.lib;%(AdditionalDependencies) - RequireAdministrator - $(SolutionDir)output\$(ProjectName)$(Platform)$(TargetExt) - - @@ -180,9 +105,7 @@ Create - Create Create - Create diff --git a/WeaselSetup/imesetup.cpp b/WeaselSetup/imesetup.cpp index 43767cc45..a74f40891 100644 --- a/WeaselSetup/imesetup.cpp +++ b/WeaselSetup/imesetup.cpp @@ -54,50 +54,67 @@ BOOL delete_file(const std::wstring& file) return ret; } +BOOL is_wow64() +{ + DWORD errorCode; + if (GetSystemWow64DirectoryW(NULL, 0) == 0) + if ((errorCode = GetLastError()) == ERROR_CALL_NOT_IMPLEMENTED) + return FALSE; + else + ExitProcess((UINT)errorCode); + else + return TRUE; +} + +typedef BOOL (WINAPI *PW64DW64FR)(PVOID *); +typedef BOOL (WINAPI *PW64RW64FR)(PVOID); typedef int (*ime_register_func)(const std::wstring& ime_path, bool register_ime, bool is_wow64, bool hant, bool silent); int install_ime_file(std::wstring& srcPath, const std::wstring& ext, bool hant, bool silent, ime_register_func func) { - std::wstring destPath; - std::wstring wow64Path; - WCHAR path[MAX_PATH]; - GetModuleFileName(GetModuleHandle(NULL), path, _countof(path)); + GetModuleFileNameW(GetModuleHandle(NULL), path, _countof(path)); - bool is_x64 = (sizeof(HANDLE) == 8); std::wstring srcFileName = (hant ? L"weaselt" : L"weasel"); - srcFileName += (is_x64 ? L"x64" + ext : ext); + srcFileName += ext; WCHAR drive[_MAX_DRIVE]; WCHAR dir[_MAX_DIR]; _wsplitpath_s(path, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0); - srcPath = std::wstring(drive) + dir + L'\\' + srcFileName; + srcPath = std::wstring(drive) + dir + srcFileName; - GetSystemDirectory(path, _countof(path)); - destPath = std::wstring(path) + L"\\weasel" + ext; - - if (GetSystemWow64Directory(path, _countof(path))) - { - wow64Path = std::wstring(path) + L"\\weasel" + ext; - } + GetSystemDirectoryW(path, _countof(path)); + std::wstring destPath = std::wstring(path) + L"\\weasel" + ext; int retval = 0; // 复制 .dll/.ime 到系统目录 if (!copy_file(srcPath, destPath)) { - if (!silent) MessageBox(NULL, destPath.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK); + if (!silent) MessageBoxW(NULL, destPath.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK); return 1; } retval += func(destPath, true, false, hant, silent); - if (!wow64Path.empty()) + if (is_wow64()) { - std::wstring x86 = srcPath; - ireplace_last(x86, L"x64" + ext, ext); - if (!copy_file(x86, wow64Path)) + ireplace_last(srcPath, ext, L"x64" + ext); + PVOID OldValue = NULL; + PW64DW64FR fnWow64DisableWow64FsRedirection = (PW64DW64FR)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "Wow64DisableWow64FsRedirection"); + PW64RW64FR fnWow64RevertWow64FsRedirection = (PW64RW64FR)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "Wow64RevertWow64FsRedirection"); + if (fnWow64DisableWow64FsRedirection == NULL || fnWow64DisableWow64FsRedirection(&OldValue) == FALSE) + { + if (!silent) MessageBoxW(NULL, L"無法取消文件系統重定向", L"安裝失敗", MB_ICONERROR | MB_OK); + return 1; + } + if (!copy_file(srcPath, destPath)) { - if (!silent) MessageBox(NULL, wow64Path.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK); + if (!silent) MessageBoxW(NULL, destPath.c_str(), L"安裝失敗", MB_ICONERROR | MB_OK); return 1; } - retval += func(wow64Path, true, true, hant, silent); + if (fnWow64RevertWow64FsRedirection == NULL || fnWow64RevertWow64FsRedirection(OldValue) == FALSE) + { + if (!silent) MessageBoxW(NULL, L"無法恢復文件系統重定向", L"安裝失敗", MB_ICONERROR | MB_OK); + return 1; + } + retval += func(destPath, true, true, hant, silent); } return retval; } @@ -106,7 +123,7 @@ int uninstall_ime_file(const std::wstring& ext, bool silent, ime_register_func f { int retval = 0; WCHAR path[MAX_PATH]; - GetSystemDirectory(path, _countof(path)); + GetSystemDirectoryW(path, _countof(path)); std::wstring imePath(path); imePath += L"\\weasel" + ext; retval += func(imePath, false, false, false, silent); @@ -115,16 +132,27 @@ int uninstall_ime_file(const std::wstring& ext, bool silent, ime_register_func f if (!silent) MessageBox(NULL, imePath.c_str(), L"卸載失敗", MB_ICONERROR | MB_OK); retval += 1; } - if (GetSystemWow64Directory(path, _countof(path))) + if (is_wow64()) { - std::wstring wow64Path(path); - wow64Path += L"\\weasel" + ext; - retval += func(wow64Path, false, true, false, silent); - if (!delete_file(wow64Path)) + retval += func(imePath, false, true, false, silent); + PVOID OldValue = NULL; + PW64DW64FR fnWow64DisableWow64FsRedirection = (PW64DW64FR)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "Wow64DisableWow64FsRedirection"); + PW64RW64FR fnWow64RevertWow64FsRedirection = (PW64RW64FR)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "Wow64RevertWow64FsRedirection"); + if (fnWow64DisableWow64FsRedirection == NULL || fnWow64DisableWow64FsRedirection(&OldValue) == FALSE) + { + if (!silent) MessageBoxW(NULL, L"無法取消文件系統重定向", L"卸載失敗", MB_ICONERROR | MB_OK); + return 1; + } + if (!delete_file(imePath)) { - if (!silent) MessageBox(NULL, wow64Path.c_str(), L"卸載失敗", MB_ICONERROR | MB_OK); + if (!silent) MessageBoxW(NULL, imePath.c_str(), L"卸載失敗", MB_ICONERROR | MB_OK); retval += 1; } + if (fnWow64RevertWow64FsRedirection == NULL || fnWow64RevertWow64FsRedirection(OldValue) == FALSE) + { + if (!silent) MessageBoxW(NULL, L"無法恢復文件系統重定向", L"卸載失敗", MB_ICONERROR | MB_OK); + return 1; + } } return retval; } @@ -378,7 +406,7 @@ int install(bool hant, bool silent) // 写注册表 HKEY hKey; LSTATUS ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, - 0, NULL, 0, KEY_ALL_ACCESS | KEY_WOW64_32KEY, 0, &hKey, NULL); + 0, NULL, 0, KEY_ALL_ACCESS, 0, &hKey, NULL); if (FAILED(HRESULT_FROM_WIN32(ret))) { if (!silent) MessageBox(NULL, WEASEL_REG_KEY, L"安裝失敗", MB_ICONERROR | MB_OK); @@ -389,6 +417,7 @@ int install(bool hant, bool silent) WCHAR dir[_MAX_DIR]; _wsplitpath_s(ime_src_path.c_str(), drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0); std::wstring rootDir = std::wstring(drive) + dir; + rootDir.pop_back(); ret = RegSetValueEx(hKey, L"WeaselRoot", 0, REG_SZ, (const BYTE*)rootDir.c_str(), (rootDir.length() + 1) * sizeof(WCHAR)); diff --git a/output/install.nsi b/output/install.nsi index 942c4b630..4f5d92c8e 100644 --- a/output/install.nsi +++ b/output/install.nsi @@ -140,11 +140,7 @@ program_files: ${EndIf} File "WeaselDeployer.exe" File "WeaselServer.exe" - ${If} ${RunningX64} - File "WeaselSetupx64.exe" - ${Else} - File "WeaselSetup.exe" - ${EndIf} + File "WeaselSetup.exe" File "rime.dll" File "WinSparkle.dll" ; shared data files @@ -176,11 +172,7 @@ program_files: IfErrors +2 0 StrCpy $R2 "/t" - ${If} ${RunningX64} - ExecWait '"$INSTDIR\WeaselSetupx64.exe" $R2' - ${Else} - ExecWait '"$INSTDIR\WeaselSetup.exe" $R2' - ${EndIf} + ExecWait '"$INSTDIR\WeaselSetup.exe" $R2' ; run as user... ExecWait "$INSTDIR\WeaselDeployer.exe /install" @@ -216,11 +208,7 @@ Section "Start Menu Shortcuts" CreateShortCut "$SMPROGRAMS\小狼毫輸入法\【小狼毫】用戶文件夾.lnk" "$INSTDIR\WeaselServer.exe" "/userdir" "$SYSDIR\shell32.dll" 126 CreateShortCut "$SMPROGRAMS\小狼毫輸入法\【小狼毫】程序文件夾.lnk" "$INSTDIR\WeaselServer.exe" "/weaseldir" "$SYSDIR\shell32.dll" 19 CreateShortCut "$SMPROGRAMS\小狼毫輸入法\【小狼毫】檢查新版本.lnk" "$INSTDIR\WeaselServer.exe" "/update" "$SYSDIR\shell32.dll" 13 - ${If} ${RunningX64} - CreateShortCut "$SMPROGRAMS\小狼毫輸入法\【小狼毫】安裝選項.lnk" "$INSTDIR\WeaselSetupx64.exe" "" "$SYSDIR\shell32.dll" 162 - ${Else} - CreateShortCut "$SMPROGRAMS\小狼毫輸入法\【小狼毫】安裝選項.lnk" "$INSTDIR\WeaselSetup.exe" "" "$SYSDIR\shell32.dll" 162 - ${EndIf} + CreateShortCut "$SMPROGRAMS\小狼毫輸入法\【小狼毫】安裝選項.lnk" "$INSTDIR\WeaselSetup.exe" "" "$SYSDIR\shell32.dll" 162 CreateShortCut "$SMPROGRAMS\小狼毫輸入法\卸載小狼毫.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 SectionEnd @@ -233,11 +221,7 @@ Section "Uninstall" ExecWait '"$INSTDIR\WeaselServer.exe" /quit' - ${If} ${RunningX64} - ExecWait '"$INSTDIR\WeaselSetupx64.exe" /u' - ${Else} - ExecWait '"$INSTDIR\WeaselSetup.exe" /u' - ${EndIf} + ExecWait '"$INSTDIR\WeaselSetup.exe" /u' ; Remove registry keys DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Weasel" diff --git a/weasel.sln b/weasel.sln index 4b8fc220c..293412470 100644 --- a/weasel.sln +++ b/weasel.sln @@ -167,12 +167,10 @@ Global {F53F3E9C-CC4D-4D1D-9C2E-719FE60A7E6B}.ReleaseHant|x64.ActiveCfg = Release|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Debug|Win32.ActiveCfg = Debug|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Debug|Win32.Build.0 = Debug|Win32 - {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Debug|x64.ActiveCfg = Debug|x64 - {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Debug|x64.Build.0 = Debug|x64 + {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Debug|x64.ActiveCfg = Debug|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Release|Win32.ActiveCfg = Release|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Release|Win32.Build.0 = Release|Win32 - {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Release|x64.ActiveCfg = Release|x64 - {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Release|x64.Build.0 = Release|x64 + {04B795DB-A22B-4657-9350-29F04B8FB8F6}.Release|x64.ActiveCfg = Release|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.ReleaseHant|Win32.ActiveCfg = Release|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.ReleaseHant|Win32.Build.0 = Release|Win32 {04B795DB-A22B-4657-9350-29F04B8FB8F6}.ReleaseHant|x64.ActiveCfg = Release|Win32