Windows NT Services and Drivers
Я немного доработал примеры по работе с сервисами и драйверами в NT через Win32 API
(новый код взят из
DbgDump).
Предыдущая версия лежит здесь
Собственно примеры кода:
Более подробно об использованых системных вызовах читайте в MSDN или
в Winsvc.h от MSVC 6.0
В принципе, я планирую оформить это дело в виде open-source библиотеки.
Для тех кому интересно - есть еще консольная утилита для установки драйверов от
фирмы Microsoft - drvinst. Я ее слегка подточил напильником, скомпилировл и выложил вместе с VC6 project'ом.
В будущем собираюсь сделать из нее полноценный инструмент для управления установкой драйверами и сервисами.
UINT
NtServiceIsRunning(
LPCTSTR ServiceName
)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
DWORD RC;
SERVICE_STATUS ssStatus;
UINT return_value;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) return -1;
schService = OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if (!schService) {
RC = GetLastError();
CloseServiceHandle(schSCManager);
if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return -2;
else return -1;
}
QueryServiceStatus(schService, &ssStatus);
if(ssStatus.dwCurrentState == SERVICE_RUNNING) return_value = 1;
else return_value = 0;
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return return_value;
}
UINT
NtServiceStart(
LPCTSTR ServiceName
)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
DWORD RC;
UINT return_value;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) return -1;
schService = OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if (!schService) {
RC = GetLastError();
CloseServiceHandle(schSCManager);
if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return -2;
else return -1;
}
return_value = StartService(schService, 0, NULL) ? 1 : -1;
RC = GetLastError();
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return return_value;
}
UINT
NtServiceStop(
LPCTSTR ServiceName,
ULONG TimeoutSeconds
)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
DWORD RC;
UINT return_value;
SERVICE_STATUS SrvStatus;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) return -1;
schService = OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if (!schService) {
RC = GetLastError();
CloseServiceHandle(schSCManager);
if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return -2;
else return -1;
}
return_value = ControlService(schService, SERVICE_CONTROL_STOP, &SrvStatus) ? 1 : -1;
if(return_value) {
while(QueryServiceStatus(schService, &SrvStatus)) {
if ( SrvStatus.dwCurrentState == SERVICE_STOP_PENDING ) {
if(!TimeoutSeconds)
break;
if(TimeoutSeconds != -1)
TimeoutSeconds--;
Sleep( 1000 );
} else {
break;
}
}
if(SrvStatus.dwCurrentState == SERVICE_STOPPED) {
return_value = 1;
} else {
return_value = -1;
}
} else {
return_value = -2;
}
RC = GetLastError();
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return return_value;
}
UINT
NtServiceInstall(
LPCTSTR ServiceName,
PCHAR PathToExecutable,
BOOLEAN KernelDriver,
ULONG StartType,
PCHAR Dependencies
)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
DWORD RC;
UINT return_value = 0;
CHAR path_name1[MAX_PATH];
CHAR path_name[MAX_PATH];
CHAR sys_path_name[MAX_PATH];
CHAR drv_path_name[MAX_PATH];
GetSystemDirectory(sys_path_name, MAX_PATH-40);
if(KernelDriver) {
_snprintf(path_name, MAX_PATH-1, "%s\\drivers\\%s.sys", sys_path_name, ServiceName);
_snprintf(path_name1, MAX_PATH-1, "%s\\%s.sys", PathToExecutable, ServiceName);
_snprintf(drv_path_name, MAX_PATH-1, "System32\\drivers\\%s.sys", ServiceName);
} else {
_snprintf(path_name, MAX_PATH-1, "%s\\%s.exe", sys_path_name, ServiceName);
_snprintf(path_name1, MAX_PATH-1, "%s\\%s.exe", PathToExecutable, ServiceName);
_snprintf(drv_path_name, MAX_PATH-1, "System32\\%s.exe", ServiceName);
}
return_value = CopyFile(path_name1, path_name, 0);
if(!return_value) {
return_value = GetLastError();
printf("Can't copy %s to %s\nerror code %#x\n", path_name1, path_name, return_value);
return -1;
}
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) return -1;
schService = CreateService(schSCManager, ServiceName, ServiceName, SERVICE_ALL_ACCESS,
KernelDriver ? SERVICE_KERNEL_DRIVER : SERVICE_WIN32_OWN_PROCESS,
StartType, SERVICE_ERROR_IGNORE,
drv_path_name, NULL, NULL, Dependencies, NULL, NULL);
if (!schService) {
RC = GetLastError();
CloseServiceHandle(schSCManager);
if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return -2;
else return -1;
} else {
return_value = 1;
}
// return_value = StartService(schService, 0, NULL) ? 1 : -1;
RC = GetLastError();
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return return_value;
}
UINT
NtServiceRemove(
LPCTSTR ServiceName
)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
DWORD RC;
UINT return_value;
// SERVICE_STATUS SrvStatus;
/*
It is unsafe to do this:
return_value = NtServiceStop(ServiceName);
if(return_value != 1) {
return return_value;
}
*/
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) return -1;
schService = OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if (!schService) {
RC = GetLastError();
CloseServiceHandle(schSCManager);
if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return -2;
else return -1;
}
return_value = DeleteService(schService) ? 1 : -1;
RC = GetLastError();
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return return_value;
}
UINT
NtServiceSetStartMode(
LPCTSTR ServiceName,
ULONG StartMode
)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
DWORD RC;
UINT return_value;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager) return -1;
schService = OpenService(schSCManager, ServiceName, SERVICE_ALL_ACCESS);
if (!schService) {
RC = GetLastError();
CloseServiceHandle(schSCManager);
if (RC == ERROR_SERVICE_DOES_NOT_EXIST) return -2;
else return -1;
}
return_value = ChangeServiceConfig(schService,
SERVICE_NO_CHANGE,
StartMode,
SERVICE_NO_CHANGE,
NULL, NULL, NULL /*tag*/,
NULL, NULL, NULL /*pwd*/,
NULL);
return_value = 0;
RC = GetLastError();
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return return_value;
}
|