驱动开发之 加载NT式驱动程序实例

来源:互联网 发布:ubuntu和linux mint 编辑:程序博客网 时间:2024/05/21 10:49

使用SCM组件加载NT驱动

下面是Driver.cpp

#include "Driver.h"/************************************************************************* 函数名称:DriverEntry* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象      pRegistryPath:驱动程序在注册表的中的路径* 返回 值:返回初始化驱动状态*************************************************************************/#pragma INITCODEextern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) {NTSTATUS status;KdPrint(("Enter DriverEntry\n"));//注册其他驱动调用函数入口pDriverObject->DriverUnload = HelloDDKUnload;pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;//创建驱动设备对象status = CreateDevice(pDriverObject);KdPrint(("Leave DriverEntry\n"));return status;}/************************************************************************* 函数名称:CreateDevice* 功能描述:初始化设备对象* 参数列表:      pDriverObject:从I/O管理器中传进来的驱动对象* 返回 值:返回初始化状态*************************************************************************/#pragma INITCODENTSTATUS CreateDevice (IN PDRIVER_OBJECTpDriverObject) {NTSTATUS status;PDEVICE_OBJECT pDevObj;PDEVICE_EXTENSION pDevExt;//创建设备名称UNICODE_STRING devName;RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");//创建设备status = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj );if (!NT_SUCCESS(status))return status;pDevObj->Flags |= DO_BUFFERED_IO;pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;pDevExt->pDevice = pDevObj;pDevExt->ustrDeviceName = devName;//创建符号链接UNICODE_STRING symLinkName;RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");pDevExt->ustrSymLinkName = symLinkName;status = IoCreateSymbolicLink( &symLinkName,&devName );if (!NT_SUCCESS(status)) {IoDeleteDevice( pDevObj );return status;}return STATUS_SUCCESS;}/************************************************************************* 函数名称:HelloDDKUnload* 功能描述:负责驱动程序的卸载操作* 参数列表:      pDriverObject:驱动对象* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODEVOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) {PDEVICE_OBJECTpNextObj;KdPrint(("Enter DriverUnload\n"));pNextObj = pDriverObject->DeviceObject;while (pNextObj != NULL) {PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;//删除符号链接UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;IoDeleteSymbolicLink(&pLinkName);pNextObj = pNextObj->NextDevice;IoDeleteDevice( pDevExt->pDevice );}KdPrint(("Leave DriverUnload\n"));}/************************************************************************* 函数名称:HelloDDKDispatchRoutine* 功能描述:对读IRP进行处理* 参数列表:      pDevObj:功能设备对象      pIrp:从IO请求包* 返回 值:返回状态*************************************************************************/#pragma PAGEDCODENTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) {KdPrint(("Enter HelloDDKDispatchRoutine\n"));NTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDispatchRoutine\n"));return status;}
应用程序main.cpp

#include <windows.h>  #include <winsvc.h>  #include <conio.h>  #include <stdio.h>#define DRIVER_NAME "HelloDDK"#define DRIVER_PATH "..\\..\\MyDriver\\MyDriver_Check\\HelloDDK.sys"//装载NT驱动程序BOOL LoadNTDriver(char* lpszDriverName,char* lpszDriverPath){char szDriverImagePath[256];//得到完整的驱动路径GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);printf("szDriverImagePath:%s\n",szDriverImagePath);BOOL bRet = FALSE;SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄//打开服务控制管理器hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );if( hServiceMgr == NULL )  {//OpenSCManager失败printf( "OpenSCManager() Faild %d ! \n", GetLastError() );bRet = FALSE;goto BeforeLeave;}else{////OpenSCManager成功printf( "OpenSCManager() ok ! \n" );  }//创建驱动所对应的服务hServiceDDK = CreateService( hServiceMgr,lpszDriverName, //驱动程序的在注册表中的名字  lpszDriverName, // 注册表驱动程序的 DisplayName 值  SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  szDriverImagePath, // 注册表驱动程序的 ImagePath 值  NULL,  NULL,  NULL,  NULL,  NULL);  DWORD dwRtn;//判断服务是否失败if( hServiceDDK == NULL )  {  dwRtn = GetLastError();if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )  {  //由于其他原因创建服务失败printf( "CrateService() Faild %d ! \n", dwRtn );  bRet = FALSE;goto BeforeLeave;}  else  {//服务创建失败,是由于服务已经创立过printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );  }// 驱动程序已经加载,只需要打开  hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );  if( hServiceDDK == NULL )  {//如果打开服务也失败,则意味错误dwRtn = GetLastError();  printf( "OpenService() Faild %d ! \n", dwRtn );  bRet = FALSE;goto BeforeLeave;}  else {printf( "OpenService() ok ! \n" );}}  else  {printf( "CrateService() ok ! \n" );}//开启此项服务bRet= StartService( hServiceDDK, NULL, NULL );  if( !bRet )  {  DWORD dwRtn = GetLastError();  if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )  {  printf( "StartService() Faild %d ! \n", dwRtn );  bRet = FALSE;goto BeforeLeave;}  else  {  if( dwRtn == ERROR_IO_PENDING )  {  //设备被挂住printf( "StartService() Faild ERROR_IO_PENDING ! \n");bRet = FALSE;goto BeforeLeave;}  else  {  //服务已经开启printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");bRet = TRUE;goto BeforeLeave;}  }  }bRet = TRUE;//离开前关闭句柄BeforeLeave:if(hServiceDDK){CloseServiceHandle(hServiceDDK);}if(hServiceMgr){CloseServiceHandle(hServiceMgr);}return bRet;}//卸载驱动程序  BOOL UnloadNTDriver( char * szSvrName )  {BOOL bRet = FALSE;SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄SERVICE_STATUS SvrSta;//打开SCM管理器hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  if( hServiceMgr == NULL )  {//带开SCM管理器失败printf( "OpenSCManager() Faild %d ! \n", GetLastError() );  bRet = FALSE;goto BeforeLeave;}  else  {//带开SCM管理器失败成功printf( "OpenSCManager() ok ! \n" );  }//打开驱动所对应的服务hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );  if( hServiceDDK == NULL )  {//打开驱动所对应的服务失败printf( "OpenService() Faild %d ! \n", GetLastError() );  bRet = FALSE;goto BeforeLeave;}  else  {  printf( "OpenService() ok ! \n" );  }  //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  {  printf( "ControlService() Faild %d !\n", GetLastError() );  }  else  {//打开驱动所对应的失败printf( "ControlService() ok !\n" );  }  //动态卸载驱动程序。  if( !DeleteService( hServiceDDK ) )  {//卸载失败printf( "DeleteSrevice() Faild %d !\n", GetLastError() );  }  else  {  //卸载成功printf( "DelServer:eleteSrevice() ok !\n" );  }  bRet = TRUE;BeforeLeave://离开前关闭打开的句柄if(hServiceDDK){CloseServiceHandle(hServiceDDK);}if(hServiceMgr){CloseServiceHandle(hServiceMgr);}return bRet;} void TestDriver(){//测试驱动程序  HANDLE hDevice = CreateFile("\\\\.\\HelloDDK",  GENERIC_WRITE | GENERIC_READ,  0,  NULL,  OPEN_EXISTING,  0,  NULL);  if( hDevice != INVALID_HANDLE_VALUE )  {printf( "Create Device ok ! \n" );  }else  {printf( "Create Device faild %d ! \n", GetLastError() );  }CloseHandle( hDevice );} int main(int argc, char* argv[])  {getchar();//加载驱动BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);if (!bRet){printf("LoadNTDriver error\n");getchar(); UnloadNTDriver(DRIVER_NAME);//getchar();return 0;}//加载成功printf( "press any to create device!\n" );  getchar();  TestDriver();//这时候你可以通过注册表,或其他查看符号连接的软件验证。  printf( "press any to unload the driver!\n" );  getchar();  //卸载驱动UnloadNTDriver(DRIVER_NAME);if (!bRet){printf("UnloadNTDriver error\n");getchar(); return 0;}getchar(); return 0;  }  

用到的函数介绍:http://blog.csdn.net/liyun123gx/article/details/37599357

0 0
原创粉丝点击