gfw 发表于 2016-8-4 16:56:28

WIN64教程里的驱动加载类,程序意外退出后就不好使了

意外退出后,无法停止和卸载驱动。求解决方案。

Tesla.Angela 发表于 2016-8-4 23:52:07

原来的驱动类确实有点坑,修改了一下,没测试过。
把驱动加载/卸载,和IO控制,给分离开了。class cDrvCtrl
{
public:
        cDrvCtrl()
        {
                m_pSysPath = NULL;
                m_pServiceName = NULL;
                m_pDisplayName = NULL;
                m_hSCManager = NULL;
                m_hService = NULL;
        }
        ~cDrvCtrl()
        {
                CloseServiceHandle(m_hService);
                CloseServiceHandle(m_hSCManager);
        }
public:
        DWORD m_dwLastError;
        PCHAR m_pSysPath;
        PCHAR m_pServiceName;
        PCHAR m_pDisplayName;
public:
        BOOL Install(PCHAR pSysPath,PCHAR pServiceName,PCHAR pDisplayName);
        BOOL Start();
        BOOL Stop();
        BOOL Remove();
        BOOL GetSvcHandle(PCHAR pServiceName);
protected:
private:
        SC_HANDLE m_hSCManager;
        SC_HANDLE m_hService;
};

BOOL cDrvCtrl::GetSvcHandle(PCHAR pServiceName)
{
        m_pServiceName = pServiceName;
        m_hSCManager = OpenSCManagerA(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if (NULL == m_hSCManager)
        {
                m_dwLastError = GetLastError();
                return FALSE;
        }
        m_hService = OpenServiceA(m_hSCManager,m_pServiceName,SERVICE_ALL_ACCESS);
        if (NULL == m_hService)
        {
                m_dwLastError = GetLastError();
                CloseServiceHandle(m_hSCManager);
                return FALSE;
        }
        return TRUE;
}

BOOL cDrvCtrl::Install(PCHAR pSysPath,PCHAR pServiceName,PCHAR pDisplayName)
{
        m_pSysPath = pSysPath;
        m_pServiceName = pServiceName;
        m_pDisplayName = pDisplayName;
        m_hSCManager = OpenSCManagerA(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if (NULL == m_hSCManager)
        {
                m_dwLastError = GetLastError();
                return FALSE;
        }
        m_hService = CreateServiceA(m_hSCManager,
                                                                m_pServiceName,
                                                                m_pDisplayName,
                                                                SERVICE_ALL_ACCESS,
                                                                SERVICE_KERNEL_DRIVER,
                                                                SERVICE_DEMAND_START,
                                                                SERVICE_ERROR_NORMAL,
                                                                m_pSysPath,
                                                                NULL,
                                                                NULL,
                                                                NULL,
                                                                NULL,
                                                                NULL);
        if (NULL == m_hService)
        {
                        m_dwLastError = GetLastError();
                        CloseServiceHandle(m_hSCManager);
                        return FALSE;
        }
        return TRUE;
}

BOOL cDrvCtrl::Start()
{
        if (!StartServiceA(m_hService,NULL,NULL))
        {
                m_dwLastError = GetLastError();
                return FALSE;
        }
        return TRUE;
}

BOOL cDrvCtrl::Stop()
{
        SERVICE_STATUS ss;
        if (!ControlService(m_hService,SERVICE_CONTROL_STOP,&ss))
        {
                m_dwLastError = GetLastError();
                return FALSE;
        }
        return TRUE;

}

BOOL cDrvCtrl::Remove()
{
        if (!DeleteService(m_hService))
        {
                m_dwLastError = GetLastError();
                return FALSE;
        }
        else
        {
                CloseServiceHandle(m_hService);
                CloseServiceHandle(m_hSCManager);
        }
        return TRUE;
}

HANDLE OpenDriver(PCHAR pLinkName)//example: \\\\.\\xxoo
{
        return CreateFileA(pLinkName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
}

BOOL DriverControl(HANDLE m_hDriver, DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes)
{
        DWORD dw;
        dwIoCode = (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (dwIoCode * 4) | METHOD_BUFFERED;
        BOOL b = DeviceIoControl(m_hDriver,dwIoCode,InBuff,InBuffLen,OutBuff,OutBuffLen,&dw,NULL);
        if(RealRetBytes)
                *RealRetBytes=dw;
        return b;
}重点:程序运行时,先用OpenDriver打开驱动。如果返回值不是INVALID_HANDLE_VALUE,则用GetSvcHandle获取服务句柄。后面的操作(停止、卸载)就好使了。卸载驱动前,记得把『驱动句柄』(就是通过CreateFile获得的句柄)给关闭。
页: [1]
查看完整版本: WIN64教程里的驱动加载类,程序意外退出后就不好使了