Skip to content

Commit

Permalink
feat: WeaselSetup.exe parameters for enable/disable update checking a…
Browse files Browse the repository at this point in the history
…utomatically, /eu to enable, /du to disable

refactor: template to write REG_SZ or REG_DWORD
  • Loading branch information
fxliang committed Jun 19, 2024
1 parent cc8fd06 commit 63ff96b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 110 deletions.
36 changes: 36 additions & 0 deletions WeaselSetup/InstallOptionsDlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,42 @@
MSG_ID_CAP(info, idCap, uType); \
}

template <typename T>
LSTATUS SetRegKeyValue(HKEY rootKey,
const wchar_t* subpath,
const wchar_t* key,
const T& value,
DWORD type,
bool disable_reg_redirect = false) {
HKEY hKey;
auto flag_wow64 = (disable_reg_redirect && is_wow64()) ? KEY_WOW64_64KEY : 0;
LSTATUS ret =
RegOpenKeyEx(rootKey, subpath, 0, KEY_ALL_ACCESS | flag_wow64, &hKey);
if (ret != ERROR_SUCCESS) {
ret = RegCreateKeyEx(rootKey, subpath, 0, NULL, 0,
KEY_ALL_ACCESS | flag_wow64, 0, &hKey, NULL);
if (ret != ERROR_SUCCESS)
return ret;
}
if (ret == ERROR_SUCCESS) {
DWORD dataSize;
const BYTE* dataPtr;
if constexpr (std::is_same<T, std::wstring>::value) {
dataSize = (value.size() + 1) * sizeof(wchar_t);
dataPtr = reinterpret_cast<const BYTE*>(value.c_str());
} else if constexpr (std::is_same<T, const wchar_t*>::value) {
dataSize = (wcslen((wchar_t*)value) + 1) * sizeof(wchar_t);
dataPtr = reinterpret_cast<const BYTE*>(value);
} else {
dataSize = sizeof(T);
dataPtr = reinterpret_cast<const BYTE*>(&value);
}
ret = RegSetValueEx(hKey, key, 0, type, dataPtr, dataSize);
RegCloseKey(hKey);
}
return ret;
}

class InstallOptionsDialog : public CDialogImpl<InstallOptionsDialog> {
public:
enum { IDD = IDD_INSTALL_OPTIONS };
Expand Down
48 changes: 19 additions & 29 deletions WeaselSetup/WeaselSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,25 +100,15 @@ static int CustomInstall(bool installing) {
if (0 != install(hant, silent, old_ime_support))
return 1;

ret = RegCreateKeyEx(HKEY_CURRENT_USER, KEY, 0, NULL, 0, KEY_ALL_ACCESS, 0,
&hKey, NULL);
if (FAILED(HRESULT_FROM_WIN32(ret))) {
MSG_ID_CAP(KEY, IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}

ret = RegSetValueEx(hKey, L"RimeUserDir", 0, REG_SZ,
(const BYTE*)user_dir.c_str(),
(user_dir.length() + 1) * sizeof(WCHAR));
ret = SetRegKeyValue(HKEY_CURRENT_USER, KEY, L"RimeUserDir", user_dir.c_str(),
REG_SZ, false);
if (FAILED(HRESULT_FROM_WIN32(ret))) {
MSG_BY_IDS(IDS_STR_ERR_WRITE_USER_DIR, IDS_STR_INSTALL_FAILED,
MB_ICONERROR | MB_OK);
return 1;
}

DWORD data = hant ? 1 : 0;
ret = RegSetValueEx(hKey, L"Hant", 0, REG_DWORD, (const BYTE*)&data,
sizeof(DWORD));
ret = SetRegKeyValue(HKEY_CURRENT_USER, KEY, L"Hant", (hant ? 1 : 0),
REG_DWORD, false);
if (FAILED(HRESULT_FROM_WIN32(ret))) {
MSG_BY_IDS(IDS_STR_ERR_WRITE_HANT, IDS_STR_INSTALL_FAILED,
MB_ICONERROR | MB_OK);
Expand Down Expand Up @@ -151,24 +141,24 @@ static int Run(LPTSTR lpCmdLine) {
if (uninstalling)
return uninstall(silent);

auto setLanguage = [](const wchar_t* language) {
const WCHAR KEY[] = L"Software\\Rime\\Weasel";
HKEY hKey;
LSTATUS ret = RegOpenKey(HKEY_CURRENT_USER, KEY, &hKey);
if (ret == ERROR_SUCCESS) {
ret = RegSetValueEx(hKey, L"Language", 0, REG_SZ, (const BYTE*)language,
(wcslen(language) + 1) * sizeof(wchar_t));
RegCloseKey(hKey);
}
return ret;
};

if (!wcscmp(L"/ls", lpCmdLine)) {
return setLanguage(L"chs");
return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel",
L"Language", L"chs", REG_SZ);
} else if (!wcscmp(L"/lt", lpCmdLine)) {
return setLanguage(L"cht");
return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel",
L"Language", L"cht", REG_SZ);
} else if (!wcscmp(L"/le", lpCmdLine)) {
return setLanguage(L"eng");
return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel",
L"Language", L"eng", REG_SZ);
}

if (!wcscmp(L"/eu", lpCmdLine)) {
return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel\\Updates",
L"CheckForUpdates", L"1", REG_SZ);
}
if (!wcscmp(L"/du", lpCmdLine)) {
return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel\\Updates",
L"CheckForUpdates", L"0", REG_SZ);
}

bool hans = !wcscmp(L"/s", lpCmdLine);
Expand Down
105 changes: 24 additions & 81 deletions WeaselSetup/imesetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ static const GUID c_guidProfile = {
#define ILOT_UNINSTALL 0x00000001
typedef HRESULT(WINAPI* PTF_INSTALLLAYOUTORTIP)(LPCWSTR psz, DWORD dwFlags);

#define WEASEL_WER_KEY \
L"SOFTWARE\\Microsoft\\Windows\\Windows Error " \
L"Reporting\\LocalDumps\\WeaselServer.exe"

BOOL copy_file(const std::wstring& src, const std::wstring& dest) {
BOOL ret = CopyFile(src.c_str(), dest.c_str(), FALSE);
if (!ret) {
Expand Down Expand Up @@ -539,11 +543,6 @@ int register_text_service(const std::wstring& tsf_path,
return 0;
}

void executeCommandA(const std::string& command) {
ShellExecuteA(NULL, "open", "cmd.exe", ("/C " + command).c_str(), NULL,
SW_HIDE);
}

int install(bool hant, bool silent, bool old_ime_support) {
std::wstring ime_src_path;
int retval = 0;
Expand All @@ -555,41 +554,29 @@ int install(bool hant, bool silent, bool old_ime_support) {
&register_text_service);

// 写注册表
HKEY hKey;
LSTATUS ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, 0, NULL, 0,
KEY_ALL_ACCESS, 0, &hKey, NULL);
if (FAILED(HRESULT_FROM_WIN32(ret))) {
MSG_NOT_SILENT_ID_CAP(silent, WEASEL_REG_KEY, IDS_STR_INSTALL_FAILED,
MB_ICONERROR | MB_OK);
return 1;
}

WCHAR drive[_MAX_DRIVE];
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));
auto ret = SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, L"WeaselRoot",
rootDir.c_str(), REG_SZ);
if (FAILED(HRESULT_FROM_WIN32(ret))) {
MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRWRITEWEASELROOT,
IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}

const std::wstring executable = L"WeaselServer.exe";
ret = RegSetValueEx(hKey, L"ServerExecutable", 0, REG_SZ,
(const BYTE*)executable.c_str(),
(executable.length() + 1) * sizeof(WCHAR));
ret = SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, L"ServerExecutable",
executable.c_str(), REG_SZ);
if (FAILED(HRESULT_FROM_WIN32(ret))) {
MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRREGIMEWRITESVREXE,
IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}

RegCloseKey(hKey);
// InstallLayoutOrTip
// https://learn.microsoft.com/zh-cn/windows/win32/tsf/installlayoutortip
// example in ref page not right with "*PTF_ INSTALLLAYOUTORTIP"
Expand All @@ -608,50 +595,20 @@ int install(bool hant, bool silent, bool old_ime_support) {
FreeLibrary(hInputDLL);
}

// write WER register
if (is_wow64()) {
PVOID OldValue = NULL;
if (Wow64DisableWow64FsRedirection(&OldValue) == FALSE) {
MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRCANCELFSREDIRECT,
IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}
}
// https://learn.microsoft.com/zh-cn/windows/win32/wer/collecting-user-mode-dumps
const std::string dmpPath = WeaselLogPath().string();
executeCommandA(
"REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows "
"Error Reporting\\LocalDumps\\WeaselServer.exe\" /f");
// dump file path
executeCommandA(
"REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows "
"Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_SZ /v DumpFolder "
"/d " +
dmpPath + " /f");
const std::wstring dmpPathW = WeaselLogPath().wstring();
// DumpFolder
SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpFolder",
dmpPathW.c_str(), REG_SZ, true);
// dump type 0
executeCommandA(
"REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows "
"Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_DWORD /v "
"DumpType /d 0 /f");
SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpType", 0, REG_DWORD,
true);
// CustomDumpFlags, MiniDumpNormal
executeCommandA(
"REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows "
"Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_DWORD /v "
"CustomDumpFlags /d 0 /f");
SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"CustomDumpFlags", 0,
REG_DWORD, true);
// maximium dump count 10
executeCommandA(
"REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows "
"Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_DWORD /v "
"DumpCount /d 10 /f");

if (is_wow64()) {
PVOID OldValue = NULL;
if (Wow64RevertWow64FsRedirection(&OldValue) == FALSE) {
MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRRECOVERFSREDIRECT,
IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}
}
SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpCount", 10,
REG_DWORD, true);

if (retval)
return 1;
Expand Down Expand Up @@ -699,26 +656,12 @@ int uninstall(bool silent) {
RegDeleteKey(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY);
RegDeleteKey(HKEY_LOCAL_MACHINE, RIME_REG_KEY);

// delete WER register
if (is_wow64()) {
PVOID OldValue = NULL;
if (Wow64DisableWow64FsRedirection(&OldValue) == FALSE) {
MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRCANCELFSREDIRECT,
IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}
}
executeCommandA(
"REG DELETE \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows "
"Error Reporting\\LocalDumps\\WeaselServer.exe\" /f");
if (is_wow64()) {
PVOID OldValue = NULL;
if (Wow64RevertWow64FsRedirection(&OldValue) == FALSE) {
MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRRECOVERFSREDIRECT,
IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK);
return 1;
}
}
// delete WER register,
// "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows Error
// Reporting\\LocalDumps\\WeaselServer.exe" no WOW64 redirect

auto flag_wow64 = is_wow64() ? KEY_WOW64_64KEY : 0;
RegDeleteKeyEx(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, flag_wow64, 0);
if (retval)
return 1;

Expand Down

0 comments on commit 63ff96b

Please sign in to comment.