之前我们加载驱动都是利用INSTDRV这个应用,其原理是在注册表中写入相应的字段,这一节我们手动编写代码去加载驱动,其原理类似:
设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager,SCM)系统组件完成。加载和卸载NT驱动分为四个步骤:
为NT驱动创建新的服务;
开启此服务;
关闭此服务;
删除NT驱动所创建的服务。
LoadNTDriver装载驱动代码主要流程如下:
代码如下:
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卸载驱动主要代码流程如下:
代码如下:
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 }
安装和卸载驱动:
注意,这里的驱动名称和路径应该设置为:
运行成功: