【C++】驱动加载/卸载/通信代码(兼容WIN32/WIN64)
类代码://Author: Anonymous
//#include <Windows.h>
class cDrvCtrl
{
public:
cDrvCtrl()
{
m_pSysPath = NULL;
m_pServiceName = NULL;
m_pDisplayName = NULL;
m_hSCManager = NULL;
m_hService = NULL;
m_hDriver = INVALID_HANDLE_VALUE;
}
~cDrvCtrl()
{
CloseServiceHandle(m_hService);
CloseServiceHandle(m_hSCManager);
CloseHandle(m_hDriver);
}
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 Open(PCHAR pLinkName);
BOOL IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen);
protected:
private:
SC_HANDLE m_hSCManager;
SC_HANDLE m_hService;
HANDLE m_hDriver;
};
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();
if (ERROR_SERVICE_EXISTS == m_dwLastError)
{
m_hService = OpenServiceA(m_hSCManager,m_pServiceName,SERVICE_ALL_ACCESS);
if (NULL == m_hService)
{
CloseServiceHandle(m_hSCManager);
return FALSE;
}
}
else
{
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;
}
return TRUE;
}
BOOL cDrvCtrl::Open(PCHAR pLinkName)//example: \\\\.\\xxoo
{
if (m_hDriver != INVALID_HANDLE_VALUE)
return TRUE;
m_hDriver = CreateFileA(pLinkName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(m_hDriver != INVALID_HANDLE_VALUE)
return TRUE;
else
return FALSE;
}
DWORD CTL_CODE_GEN(DWORD lngFunction)
{
return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED;
}
BOOL cDrvCtrl::IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen)
{
DWORD dw;
return DeviceIoControl(m_hDriver,CTL_CODE_GEN(dwIoCode),InBuff,InBuffLen,OutBuff,OutBuffLen,&dw,NULL);
}范例代码:void test6()
{
cDrvCtrl dc;
BOOL b;
DWORD dw=0x1234,dw0=0;
//load drv
b=dc.Install("D:\\temp\\MyDriver.sys","MyDriver","MyDriver");
printf("dc.Install=%d\n",b);
b=dc.Start();
printf("dc.Start=%d\n",b);
//call drv
b=dc.Open("\\\\.\\MyDriver");
printf("dc.Open=%d\n",b);
b=dc.IoControl(0x800,&dw,sizeof(dw),&dw0,sizeof(dw0));
printf("dc.IoControl=%d\n",b);
if(!b)
{
dw0=GetLastError();
printf("LastError=%ld\n",dw0);
}
else
{
printf("dw0=%ld\n",dw0);
}
//unload drv
b=dc.Stop();
printf("dc.Stop=%d\n",b);
b=dc.Remove();
printf("dc.Remove=%d\n",b);
} 关键在于使用sc来控制service,通过创建SERVICE_KERNEL_DRIVER来创建一个内核驱动方式的服务。
我突然在想,如果是单片机,想要动态加载驱动,该怎么设计单片机系统。
虽说,单片机没人把指令放RAM上,都是放ROM的。但可以设计一个功能让它从UART等接口动态读取bin然后自己烧自己的ROM。
虽说STM32F103的每个ROM页只能被烧10000次
感谢楼主分享~~~
楼主大能,感谢感谢
页:
[1]