測試代碼
#include <iostream>
#include <Windows.h>
using namespace std;
// 安裝驅動
BOOL installDvr(CONST WCHAR drvPath[50], CONST WCHAR serviceName[20]) {
// 打開服務控制管理器數據庫
SC_HANDLE schSCManager = OpenSCManager(
NULL, // 目標計算機的名稱,NULL:連接本地計算機上的服務控制管理器
NULL, // 服務控制管理器數據庫的名稱,NULL:打開 SERVICES_ACTIVE_DATABASE 數據庫
SC_MANAGER_ALL_ACCESS // 所有權限
);
if (schSCManager == NULL) {
CloseServiceHandle(schSCManager);
return FALSE;
}
// 創建服務對象,添加至服務控制管理器數據庫
SC_HANDLE schService = CreateService(
schSCManager, // 服務控件管理器數據庫的句柄
serviceName, // 要安裝的服務的名稱
serviceName, // 用戶界面程序用來標識服務的顯示名稱
SERVICE_ALL_ACCESS, // 對服務的訪問權限:所有全權限
SERVICE_KERNEL_DRIVER, // 服務類型:驅動服務
SERVICE_DEMAND_START, // 服務啟動選項:進程調用 StartService 時啟動
SERVICE_ERROR_IGNORE, // 如果無法啟動:忽略錯誤繼續運行
drvPath, // 驅動文件絕對路徑,如果包含空格需要多加雙引號
NULL, // 服務所屬的負載訂購組:服務不屬於某個組
NULL, // 接收訂購組唯一標記值:不接收
NULL, // 服務加載順序數組:服務沒有依賴項
NULL, // 運行服務的賬戶名:使用 LocalSystem 賬戶
NULL // LocalSystem 賬戶密碼
);
if (schService == NULL) {
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return FALSE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
// 啟動服務
BOOL startDvr(CONST WCHAR serviceName[20]) {
// 打開服務控制管理器數據庫
SC_HANDLE schSCManager = OpenSCManager(
NULL, // 目標計算機的名稱,NULL:連接本地計算機上的服務控制管理器
NULL, // 服務控制管理器數據庫的名稱,NULL:打開 SERVICES_ACTIVE_DATABASE 數據庫
SC_MANAGER_ALL_ACCESS // 所有權限
);
if (schSCManager == NULL) {
CloseServiceHandle(schSCManager);
return FALSE;
}
// 打開服務
SC_HANDLE hs = OpenService(
schSCManager, // 服務控件管理器數據庫的句柄
serviceName, // 要打開的服務名
SERVICE_ALL_ACCESS // 服務訪問權限:所有權限
);
if (hs == NULL) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
if (StartService(hs, 0, 0) == 0) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return TRUE;
}
// 停止服務
BOOL stopDvr(CONST WCHAR serviceName[20]) {
// 打開服務控制管理器數據庫
SC_HANDLE schSCManager = OpenSCManager(
NULL, // 目標計算機的名稱,NULL:連接本地計算機上的服務控制管理器
NULL, // 服務控制管理器數據庫的名稱,NULL:打開 SERVICES_ACTIVE_DATABASE 數據庫
SC_MANAGER_ALL_ACCESS // 所有權限
);
if (schSCManager == NULL) {
CloseServiceHandle(schSCManager);
return FALSE;
}
// 打開服務
SC_HANDLE hs = OpenService(
schSCManager, // 服務控件管理器數據庫的句柄
serviceName, // 要打開的服務名
SERVICE_ALL_ACCESS // 服務訪問權限:所有權限
);
if (hs == NULL) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
// 如果服務正在運行
SERVICE_STATUS status;
if (QueryServiceStatus(hs, &status) == 0) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
if (status.dwCurrentState != SERVICE_STOPPED &&
status.dwCurrentState != SERVICE_STOP_PENDING
) {
// 發送關閉服務請求
if (ControlService(
hs, // 服務句柄
SERVICE_CONTROL_STOP, // 控制碼:通知服務應該停止
&status // 接收最新的服務狀態信息
) == 0) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
// 判斷超時
INT timeOut = 0;
while(status.dwCurrentState != SERVICE_STOPPED){
timeOut++;
QueryServiceStatus(hs, &status);
Sleep(50);
}
if (timeOut > 80) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
}
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return TRUE;
}
// 卸載驅動
BOOL unloadDvr(CONST WCHAR serviceName[20]) {
// 打開服務控制管理器數據庫
SC_HANDLE schSCManager = OpenSCManager(
NULL, // 目標計算機的名稱,NULL:連接本地計算機上的服務控制管理器
NULL, // 服務控制管理器數據庫的名稱,NULL:打開 SERVICES_ACTIVE_DATABASE 數據庫
SC_MANAGER_ALL_ACCESS // 所有權限
);
if (schSCManager == NULL) {
CloseServiceHandle(schSCManager);
return FALSE;
}
// 打開服務
SC_HANDLE hs = OpenService(
schSCManager, // 服務控件管理器數據庫的句柄
serviceName, // 要打開的服務名
SERVICE_ALL_ACCESS // 服務訪問權限:所有權限
);
if (hs == NULL) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
// 刪除服務
if (DeleteService(hs) == 0) {
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return FALSE;
}
CloseServiceHandle(hs);
CloseServiceHandle(schSCManager);
return TRUE;
}
int main()
{
if (installDvr(L"C:\\Test_Driver_1.sys", L"LYSM_service") == TRUE) {
cout << "installDvr success." << endl;
}
if (startDvr(L"LYSM_service") == TRUE) {
cout << "startDvr success." << endl;
}
if (stopDvr(L"LYSM_service") == TRUE) {
cout << "stopDvr success." << endl;
}
if (unloadDvr(L"LYSM_service") == TRUE) {
cout << "unloadDvr success." << endl;
}
getchar();
return 0;
}
打開 DbgView,設置過濾條件,運行編譯好的 exe,看下效果:
注意要禁用驅動簽名強制,否則 startDvr 會失敗 !