?? driver.h
字號:
///////////////////////////////////////////////////
// Driver.h文件
#ifndef __DRIVER_H__
#define __DRIVER_H__
#include <Winsvc.h> // 為了使用SCM函數(shù)
class CDriver
{
public:
// 構造函數(shù)和析構函數(shù)
// 構造函數(shù),pszDriverPath為驅(qū)動所在目錄,pszLinkName為符號連接名字
// 在類的構造函數(shù)中,將試圖創(chuàng)建或打開服務,
CDriver(LPCTSTR pszDriverPath, LPCTSTR pszLinkName);
// 析構函數(shù)。在這里,將停止服務,
virtual ~CDriver();
// 屬性
// 此驅(qū)動是否可用
virtual BOOL IsValid() { return (m_hSCM != NULL && m_hService != NULL); }
// 操作
// 開啟服務。也就是說驅(qū)動的DriverEntry函數(shù)將被調(diào)用
virtual BOOL StartDriver();
// 結(jié)束服務。即驅(qū)動程序的DriverUnload例程將被調(diào)用
virtual BOOL StopDriver();
// 打開設備,即取得到此驅(qū)動的一個句柄
virtual BOOL OpenDevice();
// 向設備發(fā)送控制代碼
virtual DWORD IoControl(DWORD nCode, PVOID pInBuffer,
DWORD nInCount, PVOID pOutBuffer, DWORD nOutCount);
// 實現(xiàn)
protected:
char m_szLinkName[56]; // 符號連接名稱
BOOL m_bStarted; // 指定服務是否啟動
BOOL m_bCreateService; // 指定是否創(chuàng)建了服務
HANDLE m_hSCM; // SCM數(shù)據(jù)庫句柄
HANDLE m_hService; // 服務句柄
HANDLE m_hDriver; // 設備句柄
};
CDriver::CDriver(LPCTSTR pszDriverPath, LPCTSTR pszLinkName)
{
strncpy(m_szLinkName, pszLinkName, 55);
m_bStarted = FALSE;
m_bCreateService = FALSE;
m_hSCM = m_hService = NULL;
m_hDriver = INVALID_HANDLE_VALUE;
// 打開SCM管理器
m_hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(m_hSCM == NULL)
{
MessageBox(0, "打開服務控制管理器失敗\n",
"可能是因為您不擁有Administrator權限\n", 0);
return;
}
// 創(chuàng)建或打開服務
m_hService = ::CreateService(m_hSCM, m_szLinkName, m_szLinkName, SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
pszDriverPath, NULL, 0, NULL, NULL, NULL);
if(m_hService == NULL)
{
// 創(chuàng)建服務失敗,可能是因為服務已經(jīng)存在,所以還要試圖打開它
int nError = ::GetLastError();
if(nError == ERROR_SERVICE_EXISTS || nError == ERROR_SERVICE_MARKED_FOR_DELETE)
{
m_hService = ::OpenService(m_hSCM, m_szLinkName, SERVICE_ALL_ACCESS);
}
}
else
{
m_bCreateService = TRUE;
}
}
CDriver::~CDriver()
{
// 關閉設備句柄
if(m_hDriver != INVALID_HANDLE_VALUE)
::CloseHandle(m_hDriver);
// 如果創(chuàng)建了服務,就將之刪除
if(m_bCreateService)
{
StopDriver();
::DeleteService(m_hService);
}
// 關閉句柄
if(m_hService != NULL)
::CloseServiceHandle(m_hService);
if(m_hSCM != NULL)
::CloseServiceHandle(m_hSCM);
}
BOOL CDriver::StartDriver()
{
if(m_bStarted)
return TRUE;
if(m_hService == NULL)
return FALSE;
// 啟動服務
if(!::StartService(m_hService, 0, NULL))
{
int nError = ::GetLastError();
if(nError == ERROR_SERVICE_ALREADY_RUNNING)
m_bStarted = TRUE;
else
::DeleteService(m_hService);
}
else
{
// 啟動成功后,等待服務進入運行狀態(tài)
int nTry = 0;
SERVICE_STATUS ss;
::QueryServiceStatus(m_hService, &ss);
while(ss.dwCurrentState == SERVICE_START_PENDING && nTry++ < 80)
{
::Sleep(50);
::QueryServiceStatus(m_hService, &ss);
}
if(ss.dwCurrentState == SERVICE_RUNNING)
m_bStarted = TRUE;
}
return m_bStarted;
}
BOOL CDriver::StopDriver()
{
if(!m_bStarted)
return TRUE;
if(m_hService == NULL)
return FALSE;
// 停止服務
SERVICE_STATUS ss;
if(!::ControlService(m_hService, SERVICE_CONTROL_STOP, &ss))
{
if(::GetLastError() == ERROR_SERVICE_NOT_ACTIVE)
m_bStarted = FALSE;
}
else
{
// 等待服務完全停止運行
int nTry = 0;
while(ss.dwCurrentState == SERVICE_STOP_PENDING && nTry++ < 80)
{
::Sleep(50);
::QueryServiceStatus(m_hService, &ss);
}
if(ss.dwCurrentState == SERVICE_STOPPED)
m_bStarted = FALSE;
}
return !m_bStarted;
}
BOOL CDriver::OpenDevice()
{
if(m_hDriver != INVALID_HANDLE_VALUE)
return TRUE;
// "\\.\"是Win32中定義本地計算機的方法,
// m_szLinkName是設備對象的符號連接名稱,后面章節(jié)會詳細討論
char sz[256] = "";
wsprintf(sz, "\\\\.\\%s", m_szLinkName);
// 打開驅(qū)動程序所控制設備
m_hDriver = ::CreateFile(sz,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
return (m_hDriver != INVALID_HANDLE_VALUE);
}
DWORD CDriver::IoControl(DWORD nCode, PVOID pInBuffer,
DWORD nInCount, PVOID pOutBuffer, DWORD nOutCount)
{
if(m_hDriver == INVALID_HANDLE_VALUE)
return -1;
// 向驅(qū)動程序發(fā)送控制代碼
DWORD nBytesReturn;
BOOL bRet = ::DeviceIoControl(m_hDriver, nCode,
pInBuffer, nInCount, pOutBuffer, nOutCount, &nBytesReturn, NULL);
if(bRet)
return nBytesReturn;
else
return -1;
}
#endif // __DRIVER_H__
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -