mirror of
https://gitea.tendokyu.moe/moegrid/sega-mount.git
synced 2026-10-01 11:07:56 +03:00
首次提交
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#define LOG_MODULE "DRIVER"
|
||||
#include "driver_service.h"
|
||||
#include "utils/files.h"
|
||||
#include "utils/strings.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
namespace driver {
|
||||
bool ensure_running(std::string *error) {
|
||||
SC_HANDLE hScm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
||||
if (!hScm) {
|
||||
if (error) *error = "OpenSCManager failed: " + std::to_string(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to open existing service
|
||||
SC_HANDLE hSvc = OpenServiceW(hScm, SERVICE_NAME,
|
||||
SERVICE_ALL_ACCESS);
|
||||
|
||||
if (!hSvc) {
|
||||
DWORD last = GetLastError();
|
||||
if (last != ERROR_SERVICE_DOES_NOT_EXIST) {
|
||||
if (error) *error = "OpenService failed: " + std::to_string(last);
|
||||
CloseServiceHandle(hScm);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Service does not exist - create it
|
||||
std::wstring driver_path = utils::get_exe_dir() + L"\\" + DRIVER_FILENAME;
|
||||
hSvc = CreateServiceW(
|
||||
hScm, SERVICE_NAME, SERVICE_NAME,
|
||||
SERVICE_ALL_ACCESS,
|
||||
SERVICE_KERNEL_DRIVER,
|
||||
SERVICE_DEMAND_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
driver_path.c_str(),
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
if (!hSvc) {
|
||||
if (error) *error = "CreateService failed: " + std::to_string(GetLastError());
|
||||
CloseServiceHandle(hScm);
|
||||
return false;
|
||||
}
|
||||
LOG_INFO("Service installed: {}", utils::wstr_to_str(driver_path));
|
||||
}
|
||||
|
||||
// Query current state
|
||||
SERVICE_STATUS status{};
|
||||
if (!QueryServiceStatus(hSvc, &status)) {
|
||||
if (error) *error = "QueryServiceStatus failed: " + std::to_string(GetLastError());
|
||||
CloseServiceHandle(hSvc);
|
||||
CloseServiceHandle(hScm);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
CloseServiceHandle(hSvc);
|
||||
CloseServiceHandle(hScm);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start the service
|
||||
if (!StartServiceW(hSvc, 0, nullptr)) {
|
||||
DWORD last = GetLastError();
|
||||
if (last != ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
if (error) *error = "StartService failed: " + std::to_string(last);
|
||||
CloseServiceHandle(hSvc);
|
||||
CloseServiceHandle(hScm);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for it to actually enter RUNNING state
|
||||
int tries = 30;
|
||||
while (tries-- > 0) {
|
||||
if (!QueryServiceStatus(hSvc, &status)) break;
|
||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
LOG_INFO("Service started");
|
||||
CloseServiceHandle(hSvc);
|
||||
CloseServiceHandle(hScm);
|
||||
return true;
|
||||
}
|
||||
if (status.dwCurrentState == SERVICE_STOPPED) break;
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
if (status.dwCurrentState != SERVICE_RUNNING) {
|
||||
if (error) *error = "Service failed to reach RUNNING state";
|
||||
CloseServiceHandle(hSvc);
|
||||
CloseServiceHandle(hScm);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Service started");
|
||||
CloseServiceHandle(hSvc);
|
||||
CloseServiceHandle(hScm);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user