转载自:http://mzf2008.blog.163.com/blog/static/355997862010119935492/
编写程序加载NT式驱动
设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager,SMC)系统组件完成。Driver Service是Windows服务的一个特例,它遵从Windows服务的协议。加载和卸载NT式驱动分为4个步骤:
1. 为NT驱动创建新的服务
2. 开启此项服务。
3. 关闭此项服务
4. 删除NT驱动所创建的服务。
(1)打开SCM管理器函数
此函数的作用是打开SCM管理器,用于SCM的初始化。
SC_HANDLE OpenSCManager(
LPCTSTR lpMachineName, //计算机名称。如果为NULL代表是本机。
LPCTSTR lpDatabaseName,//SCM数据库名称。NULL代表使用缺省数据库。
DWORD dwDesiredAccess //使用权限,一般为SC_MANAGER_ALL_ACCESS
);
此函数如果成功返回SCM管理器的句柄,失败则返回NULL.
(2)关闭服务句柄
此函数的作用是关闭SCM管理器的句柄,用于SCM的清除工作。
BOOL CloseServiceHandle(
SC_HANDLE hSCObject //要关闭的SCM句柄
);
(3)创建服务
SC_HANDLE CreateService(
SC_HANDLE hSCManager, // SCM管理器的句柄
LPCTSTR lpServiceName, // 服务名称,就是在设备管理器中看到的设备名称
LPCTSTR lpDisplayName, // 服务显示出来的名称
DWORD dwDesiredAccess, // 打开权限,一般为SERVICE_ALL_ACCESS
DWORD dwServiceType, // 服务类型
DWORD dwStartType, // 服务启动的类型
DWORD dwErrorControl, // 关于错误处理的代码
LPCTSTR lpBinaryPathName, // 二进制文件代码,即编译出来的驱动文件路径
LPCTSTR lpLoadOrderGroup, // 用何用户组开启服务
LPDWORD lpdwTagId, // 输出验证标签
LPCTSTR lpDependencies, // 所依赖的服务的名称
LPCTSTR lpServiceStartName,//用户帐户名称
LPCTSTR lpPassword // 用户口令
);
dwServiceType:服务类型,有以下几种选择:
1. SERVICE_KERNEL_DRIVER 普通程序的驱动,一般使用此项
2. SERVICE_FILE_SYSTEM_DRIVER 文件系统的驱动
dwStartType:服务启动的类型,有以下几种选择:
1. SERVICE_BOOT_START 被SystemLoader加载,即系统启动前就被启动
2. SERVICE_AUTO_START 驱动自动加载
3. SERVICE_DEMAND_START 按照需要时启动,一般选择此项
(4)打开服务
此函数的作用是针对已经创建过的服务,再次打开此项服务
SC_HANDLE OpenService(
SC_HANDLE hSCManager, // handle to service control manager
// database
LPCTSTR lpServiceName, // pointer to name of service to start
DWORD dwDesiredAccess // 访问权限,一般设置为SERVICE_ALL_ACCESS
};
(5)启动服务
用于启动已经创建的服务
BOOL StartService(
SC_HANDLE hService, // handle of service
DWORD dwNumServiceArgs, // number of arguments
LPCTSTR *lpServiceArgVectors // array of argument strings
// string pointers
);
(6)控制服务
此函数的作用是对相应的服务,发送控制码,根据不同的控制码操作服务。
BOOL ControlService(
SC_HANDLE hService, // handle to service
DWORD dwControl, // control code
LPSERVICE_STATUS lpServiceStatus
// pointer to service status structure
);
dwControl:对服务的控制码,此处列出常用的控制码
1.SERVICE_CONTROL_STOP 针对运行的服务发出停止的命令
2.SERVICE_CONTROL_PAUSE 针对正在执行的服务发出暂停的命令
3.SERVICE_CONTROL_CONTINUE 针对暂停的服务发出继续运行的命令
(7)删除停止运行的服务
BOOL DeleteService(
SC_HANDLE hService // handle to service
);
如果服务没有停止,那么系统会在重启的时候删除服务。
测试代码:
#include<windows.h>
#include <stdio.h>
void TestDriver();
//加载驱动
BOOL LoadNTDriver(char* lpszDriverName, char* lpszDriverPath)
{
char szDriverPath[MAX_PATH];
GetFullPathName(lpszDriverPath, MAX_PATH, szDriverPath, NULL);
printf("%s\n", szDriverPath);
SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
printf("OpenSCManager error:%d\n", GetLastError());
return FALSE;
}
SC_HANDLE hDriver = CreateService(hSCM, lpszDriverName, lpszDriverName, SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE,
szDriverPath, NULL, NULL, NULL, NULL, NULL);
DWORD dwError;
if (hDriver == NULL)
{
dwError = GetLastError();
if (dwError != ERROR_IO_PENDING && dwError != ERROR_SERVICE_EXISTS)
{
printf("CreateService error:%d\n", dwError);
CloseServiceHandle(hSCM);
return FALSE;
}
else
{
printf("Service already Created.\n");
}
hDriver = OpenService(hSCM, lpszDriverName, SERVICE_ALL_ACCESS);
if (hDriver == NULL)
{
printf("OpenService error:%d\n", GetLastError());
CloseServiceHandle(hSCM);
return FALSE;
}
else
printf("OpenService OK!\n");
}
else
{
printf("CreateService OK!\n");
}
dwError = StartService(hDriver, 0, NULL);
if (!dwError)
{
dwError = GetLastError();
if (dwError != ERROR_IO_PENDING && dwError != ERROR_SERVICE_ALREADY_RUNNING)
{
printf("StartService error:%d\n", dwError);
CloseServiceHandle(hSCM);
CloseServiceHandle(hDriver);
return FALSE;
}
else
{
printf("Service already run\n");
CloseServiceHandle(hSCM);
CloseServiceHandle(hDriver);
return TRUE;
}
}
return TRUE;
}
//卸载驱动
BOOL UnLoadNTDriver(char* szSrvName)
{
SC_HANDLE hSCM = NULL;
SC_HANDLE hSrv = NULL;
hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
printf("OpenSCManager error:%d\n", GetLastError());
return FALSE;
}
else
{
printf("OpenSCManager OK!\n");
}
hSrv = OpenService(hSCM, szSrvName, SERVICE_ALL_ACCESS);
if (hSrv == NULL)
{
printf("OpenService error:%d\n", GetLastError());
CloseServiceHandle(hSCM);
return FALSE;
}
else
printf("OpenService OK!\n");
SERVICE_STATUS ss;
if (!ControlService(hSrv, SERVICE_CONTROL_STOP, &ss))
{
printf("ControlService error:%d\n", GetLastError());
CloseServiceHandle(hSCM);
CloseServiceHandle(hSrv);
return FALSE;
}
else
printf("ControlService ok!\n");
if (!DeleteService(hSrv))
{
printf("DeleteService error:%d\n", GetLastError());
CloseServiceHandle(hSCM);
CloseServiceHandle(hSrv);
return FALSE;
}
else
printf("DeleteService ok!\n");
return TRUE;
}
int main(void)
{
BOOL bRet = LoadNTDriver("MzfDDK",
"C:\\Documents and Settings\\Administrator\\桌面\\HelloDDK\\objchk_wxp_x86\\i386\\MzfFirstDriver.sys");
if (!bRet)
{
printf("LoadNTDriver error\n");
return -1;
}
printf("Press any key to Test Driver!\n");
getchar();
TestDriver();
printf("Press any key to Unload Driver!\n");
getchar();
bRet = UnLoadNTDriver("MzfDDK");
if (!bRet)
{
printf("UnLoadNTDriver error\n");
return -1;
}
return 0;
}
void TestDriver()
{
HANDLE hDriver = CreateFile("\\\\.\\HelloDDK", GENERIC_WRITE | GENERIC_READ, //HelloDDK为驱动的符号链接
0, NULL, OPEN_EXISTING, 0, NULL);
if (hDriver != INVALID_HANDLE_VALUE)
{
printf("Open Driver OK!\n");
}
else
printf("Open Driver fail,error:%d\n", GetLastError());
CloseHandle(hDriver);
}
![2010年12月09日 - Fly - 从C开始](http://img100.ph.126.net/aW5IgIt_Dq0rPkL9GxyXdA==/2051389630269009450.jpg)
![2010年12月09日 - Fly - 从C开始](http://img855.ph.126.net/_xAZ6dwE2ewrCDWsNhfV7A==/2760706571579028961.png)
注: #4~#5 由IRP_MJ_CREATE调用
#6~#7 由IRP_MJ_CLOSE调用