c++ 實現驅動的加載啟動


測試代碼

#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 會失敗 !


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM