现在的Windows操作系统支持三种驱动程序模型:KDM、WDM、WDF,其中后两者没有本质区别,只是WDF是用运行库封装的WDM而已。KDM是按照NT系统服务启动的,而WDM和WDF都是用设备管理器启动的,后两者比较复杂,这里不作介绍。
安装KDM驱动(安装NT服务):
- 打开服务控制管理器——OpenSCManager
- 创建服务——CreateService
- 关闭所有句柄——CloseServiceHandle
删除KDM驱动(删除NT服务):
- 打开服务控制管理器——OpenSCManager
- 按名称打开服务——OpenService
- 删除服务——DeleteService
- 关闭所有句柄——CloseServiceHandle
启动KDM驱动(启动NT服务,也可以用net start命令实现):
- 打开服务控制管理器——OpenSCManager
- 按名称打开服务——OpenService
- 启动服务——StartService
- 关闭所有句柄——CloseServiceHandle
停止KDM驱动(停止NT服务,也可以用net stop命令实现):
- 打开服务控制管理器——OpenSCManager
- 按名称打开服务——OpenService
- 停止服务——ControlService,SERVICE_CONTROL_STOP
- 关闭所有句柄——CloseServiceHandle
注意:新系统要先关闭驱动程序强制签名。
【示例程序】
警告:一定要在VMWare Workstation、VirtualBox等虚拟机中测试,不要在工作用机中加载编译的驱动程序
内核模式驱动程序非常危险,可能造成蓝屏死机,重要数据损坏丢失,Windows系统损坏,甚至硬件烧毁等严重后果
命令行编译使用下面的命令:
<code class="language-bat">cl ntdrv.cpp kernel32.lib user32.lib advapi32.lib /DUNICODE /D_UNICODE
</code>
CPP代码如下:
<code class="language-cpp">// ntdrv.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
BOOL InstallNTDriver(TCHAR * svrName, TCHAR * lpszDriverPath)
{
BOOL bRet = TRUE;
TCHAR szDriverPath[MAX_PATH] = { 0 };
GetFullPathName(lpszDriverPath, MAX_PATH, szDriverPath, NULL);
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCM)
{
bRet = FALSE;
goto ret;
}
SC_HANDLE hService = CreateService(hSCM,
svrName, //服务的名称
svrName, //显示的名称DisplayName
SERVICE_ALL_ACCESS, //访问所有权
SERVICE_KERNEL_DRIVER, //表示加载的服务是驱动程序
SERVICE_DEMAND_START, //启动类型为手动启动
SERVICE_ERROR_IGNORE, //忽略错误
szDriverPath, //驱动文件名(保护路径),注册表中的ImagePath值
NULL,
NULL,
NULL,
NULL,
NULL);
if (!hService)
{
bRet = FALSE;
goto ret;
}
ret:
if (hService)
{
CloseServiceHandle(hService);
}
if (hSCM)
{
CloseServiceHandle(hSCM);
}
return bRet;
}
BOOL StartNTDriver(TCHAR * szSvrName)
{
BOOL bRet = TRUE;
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCM)
{
bRet = FALSE;
goto ret;
}
SC_HANDLE hService = OpenService(hSCM, szSvrName, SERVICE_ALL_ACCESS);
if (!hService)
{
bRet = FALSE;
goto ret;
}
bRet = StartService(hService, NULL, NULL);
ret:
if (hService)
{
CloseServiceHandle(hService);
}
if (hSCM)
{
CloseServiceHandle(hSCM);
}
return bRet;
}
BOOL StopNTDriver(TCHAR * szSvrName)
{
BOOL bRet = TRUE;
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCM)
{
bRet = FALSE;
goto ret;
}
SC_HANDLE hService = OpenService(hSCM, szSvrName, SERVICE_ALL_ACCESS);
if (!hService)
{
bRet = FALSE;
goto ret;
}
SERVICE_STATUS SvrSta = { 0 };
bRet = ControlService(hService, SERVICE_CONTROL_STOP, &SvrSta);
ret:
if (hService)
{
CloseServiceHandle(hService);
}
if (hSCM)
{
CloseServiceHandle(hSCM);
}
return bRet;
}
BOOL DeleteNTDriver(TCHAR * szSvrName)
{
BOOL bRet = TRUE;
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCM)
{
bRet = FALSE;
goto ret;
}
SC_HANDLE hService = OpenService(hSCM, szSvrName, SERVICE_ALL_ACCESS);
if (!hService)
{
bRet = FALSE;
goto ret;
}
bRet = DeleteService(hService);
ret:
if (hService)
{
CloseServiceHandle(hService);
}
if (hSCM)
{
CloseServiceHandle(hSCM);
}
return bRet;
}
void winprintf(TCHAR *fmt, ...)
{
TCHAR buf[1024]; // wsprintf/wvsprintf只支持1024个字符
va_list va;
va_start(va, fmt);
wvsprintf(buf, fmt, va);
va_end(va);
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD written;
if (!WriteConsole(hout, buf, lstrlen(buf), &written, 0))
{
WriteFile(hout, buf, lstrlen(buf) * sizeof (TCHAR), &written, 0);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 3)
{
winprintf(_T("用法:ntdrv [install|delete|start|stop] svrname [path]\r\n"));
return 0;
}
if (lstrcmpi(argv[1], _T("install")) == 0)
{
if (argc < 4)
{
winprintf(_T("用法:ntdrv install svrname path\r\n"));
return 0;
}
if (!InstallNTDriver(argv[2], argv[3]))
{
winprintf(_T("安装失败,错误码:%d\r\n"), GetLastError());
return 1;
}
else
{
winprintf(_T("安装成功\r\n"));
return 0;
}
}
else if (lstrcmpi(argv[1], _T("delete")) == 0)
{
if (!DeleteNTDriver(argv[2]))
{
winprintf(_T("删除失败,错误码:%d\r\n"), GetLastError());
return 1;
}
else
{
winprintf(_T("删除成功\r\n"));
return 0;
}
}
else if (lstrcmpi(argv[1], _T("delete")) == 0)
{
if (!DeleteNTDriver(argv[2]))
{
winprintf(_T("删除失败,错误码:%d\r\n"), GetLastError());
return 1;
}
else
{
winprintf(_T("删除成功\r\n"));
return 0;
}
}
else if (lstrcmpi(argv[1], _T("start")) == 0)
{
if (!StartNTDriver(argv[2]))
{
winprintf(_T("启动失败,错误码:%d\r\n"), GetLastError());
return 1;
}
else
{
winprintf(_T("启动成功\r\n"));
return 0;
}
}
else if (lstrcmpi(argv[1], _T("stop")) == 0)
{
if (!StopNTDriver(argv[2]))
{
winprintf(_T("停止失败,错误码:%d\r\n"), GetLastError());
return 1;
}
else
{
winprintf(_T("停止成功\r\n"));
return 0;
}
}
return 0;
}
</tchar.h></windows.h></code>
200字以内,仅用于支线交流,主线讨论请采用回复功能。