diff options
| author | a1xd <[email protected]> | 2021-02-26 21:50:35 -0500 |
|---|---|---|
| committer | a1xd <[email protected]> | 2021-09-23 22:36:19 -0400 |
| commit | 41d73f257a58905f273fce3195cb4c0f3cd5c165 (patch) | |
| tree | 33ed86b2257878a4102dc15b86e25875e13b172f | |
| parent | bump version, target win10 (diff) | |
| download | rawaccel-41d73f257a58905f273fce3195cb4c0f3cd5c165.tar.xz rawaccel-41d73f257a58905f273fce3195cb4c0f3cd5c165.zip | |
improve installer
use standard syntax for service binpath
throw if copy_file fails
| -rw-r--r-- | common/utility-install.hpp | 23 | ||||
| -rw-r--r-- | installer/installer.cpp | 85 | ||||
| -rw-r--r-- | signed/installer.exe | bin | 62264 -> 61752 bytes | |||
| -rw-r--r-- | signed/uninstaller.exe | bin | 57656 -> 54584 bytes | |||
| -rw-r--r-- | uninstaller/uninstaller.cpp | 20 |
5 files changed, 76 insertions, 52 deletions
diff --git a/common/utility-install.hpp b/common/utility-install.hpp index e1823e4..55ae9d6 100644 --- a/common/utility-install.hpp +++ b/common/utility-install.hpp @@ -10,25 +10,24 @@ namespace wr = winreg; inline const std::wstring DRIVER_NAME = L"rawaccel"; inline const std::wstring DRIVER_FILE_NAME = DRIVER_NAME + L".sys"; +inline const std::wstring DRIVER_ENV_PATH = L"%systemroot%\\system32\\drivers\\" + DRIVER_FILE_NAME; -fs::path get_sys_path() { - std::wstring path; - path.resize(MAX_PATH); +inline const auto sys_error = [](auto what, DWORD code = GetLastError()) { + return std::system_error(code, std::system_category(), what); +}; - UINT chars_copied = GetSystemDirectoryW(path.data(), MAX_PATH); - if (chars_copied == 0) throw std::runtime_error("GetSystemDirectory failed"); +inline std::wstring expand(const std::wstring& env_path) { + std::wstring path(MAX_PATH, L'\0'); - path.resize(chars_copied); + auto len = ExpandEnvironmentStringsW(env_path.c_str(), &path[0], MAX_PATH); + if (len == 0) throw sys_error("ExpandEnvironmentStrings failed"); + path.resize(len - 1); return path; } -fs::path get_target_path() { - return get_sys_path() / L"drivers" / DRIVER_FILE_NAME; -} - -fs::path make_temp_path(const fs::path& p) { +inline fs::path make_temp_path(const fs::path& p) { auto tmp_path = p; - tmp_path.concat(".tmp"); + tmp_path.concat(L".tmp"); return tmp_path; } diff --git a/installer/installer.cpp b/installer/installer.cpp index cf5a43a..27c9414 100644 --- a/installer/installer.cpp +++ b/installer/installer.cpp @@ -3,24 +3,16 @@ #include <utility-install.hpp> #include <VersionHelpers.h> -void add_service(const fs::path& target) { - SC_HANDLE schSCManager = OpenSCManager( - NULL, // local computer - NULL, // ServicesActive database - SC_MANAGER_ALL_ACCESS // full access rights - ); - - if (schSCManager == NULL) throw std::runtime_error("OpenSCManager failed"); - - SC_HANDLE schService = CreateService( - schSCManager, // SCM database +void add_service(SC_HANDLE srv_manager) { + SC_HANDLE srv = CreateServiceW( + srv_manager, // SCM database DRIVER_NAME.c_str(), // name of service DRIVER_NAME.c_str(), // service name to display SERVICE_ALL_ACCESS, // desired access SERVICE_KERNEL_DRIVER, // service type SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type - target.c_str(), // path to service's binary + DRIVER_ENV_PATH.c_str(), // path to service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies @@ -28,45 +20,76 @@ void add_service(const fs::path& target) { NULL // no password ); - if (schService) { - CloseServiceHandle(schService); - CloseServiceHandle(schSCManager); - return; - } + if (srv) CloseServiceHandle(srv); + else throw sys_error("CreateService failed"); +} - if (auto err = GetLastError(); err != ERROR_SERVICE_EXISTS) { - CloseServiceHandle(schSCManager); - throw std::runtime_error("CreateService failed"); - } +BOOL update_service(SC_HANDLE srv) { + return ChangeServiceConfigW( + srv, // service handle + SERVICE_KERNEL_DRIVER, // service type + SERVICE_DEMAND_START, // start type + SERVICE_ERROR_NORMAL, // error control type + DRIVER_ENV_PATH.c_str(), // path to service's binary + NULL, // no load ordering group + NULL, // no tag identifier + NULL, // no dependencies + NULL, // LocalSystem account + NULL, // no password + DRIVER_NAME.c_str() // service name to display + ); } int main() { + SC_HANDLE srv_manager = NULL; + try { if (!IsWindows10OrGreater()) { throw std::runtime_error("OS not supported, you need at least Windows 10"); } + fs::path source = fs::path(L"driver") / DRIVER_FILE_NAME; if (!fs::exists(source)) { throw std::runtime_error(source.generic_string() + " does not exist"); } - fs::path target = get_target_path(); - + fs::path target = expand(DRIVER_ENV_PATH); + if (fs::exists(target)) { std::cout << "Driver already installed. Removing previous installation.\n"; - } - add_service(target); + fs::path tmp = make_temp_path(target); - fs::path tmp = make_temp_path(target); + // schedule tmp to be deleted if rename target -> tmp is successful + if (MoveFileExW(target.c_str(), tmp.c_str(), MOVEFILE_REPLACE_EXISTING)) { + MoveFileExW(tmp.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + } + } - // schedule tmp to be deleted if rename target -> tmp is successful - if (MoveFileExW(target.c_str(), tmp.c_str(), MOVEFILE_REPLACE_EXISTING)) { - MoveFileExW(tmp.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + if (!fs::copy_file(source, target, fs::copy_options::overwrite_existing)) { + throw sys_error("copy_file failed"); } - fs::copy_file(source, target, fs::copy_options::overwrite_existing); + srv_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (srv_manager == NULL) throw sys_error("OpenSCManager failed"); + + SC_HANDLE srv = OpenServiceW(srv_manager, DRIVER_NAME.c_str(), SC_MANAGER_ALL_ACCESS); + + if (srv != NULL) { + BOOL success = update_service(srv); + CloseServiceHandle(srv); + if (!success) throw sys_error("ChangeServiceConfig failed"); + } + else { + auto error_code = GetLastError(); + if (error_code == ERROR_SERVICE_DOES_NOT_EXIST) { + add_service(srv_manager); + } + else { + throw sys_error("OpenService failed", error_code); + } + } modify_upper_filters([](std::vector<std::wstring>& filters) { auto driver_pos = std::find(filters.begin(), filters.end(), DRIVER_NAME); @@ -86,6 +109,8 @@ int main() { std::cerr << "Error: " << e.what() << '\n'; } + if (srv_manager) CloseServiceHandle(srv_manager); + std::cout << "Press any key to close this window . . .\n"; _getwch(); } diff --git a/signed/installer.exe b/signed/installer.exe Binary files differindex 37a6291..321350b 100644 --- a/signed/installer.exe +++ b/signed/installer.exe diff --git a/signed/uninstaller.exe b/signed/uninstaller.exe Binary files differindex 13bc55c..4dd8788 100644 --- a/signed/uninstaller.exe +++ b/signed/uninstaller.exe diff --git a/uninstaller/uninstaller.cpp b/uninstaller/uninstaller.cpp index bd9c564..3434cb7 100644 --- a/uninstaller/uninstaller.cpp +++ b/uninstaller/uninstaller.cpp @@ -14,22 +14,22 @@ int main() { } }); - fs::path target = get_target_path(); + fs::path target = expand(DRIVER_ENV_PATH); fs::path tmp = make_temp_path(target); - if (fs::exists(target) || fs::exists(tmp)) { + if (fs::exists(target)) { reboot_required = true; - } - // schedule tmp to be deleted if rename target -> tmp is successful - if (MoveFileExW(target.c_str(), tmp.c_str(), MOVEFILE_REPLACE_EXISTING)) { - MoveFileExW(tmp.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); - } - else { // tmp is in use and delete is already scheduled - if (fs::exists(target)) fs::remove(target); + // schedule tmp to be deleted if rename target -> tmp is successful + if (MoveFileExW(target.c_str(), tmp.c_str(), MOVEFILE_REPLACE_EXISTING)) { + MoveFileExW(tmp.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + } + else { // tmp is in use and delete is already scheduled + fs::remove(target); + } } - if (reboot_required) { + if (reboot_required || fs::exists(tmp)) { std::cout << "Removal complete, change will take effect after restart.\n"; } else { |