《Windows驱动开发技术详解》之编程加载NT式驱动

时间:2022-12-26 16:16:25

之前我们加载驱动都是利用INSTDRV这个应用,其原理是在注册表中写入相应的字段,这一节我们手动编写代码去加载驱动,其原理类似:

《Windows驱动开发技术详解》之编程加载NT式驱动

设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager,SCM)系统组件完成。加载和卸载NT驱动分为四个步骤:

为NT驱动创建新的服务;

开启此服务;

关闭此服务;

删除NT驱动所创建的服务。

LoadNTDriver装载驱动代码主要流程如下:

《Windows驱动开发技术详解》之编程加载NT式驱动

代码如下:

 1 BOOL LoadNTDriver(char*lpszDriverName, char*lpszDriverPath){
 2     char szDriverImagePath[256];
 3     //得到完整的驱动路径
 4     GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
 5     BOOL bRet = FALSE;
 6     SC_HANDLE hServiceMgr = NULL;
 7     SC_HANDLE hServiceDDK = NULL;
 8     //打开服务控制管理器
 9     hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
10     if (NULL == hServiceMgr){
11         printf("OpenSCManager() failed : %d \n", GetLastError());
12         goto BeforeLeave;
13         bRet = FALSE;
14     }
15     else{
16         printf("OpenSCManager() OK!\n");
17     }
18     //创建驱动所对应的服务
19     hServiceDDK = CreateService(hServiceMgr,
20         lpszDriverName,
21         lpszDriverName,
22         SERVICE_ALL_ACCESS,
23         SERVICE_KERNEL_DRIVER,
24         SERVICE_DEMAND_START,
25         SERVICE_ERROR_IGNORE,
26         szDriverImagePath,
27         NULL, NULL, NULL, NULL, NULL);
28 
29     DWORD dwRtn;
30     if (NULL == hServiceDDK){
31         dwRtn = GetLastError();
32         if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS){
33             printf("CreateService failed:%d!\n", dwRtn);
34             bRet = FALSE;
35             goto BeforeLeave;
36         }
37         else{
38             printf("CreateService failed:ERROR_IO_PENDING or ERROR_SERVICE_EXISTS\n");
39         }
40         //创建失败说明服务已经存在,直接打开即可
41         hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS);
42         if (NULL == hServiceDDK){
43             dwRtn = GetLastError();
44             printf("OpenService() failed:%d!\n", dwRtn);
45             bRet = FALSE;
46             goto BeforeLeave;
47         }
48         else{
49             printf("OpenService OK!\n");
50         }
51     }
52     else{
53         printf("CreateService OK!\n");
54     }
55 
56     //创建服务成功,开启此服务
57     bRet = StartService(hServiceDDK, NULL, NULL);
58     if (!bRet){
59         dwRtn = GetLastError();
60         if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING){
61             printf("StartService failed:%d!\n", dwRtn);
62             bRet = FALSE;
63             goto BeforeLeave;
64         }
65         else{
66             if (ERROR_IO_PENDING == dwRtn){
67                 printf("StartService() failed:ERROR_IO_PENDING");
68                 bRet = FALSE;
69                 goto BeforeLeave;
70             }
71             else{
72                 printf("StartService() failed :ERROR_SERVICE_ALREADY_RUNNING");
73                 bRet = TRUE;
74                 goto BeforeLeave;
75             }
76         }
77     }
78     bRet = TRUE;
79 BeforeLeave:
80     if (hServiceDDK){
81         CloseServiceHandle(hServiceDDK);
82     }
83     if (hServiceMgr){
84         CloseServiceHandle(hServiceMgr);
85     }
86     return bRet;
87 }

UnLoadNTDriver卸载驱动主要代码流程如下:

《Windows驱动开发技术详解》之编程加载NT式驱动

代码如下:

 1 BOOL UnloadNTDriver(char*szSvrName){
 2     BOOL bRet = FALSE;
 3     SC_HANDLE hServiceMgr = NULL;
 4     SC_HANDLE hServiceDDK = NULL;
 5     hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
 6     if (NULL == hServiceMgr){
 7         printf("OpenSCManager() failed : %d \n", GetLastError());
 8         goto BeforeLeave;
 9         bRet = FALSE;
10     }
11     else{
12         printf("OpenSCManager() OK!\n");
13     }
14     hServiceDDK = OpenService(hServiceMgr, szSvrName, SERVICE_ALL_ACCESS);
15     if (NULL == hServiceDDK){
16         printf("OpenService() failed :%d\n", GetLastError());
17         bRet = FALSE;
18         goto BeforeLeave;
19     }
20     else{
21         printf("OpenService() OK!\n");
22     }
23     SERVICE_STATUS SvrSta;
24     //停止驱动程序
25     if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta)){
26         printf("ControlService() failed:%d\n", GetLastError());
27     }
28     else{
29         printf("ControlService() OK!\n");
30     }
31     //动态卸载驱动程序
32     if (!DeleteService(hServiceDDK)){
33         printf("DeleteService() failed:%d\n", GetLastError());
34     }
35     else{
36         printf("DeleteService() OK!\n");
37     }
38     bRet = TRUE;
39 
40 BeforeLeave:
41     if (hServiceDDK){
42         CloseServiceHandle(hServiceDDK);
43     }
44     if (hServiceMgr){
45         CloseServiceHandle(hServiceMgr);
46     }
47     return bRet;
48 }

安装和卸载驱动:

《Windows驱动开发技术详解》之编程加载NT式驱动

注意,这里的驱动名称和路径应该设置为:

《Windows驱动开发技术详解》之编程加载NT式驱动

运行成功:

《Windows驱动开发技术详解》之编程加载NT式驱动