驱动程序的基本结构课件

上传人:29 文档编号:241969053 上传时间:2024-08-08 格式:PPT 页数:35 大小:193.37KB
返回 下载 相关 举报
驱动程序的基本结构课件_第1页
第1页 / 共35页
驱动程序的基本结构课件_第2页
第2页 / 共35页
驱动程序的基本结构课件_第3页
第3页 / 共35页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,第一级,第二级,*,驱动程序的基本结构,驱动程序的基本结构,最简单的驱动程序,extern,“C”#,include,extern,C,NTSTATUS,DriverEntry(,IN,PDRIVER_OBJECT,DriverObject,IN PUNICODE_STRING,RegistryPath),NTSTATUS,status=STATUS_UNSUCCESSFUL;,KdPrint(Hello World!);,return,status;,2,最简单的驱动程序extern“C”#include,驱动程序的入口函数,NTSTATUS,DriverEntry(,IN,PDRIVER_OBJECT,DriverObject,IN,PUNICODE_STRING,RegistryPath),return,status;,参数DriverObject表示指向,驱动对象,的指针;,参数RegistryPath表示该驱动所对应的注册表,服务键,的子目录,返回值表示初始化是否成功,3,驱动程序的入口函数NTSTATUS DriverEntry(,内核模式下我们,能,调用哪些函数?,Windows内核输出的,内核API函数,;,DDK提供的运行时间库,其它驱动程序提供的服务,4,内核模式下我们能调用哪些函数?Windows内核输出的内核A,内核模式下我们,不能,调用哪些函数?,Windows的,用户模式API函数,;,ISO规定的C/C+标准函数库,5,内核模式下我们不能调用哪些函数?Windows的用户模式AP,DDK中一个驱动型工程的组成,MAKEFILE,文件,一般不作改动,Sources文件,:(1)指示了整个工程由哪些源程序和资源文件构成;(2)包含了主要的编译参数,指导编译器和链接器的工作。,.cpp文件和.h文件,6,DDK中一个驱动型工程的组成MAKEFILE文件,一般不作改,如何安装NT型驱动程序?,方法1,:在注册表HKEY_LOCAL_MACHINE,SYSTEMCurrentControlSetServices下增加一个新的项目。可以将该,服务,指定为,开机自启动,,也可以指定为,按需启动,。如果是按需启动,则可以用,net start,命令启动,用,net stop,命令停止。,方法2,:编写另外的用户模式程序利用SCM函数按需启动。,方法3,:在调试阶段可以利用第三方的工具如:DriverMoniter和IntallDriver随时安装和卸载。,7,如何安装NT型驱动程序?方法1:在注册表HKEY_LOCAL,如何安装WDM驱动程序?,必须编写一个,安装指示文件,(.inf)指导Windows将驱动程序安装到指定位置(一般安装在,windowssystem32drivers,子目录下),并在注册表中进行登记。,对于,即插即用,类设备的驱动,操作系统会自动发现该设备并调用“,添加新硬件,”程序向用户询问相应的inf文件的位置。,对于非即插即用类设备的驱动,用户必须自己手动调用“添加新硬件”程序,并通过告诉该程序inf文件的位置。,8,如何安装WDM驱动程序?必须编写一个安装指示文件(.inf),inf文件主要包含了哪些内容?,设备类型、设备型号、厂商信息、程序版本号。,对操作系统版本和CPU类型的要求,源文件(.sys文件)的文件名和所在位置,安装目标子目录,在注册表中添加哪些内容,硬件配置信息,安全配置信息,9,inf文件主要包含了哪些内容?设备类型、设备型号、厂商信息、,驱动对象(Driver Object),在操作系统首次装载一个驱动程序之后,它会创建一个数据结构用来记录该驱动,该数据结构我们称为,驱动对象,(,Driver Object,)。,驱动对象,记录与驱动程序本身相关的信息,它主要包含了除了DriverEntry之外的其它驱动程序入口函数的入口地址。(,驱动程序是一种具有多个入口函数的程序,),驱动对象是由操作系统创建,然后作为DriverEntry的第一个参数传递给你的程序。,在获得驱动对象的指针之后,你的程序需要对其中的一些字段进行初始化。,10,驱动对象(Driver Object)在操作系统首次装载一个,驱动对象(Driver Object),驱动对象在DDK的头文件(ntddk.h)中按如下方式定义:。,typedef,struct,_DRIVER_OBJECT,CSHORTType;,CSHORTSize;,DRIVER_OBJECT,*PDRIVER_OBJECT;,由上面的定义可以看成,驱动对象不同于C+中的Class,它只是一个Struct。,11,驱动对象(Driver Object)驱动对象在DDK的头文,12,12,驱动对象的一些关键字段(一),DriverStartIo,(,PDRIVER_STARTIO,):指向StartIO入口函数的指针.,DriverUnload,(,PDRIVER_UNLOAD,):指向,DriverUnload,入口函数的指针。在驱动程序被从内存中卸载时,DriverUnload入口函数会被操作系统调用,你应该在该函数内部做一些与DriverEntry向对应的资源清除工作。,MajorFunction,(一个数组,数组中每一元素又是一个指向函数的指针 PDRIVER_DISPATCH):数组中每一个指针指向一个入口函数。在接收到不同的请求包(IRP)时,OS会调用不同的入口函数。,13,驱动对象的一些关键字段(一)DriverStartIo(P,驱动对象的一些关键字段(二),DeviceObject,(,PDEVICE_OBJECT,):指向一个链表的指针,该链表中每一个节点都存储了一个FDO对象。每一个FDO都代表一个由该驱动维护的硬件设备实例。,在WDM模型中,该链表由OS自动维护,。,DriverExtension,(,PDRIVER_EXTENSION,):指向另外一个结构体,该结构体中唯一有用的字段为,AddDevice,。AddDevice字段指向一个入口函数。在操作系统发现一个新的设备实例时,它会自动调用AddDevice函数,你应该在该函数中做一些与设备实例相关的初始化工作。,14,驱动对象的一些关键字段(二)DeviceObject(PD,DriverEntry函数的主要工作,在操作系统创建的,驱动对象,中填写其它,入口函数,的地址,使得操作系统在必要的时候能够找到这些入口函数并调用它们。,创建一个或多个设备对象,并将这些对象挂接在驱动对象所指示的链表上。(只针对NT型驱动),与该设备相关的其他初始化工作,VOID(*PDRIVER_UNLOAD)(IN PDRIVER_OBJECT DriverObject);,VOID(*PDRIVER_STARTIO)(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);,NTSTATUS(*PDRIVER_DISPATCH)(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);,NTSTATUS(*PDRIVER_ADD_DEVICE)(,IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject );,15,DriverEntry函数的主要工作在操作系统创建的驱动对象,DriverUnload函数的主要工作,删除以链表形式挂接在,驱动对象,上的一个或多个,设备对象,。(只针对NT型驱动),进行与DriverEntry函数中相对应的,反初始化,工作。例如如果在DriverEntry函数中申请了堆内存,那么在DriverUnload函数中应该释放该堆内存。,VOID DriverUnload(PDRIVER_OBJECT DriverObject),RtlFreeUnicodeString(,16,DriverUnload函数的主要工作删除以链表形式挂接在驱,第二简单的驱动程序,extern,“C”#,include,VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);,NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);,extern,C NTSTATUS DriverEntry(,IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath),NTSTATUS status=STATUS_SUCCESS;,KdPrint(,Enter DriverEntryn,);,KdPrint(,RegistryPath:%wZn,pRegistryPath,);,pDriverObject-DriverUnload=HelloDDKUnload;,pDriverObject-MajorFunctionIRP_MJ_CREATE=HelloDDKDispatchRoutine;,pDriverObject-MajorFunctionIRP_MJ_CLOSE=HelloDDKDispatchRoutine;,pDriverObject-MajorFunctionIRP_MJ_WRITE=HelloDDKDispatchRoutine;,pDriverObject-MajorFunctionIRP_MJ_READ=HelloDDKDispatchRoutine;,KdPrint(,Leave DriverEntryn,);,return,status;,17,第二简单的驱动程序extern“C”#includ,第二简单的驱动程序(续),VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject),KdPrint(,Enter DriverUnloadn,);,KdPrint(,Leave DriverUnloadn,);,NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp),NTSTATUS status=STATUS_SUCCESS;,KdPrint(,Enter HelloDDKDispatchRoutinen,);,KdPrint(,Leave HelloDDKDispatchRoutinen,);,return,status;,18,第二简单的驱动程序(续)VOID HelloDDKUnloa,设备对象(Device Object),针对每一个硬件设备,Windows都需要用一个数据结构来记录它的相关信息,这个数据结构就叫做,设备对象,(,Devcie Object,)。,因为一个驱动程序可以同时管理多个同类型的硬件设备,因此,一个驱动对象可以对应多个设备对象,。,对应同一个驱动对象的多个设备对象构成一个链表挂接在驱动对象的,DeviceObject,字段上。,设备对象由驱动程序负责创建和初始化,由操作系统负责保存和管理。,设备对象可以有名字,其他驱动程序或应用程序可以通过该名字找到该设备对象。,19,设备对象(Device Object)针对每一个硬件设备,W,The Device Object,20,The Device Object20,设备对象的一些关键字段(一),DriverObject(PDRIVER_OBJECT),:指向与该设备对象相对应的驱动对象的指针。,NextDevice(PDEVICE_OBJECT),:指向下一个设备对象的指针,利用该字段与同一个驱动对象对应的多个设备对象就可以构成一个单链表,该链表最后挂接在驱动对象的,DeviceObject,字段上。,21,设备对象的一些关键字段(一)DriverObject(PD,设备对象的一些关键字段(二),Flags(ULONG),:保存了一些标志位,这些标志位指示了该设备的一些工作方式。,DO_BUFFERED_IO,Reads and writes use the buffered method(system copy buffer)for accessing user-mode data.,DO_DIRECT_IO,Reads and writes use the direct method(memory descriptor list)for accessing user-mode data.,DO_EXCLUSIVE,Only one thread at a time is allowed to open a handle.,DO_DEVICE_INITIALIZING,Device object isnt initialized yet.,DO_POWER_PAGABLE,IRP_MJ_PNP must be handled at PASSIVE_LEVEL.,DO_POWER_INRUSH,Device requires large inrush of current during power-on.,22,设备对象的一些关键字段(二)Flags(ULONG):保存,设备对象的一些关键字段(三),Characteristics(ULONG),:,另外一组标志位集合。,DeviceExtension(PVOID),:指向一个扩展内存区,该内存区的大小和使用方式由程序员规定。一般在该区域存放一个自定义的结构体,用于存储硬件设备特有的信息。今后称该结构体为,设备扩展对象,。该扩展内存区由操作系统负责创建并维护。,DeviceType(DEVICE_TYPE),:一个枚举型变量,指明该设备的类型 (,FILE_DEVICE_UNKNOWN,),AlignmentRequirement(ULONG),:指定该设备使用内存时的对齐方式(FILE_BYTE_ALIGNMENT、FILE_WORD_ALIGNMENT FILE_512_BYTE_ALIGNMENT),23,设备对象的一些关键字段(三)Characteristics,如何创建设备对象,利用内核API函数,IoCreateDevice,创建设备对象。OS负责申请并管理设备对象所需内存,并对其中的一些字段按照输入参数做了初始化,最后OS将其挂接在设备对象链表上。,NTSTATUS IoCreateDevice(,IN PDRIVER_OBJECT DriverObject,/设备对象所对应的驱动对象,IN ULONG DeviceExtensionSize,/设备扩展区的大小,IN PUNICODE_STRING DeviceName OPTIONAL,/设备对象名称,IN DEVICE_TYPE DeviceType,/设备类型,IN ULONG DeviceCharacteristics,/设备对象特征,IN BOOLEAN Exclusive,/一般设为TRUE,OUT PDEVICE_OBJECT *DeviceObject,/由操作系统创建的设备对象,/的起始地址利用该参数返回,);,24,如何创建设备对象利用内核API函数 IoCreateDevi,如何删除设备对象,在WDM驱动中,如果接收到,IRP_MN_REMOVE_DEVICE,消息,则应删除设备对象;在NT式驱动中,在,DriverUnload,函数中删除设备对象。,在创建设备对象之后如果出错也应该及时删除对象。,通过调用内核API函数,IoDeleteDevice,删除设备对象,NTSTATUS status=IoCreateDevice(.);,if(!NT_SUCCESS(status),return status;,.,if(),IoDeleteDevice(pdo);,return status;,25,如何删除设备对象在WDM驱动中,如果接收到 IRP_MN_R,设备对象的命名,Windows系统中有一个称为“,对象管理器,”的执行模块复杂集中管理系统中所有的内核对象,其中包括,驱动对象,和,设备对象,。,对象管理器给大多数内核对象都起了名字,并把这些名字组织为具有,树形结构的命名空间,。,设备对象一般都位于该命名空间的,Device,子目录下,其他内核模块和驱动程序都可以通过设备的名字获得该设备对象的指针(利用,IoGetDeviceObjectPointer,),并通过该指针向驱动对象发送IRP。,用户模式的应用程序对,Device,子目录没有访问权,26,设备对象的命名Windows系统中有一个称为“对象管理器”的,设备对象的命名(续),为了给自己的设备对象命名,必须将名字存放在一个,UNCODE_STRING,型的字符串中,并将其作为,IoCreateDevice,的第3个参数传入。,UNICODE_STRING devname;,RtlInitUnicodeString(,IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),27,设备对象的命名(续)为了给自己的设备对象命名,必须将名字存放,设备对象名与符号链接,因为应用程序只能访问Windows内核对象空间中的,“?”,子目录,而对对,Device,子目录没有访问权限,因此必须在,“?”,子目录中创建一个符号链接,将其指向,Device,子目录中的名字。,符号链接就类似于Windows文件系统中的快捷方式,创建符号链接的方法是调用,IoCreateSymbolicLink,28,设备对象名与符号链接因为应用程序只能访问Windows内核对,设备对象名与符号链接(续),UNICODE_STRING devname;,UNICODE_STRING linkname;,RtlInitUnicodeString(,RtlInitUnicodeString(,IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),RtlInitUnicodeString(,IoCreateSymbolicLink(&linkname,&,devname,);,29,设备对象名与符号链接(续)UNICODE_STRING de,应用程序如何通过设备名打开设备,在用户模式下,“?”,子目录叫做,“.”,子目录,因此通过“.”子目录下的符号链接名就可以找到设备对象,并打开指向设备对象的句柄。,hDevice=CreateFile(.Simple1,GENERIC_WRITE|GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);,ReadFile(hDevice,lpBuffer,.);,WriteFile(hDevice,lpBuffer,.);,.,30,应用程序如何通过设备名打开设备在用户模式下“?”子目录,创建完设备对象后还需做什么,设置设备扩展对象的内容,设置设备对象的flags字段设定该设备的工作方式。,fdo-AlignmentRequirement=.,fdo-Flags=DO_BUFFERED_IO DO_POWER_PAGABLE;,创建设备对象栈(可选),等所有准备工作做完之后一定要清除flags字段的DO_DEVICE_INITIALIZING标志告诉OS可以接收IRP了,fdo-Flags,31,创建完设备对象后还需做什么设置设备扩展对象的内容fdo-A,第三个例子程序,32,第三个例子程序32,基于I/O请求包(IRP)的工作方式,33,基于I/O请求包(IRP)的工作方式33,应用程序与驱动程序的通信,Windows应用程序与WDM通信的一般过程是:应用程序先用,CreateFile,函数打开设备,然后用,ReadFile,从WDM中读取数据,用,WriteFile,函数向WDM写数据,用,DeviceIoControl,函数向WDM发送自定义的控制信息,最后用,CloseHandle,函数关闭设备。对于异步IO请求还可以用,CancelIo,函数取消。,这些函数调用使得IO管理器产生相应的IRP发送给驱动程序,Win32函数,IRP主功能代码,Parameters结构,CreateFile,IRP_MJ_CREATE,Create,ReadFile,IRP_MJ_READ,Read,WriteFile,IRP_MJ_WRITE,Write,DeviceIoControl,IRP_MJ_DEVICE_CONTROL,DeviceIoControl,CloseHandle,IRP_MJ_CLOSE/CLEANUP,Close,34,应用程序与驱动程序的通信Windows应用程序与WDM通信的,第四个例子程序,35,第四个例子程序35,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!