编写程序加载NT式驱动
2013-11-29 22:35
375 查看
转载自: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);
}
注: #4~#5 由IRP_MJ_CREATE调用
#6~#7 由IRP_MJ_CLOSE调用
编写程序加载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);
}
注: #4~#5 由IRP_MJ_CREATE调用
#6~#7 由IRP_MJ_CLOSE调用
相关文章推荐
- 编写软件动态加载NT式驱动
- 编写软件动态加载NT式驱动
- 编写软件动态加载NT式驱动
- 编写软件动态加载NT式驱动
- LED驱动测试程序以及静态加载驱动过程
- 同一程序加载sql2000和2005驱动
- c语言编写cgi程序,无法加载lib文件的问题
- Windows内核学习笔记(四)-- 编写程序手动加载驱动程序
- 编写一个Android Linux内核驱动并用C可执行程序测试
- 编写嵌入式linux驱动时,如何才能自动加载设备并生成节点
- 基于TX2440开发板在ADS1.2中编写LED的驱动(GPIO的使用)裸机程序
- 在桌面红旗6上编写并运行第一个驱动设备程序
- MAC 平台 QT编写iphone程序,加载iphone模拟器失败解决办法
- Linux设备驱动之LCD显示摄像图像之二编写V4l2程序
- JDBC驱动加载程序
- Windows内核学习笔记-- 编写程序手动加载驱动程序
- 32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数
- 32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数
- Linux系统自带spi驱动加载及应用程序编写方法详解
- 编写一个随内核加载的简单驱动