
BOOL Kmd_Install_Service(
const wchar_t *Service_Name,
const wchar_t *Service_Path,
const wchar_t *Service_Display,
const wchar_t *Service_Group,
OPTIONS Options)
{
SC_HANDLE service;
// convert options into specific flags
DWORD ServiceType;
DWORD StartType;
if (Options & OPT_KERNEL_TYPE)
ServiceType = SERVICE_KERNEL_DRIVER;
else
ServiceType = SERVICE_WIN32_OWN_PROCESS;
if (Options & OPT_SYSTEM_START)
StartType = SERVICE_SYSTEM_START;
else if (Options & OPT_AUTO_START)
StartType = SERVICE_AUTO_START;
else
StartType = SERVICE_DEMAND_START;
// create a service for the driver
if (! Service_Display)
Service_Display = Service_Name;
service = CreateService(
ScMgr,
Service_Name, Service_Display,
SERVICE_ALL_ACCESS,
ServiceType,
StartType,
SERVICE_ERROR_NORMAL,
Service_Path,
Service_Group,
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL);
if (! service) {
if (GetLastError() != ERROR_SERVICE_EXISTS) {
Display_Error(L"CreateService", 0);
return FALSE;
}
}
return TRUE;
}
BOOL Kmd_Start_Service(
const wchar_t *Driver_Name)
{
SC_HANDLE service;
SERVICE_STATUS service_status;
// try to open the service for the driver
service = OpenService(
ScMgr, Driver_Name,
SERVICE_INTERROGATE | SERVICE_START);
if (! service) {
Display_Error(L"OpenService", 0);
return FALSE;
}
// stop the service
if (! ControlService(
service,
SERVICE_CONTROL_INTERROGATE, &service_status)) {
if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE)
service_status.dwCurrentState = SERVICE_STOPPED;
else {
Display_Error(L"ControlService Interrogate", 0);
return FALSE;
}
}
if (service_status.dwCurrentState == SERVICE_STOPPED) {
if (! StartService(service, 0, NULL)) {
Display_Error(L"ControlService Start", 0);
return FALSE;
}
}
return TRUE;
}
BOOL Kmd_Stop_Service(
const wchar_t *Driver_Name)
{
extern BOOLEAN Kmd_Stop_SbieDrv(void);
SC_HANDLE service;
SERVICE_STATUS service_status;
ULONG retries;
if (_wcsicmp(Driver_Name, SBIEDRV) == 0) {
// stop the driver
if (! Kmd_Stop_SbieDrv())
return FALSE;
// fallback to stopping through SCM, otherwise the
// driver registry key does not always disappear
}
// try to open the service for the driver
service = OpenService(
ScMgr, Driver_Name,
SERVICE_INTERROGATE | SERVICE_STOP);
if (! service) {
if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
return TRUE;
Display_Error(L"OpenService", 0);
return FALSE;
}
//
// stop the service if it's active
//
for (retries = 0; ; ++retries) {
if (retries) {
WCHAR Text[384];
wcscpy(Text, SbieDll_FormatMessage1(8102, Driver_Name));
wcscat(Text, L"\n\n");
wcscat(Text, SbieDll_FormatMessage0(8102 + retries));
MessageBox(NULL, Text, L"KmdUtil", MB_ICONEXCLAMATION | MB_OK);
}
if (! ControlService(
service,
SERVICE_CONTROL_INTERROGATE, &service_status)) {
if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE)
return TRUE;
if ((GetLastError() == ERROR_SERVICE_REQUEST_TIMEOUT ||
GetLastError() == ERROR_PIPE_BUSY) && retries < 5) {
Sleep(2500);
continue;
}
Display_Error(L"ControlService Interrogate", 0);
return FALSE;
}
if (service_status.dwCurrentState != SERVICE_STOPPED) {
if (! ControlService(
service,
SERVICE_CONTROL_STOP, &service_status)) {
if ((GetLastError() == ERROR_SERVICE_REQUEST_TIMEOUT ||
GetLastError() == ERROR_PIPE_BUSY) && retries < 5) {
Sleep(2500);
continue;
}
Display_Error(L"ControlService Stop", 0);
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
BOOL Kmd_Delete_Service(
const wchar_t *Driver_Name)
{
SC_HANDLE service;
// try to open the service for the driver
service = OpenService(
ScMgr, Driver_Name, SERVICE_INTERROGATE | DELETE);
if (! service) {
if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
return TRUE;
Display_Error(L"OpenService", 0);
return FALSE;
}
// if the service opened successfully, we must delete it
if (! DeleteService(service)) {
if (GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) {
Display_Error(L"DeleteService", 0);
return FALSE;
}
}
return TRUE;
}
void RestartService(SC_HANDLE hScm, WCHAR *wszServiceName)
{
SC_HANDLE hService;
BOOL res;
hService = OpenService(hScm, wszServiceName, SERVICE_ALL_ACCESS);
res = GetLastError();
if (hService != NULL)
{
SERVICE_STATUS stServiceStatus;
res = ControlService(hService, SERVICE_CONTROL_STOP, &stServiceStatus);
res = StartServiceW(hService, 0, NULL);
CloseServiceHandle(hService);
}
}
SC_HANDLE handle1 = OpenSCManager(NULL, NULL, GENERIC_READ);
if (! handle1)
status = GetLastError();
else {
SC_HANDLE handle2 = OpenService(handle1, req->name, SERVICE_START);
if (! handle2)
status = GetLastError();
else {
if (! StartService(handle2, 0, NULL))
status = GetLastError();
CloseServiceHandle(handle2);
}
CloseServiceHandle(handle1);
}
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);