summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/utility-install.hpp23
-rw-r--r--installer/installer.cpp85
-rw-r--r--signed/installer.exebin62264 -> 61752 bytes
-rw-r--r--signed/uninstaller.exebin57656 -> 54584 bytes
-rw-r--r--uninstaller/uninstaller.cpp20
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
index 37a6291..321350b 100644
--- a/signed/installer.exe
+++ b/signed/installer.exe
Binary files differ
diff --git a/signed/uninstaller.exe b/signed/uninstaller.exe
index 13bc55c..4dd8788 100644
--- a/signed/uninstaller.exe
+++ b/signed/uninstaller.exe
Binary files differ
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 {