《现代微机原理与接口技术接口第10章.ppt》由会员分享,可在线阅读,更多相关《现代微机原理与接口技术接口第10章.ppt(75页珍藏版)》请在三一办公上搜索。
1、1,第10章 PC机的高级编程技术,2,10.1 PC机环境下软件对接口的访问层次,裸机,BIOS,直接访问,操作系统驱动程序,间接访问,应用程序,3,1.直接访问层次,特点:可以直接进行内存和端口的访问,也可以自行决定是否在实模式和保护模式间切换。通常所有的端口和内存都是对程序员开放的。工具:汇编语言或C语言。应用:BIOS都是基于这种低级层次用汇编来编写的。驱动程序也有使用这种方法的。优点:能够编写速度最快,占用空间最小的有效代码。缺点:需要对硬件和接口有很熟悉的了解。要会汇编,或熟练使用C语言的指针。不利于增加对新设备的控制。,4,2.BIOS访问层次,特点:通过BIOS提供的功能调用间
2、接地对内存或端口访问,从而控制硬件。工具:汇编语言或C语言。应用:驱动程序有些会使用这些功能调用。需要获得高效率的应用程序也采用这种方法。优点:能够编写速度较快的有效代码。可以不需要编写直接对硬件进行控制的代码。缺点:需要对底层信号有所了解。增加对新设备的控制不是很方便,但好于低级层次。,5,3.驱动程序层次,特点:使用BIOS功能调用和直接内存访问的方法编写符合特定操作系统管理规范的设备驱动程序。工具:VC+与DDK开发包,或第三方开发工具如DriverStudio。应用:在操作系统层面上的设备控制,并为应用程序提供API支持。优点:既控制硬件,又保证操作系统的完整与安全。缺点:需要对底层信
3、号有所了解。需要对操作系统的各个管理模块有深入的了解。,6,4.应用层次,特点:使用操作系统各种驱动程序所提供的功能调用或API函数间接对硬件或内存进行访问。工具:VC+、Delphi、Java等。应用:编写面向终端用户的各类应用程序。优点:无需对硬件控制有太多了解,只需完成应用层面的工作就可以,而且还保证操作系统的完整与安全。缺点:需要了解大量的API和功能调用函数的功能。由于是间接调用,所以代码的效率和编译系统有很大的关系。,7,16位段地址,16位段内偏移,:,6417H0100H 6417H10H+0100H=64170H+0100H=64270H,采用了内存分段的办法,内存分为若干段
4、,段的大小根据需要决定,最大为64KB,10.2.1 实地址模式的存储管理(同PC/XT),10.2 Pentium 4的内存管理接口直接访问,8,000000,0A0000,100000,110000,FFFFFF,640KB常规内存,384KB高端内存,64KB高内存区,14095MB扩展内存,存放用户程序和DOS驻留部分,存放显存、网卡和部分用户的DOS驱动程序和BIOS,存放部分DOS驻留程序,大于1M以上的 扩展内存,DOS下不能直接访问,需要用XMS规范使用。可利用DOS调用或BIOS调用来使用。,9,10.2.2 保护模式下使用的系统地址寄存器,GDTR 48位的全局描述符表寄存
5、器,全局描述符表32位线性地址,16位界限值,IDTR 48位的中断描述符表寄存器,中断描述符表32位线性地址,16位界限值,TR 16位的任务状态段寄存器,TSS的16位选择字,LDTR 16位的局部描述符选择字寄存器,LDT的16位选择字,10,10.2.3 保护模式下Pentium 4的段式存储管理,1.段式管理的地址变换,段寄存器的152位,偏移量,45 32,31 0,段描述符,段表,32位线性地址,物理地址,逻辑地址,段基址,Pentium 系列的虚拟地址空间是24664TB。,11,2.段描述符,12,D7 D0,AVL,G,D/B,0,段界限 1916,用户的操作系统可用位,D
6、/B位,代码段(D位),D=1 使用32位操作系统和32位寻址方式,D=0 使用16位操作系统和16位寻址方式,数据段(B位),B=1 使用ESP寄存器,上限为FFFFFFFFH,B=0 使用SP寄存器,上限为FFFFH,G=0 段长以1字节为单位,G=1 段长以4K字节为单位,D/B位,粒度位,13,D7 D0,存在位,特权位,S=1是非系统段S=0是系统描述符,代码段标志,数据段标志,兼容位,可读位,访问位,扩展方向位,可写位,非系统段中的第5字节,可执行位,14,系统描述符中的TYPE,15,RPL,Ti,选择符(段寄存器),15 2 1 0,索引,Ti=1,Ti=0,0,1,0,1,L
7、DT,LDT,LDT,GDT,基址,界限,选择符,基址,界限,LDTR,GDTR,2,2,16,#include stdafx.h#include#include/wtypes.h定义了WORDLONG,/DWORD,WORD等数据类型DWORDLONG gdtr,savegdt;/下面是GDT中将创建的数据段描述符表,基地址0X00000F00,/段界限为0XFFFF,优先级为3的在内存中的可写数据段WORD descriptor4=0 xFFFF,0X0F00,0XF200,0X0040;int result10;int main(int argc,char*argv)_asm pushe
8、bpsgdtgdtr/将GDTR寄存器的内容读取到/gdtr开始的6个字节中,其中/前两个字节给出GDT的界限值,/高4个字节给出GDT的基地址,17,movebp,dword ptr gdtr+2/将gdt的基/地址读到EBP中addebp,70h/我们选择70H偏移下的段描述/符(GDT中第14个描述符)leaedi,savegdtmovesi,ebpmovsd/以上4条指令保存原来在70H偏移上movsd/的描述符movedi,ebpleaesi,descriptor;movsd/把我们的数据段描述符装入70Hmovsd/偏移上pushesmovax,0073h/选择字为描述符偏移70H
9、拼接上/低3位控制位元,其中Ti为0,表/示访问GDT,RPL为11,为3级优/先级,所以就为73H,18,moves,ax/ES装入选择字73Hleaedi,result/将存放输出结果的变量/的地址放在EDI中moveax,1movebx,1_asmmovcx,10a1:moves:eax,eaxaddeax,4loopa1/上面4条指令将向物理地址/0X00000F00处写10个双字_asmmovcx,10a2:moveax,es:ebxmovedi,eax,19,addebx,4addedi,4loopa2/以上从物理地址0X00000F00/处依次读出10个数据存放在/result数
10、组中_asmpopespopebp printf(result=);for(int i=0;i10;i+)printf(%d,resulti);/输出结果return 0;,20,10.2.4 保护模式下Pentium 4的虚拟页式存储管理,主存,页框,页面,程序1,程序2,程序3,21,22,4KB分页方式,P=出现位,US=用户/监督位,PCD是页Cache禁止,D=Cache“脏”位,RW=读/写位,PWT=页写贯穿位,A=访问位,AVL=用户的操作系统可用位。而第7位(PS)在4KB分页中为0,23,4MB分页方式,24,Pentium III 36位地址下的4KB分页方式地址转换,2
11、5,Pentium III 36位地址下的2MB分页方式地址转换,26,10.3.1 虚拟机与VxD的引入,特权级3,特权级0,10.3 Windows 9x驱动程序编写,27,Windows 9x,SYSVM,Win16地址空间,Win16程序,Win16程序,Win16程序,Win16程序,Win32程序,Win32地址空间,Win32程序,Win32地址空间,DOSVM,DOS程序,DOSVM,DOS程序,28,10.3.1保护模式下的I/O端口访问,执行in,out指令,CPL IOPL?,IOPM相关位=0?,进行I/O操作,否,否,产生一个一般保护异常,是,是,IOPM是对所有VM
12、都起作用的权限机制,它以位(bit)来代表每个端口。某位为1,则该代表的端口被禁止访问;某位为0;则允许访问该位所代表的端口。,IOPL用以表示指定的I/O操作处于特权级的哪一级。它在EFLAGS中。CPL当前段的I/O优先级,它实际上是CS段选择符的第0第1位。,29,V86模式下(DOSVM)的I/O端口访问,执行in,out指令,IOPM相关位=0?,进行I/O操作,否,产生一个一般保护异常,是,如何捕获一个端口的访问?,30,31,10.3.2 保护模式下对中断或异常的处理,外部中断和处理器异常,软中断,CPL 门描述符的DPL?,是,访问各类门描述符,转移后代码段的DPLCPL?,是
13、,执行0特权级别中的中断处理程序,禁止访问,否,否,32,CPU根据中断向量表IDT调用相应的VMM异常处理程序,从而切换到0特权级别。其他各种VxD可以通过安装回调例程来响应处理各种异常和中断,但是它们不能改变中断描述符表IDT中给出的各种VMM异常处理程序。VMM异常处理程序通过使用CALL指令调用安装的各个回调例程或自身处理异常。对于硬件中断,VMM则将控制权交给 VPICD(虚拟可编程中断控制器)处理,VPICD就调用其他VxD通过系统服务VPICD_Virtualize_IRQ安装的回调例程处理硬件中断。,一个回调例程要么处理中断和异常,要么忽略该中断,但是它必须使用RET指令返回到
14、VMM异常处理程序。,33,VMM异常处理程序使用IRET或IRETD指令返回到虚拟机中,虚拟机中的应用程序重新获得控制从而继续执行。,Win32程序,虚拟机,VxD中的回调函数,异常处理程序,VPICD,34,特殊应用:如何利用保护模式下中断的处理流程设法使自己从用户级转到核心级?,35,#include stdafx.h#include#include/wtypes.h定义了DWORDLONG,/DWORD,WORD等数据类型DWORD_cr0;/用来保存CR0寄存器的值void _declspec(naked)newint3(void)/运行在核心级的/中断3处理程序_asmmoveax
15、,cr0/这是必须在核心级才能执行的/特权指令mov_cr0,eax_asmiretd/中断返回(为什么不是ret?),36,int main(int argc,char*argv)DWORDLONG idtr,saveidt;WORDnewgate4=0 x0000,0 x0028,0 xee00,0 x0000;/中断门描述符,DPL=3_asmsidtidtr/将IDTR的值存在idtr变量开/始的6个字节中movebx,DWORD ptridtr+2/把IDT的/基地址读入EBX寄存器addebx,24/选择中断3作为进入核心级的/入口,中断3的门描述符/的地址是IDT基地址加上3*8
16、/(每个门描述符8个字节)movesi,ebxleaedi,saveidt,37,movsd/保存原来中断3的门描述符movsd/到saveidt中leaeax,newint3movnewgate,axshreax,16movnewgate+6,ax/向新的中断描述符中填入/中断处理程序的入口偏移量leaesi,newgatemovedi,ebxmovsd/用新中断描述符在IDT中movsd/替换原来的中断3描述符int3h/触发中断3,使程序跳转到/0级执行中断处理程序,38,leaesi,saveidtmovedi,ebxmovsdmovsd/恢复原来中断3的门描述符 printf(cr0
17、=0 x%x,_cr0);/输出结果 return 0;,39,10.3.3 虚拟设备驱动程序(VxD)基础,1.VxD的文件结构,VxD的五个段,VxD_CODE 保护模式下的代码段含设备驱动程序回调例程、服务程序、API接口函数和控制程序。VxD_DATA 保护模式下的数据段包含设备描述块、服务表、全局变量等。VxD_ICODE 保护模式下的初始化代码段初始化的时候用的服务程序和过程。初始化后被丢弃VxD_IDATA 保护模式下的初始化数据段初始化时用的数据。初始化后被丢弃。VxD_REAL_INIT 实模式下的初始化资料与代码该过程返回后被丢弃。,40,typedef struct ta
18、gDDB DWORDDDB_Next;/VMM使用这一项来指出/下一个DDB的地址WORDDDB_SDK_Version;/建立该VxD所使用的/SDK/DDK的版本号WORDDDB_Req_Device_Number;/设备ID。/UNDEFINED_DEVICE_ID表示/不使用唯一IDBYTEDDB_Dev_Major_Version;/VxD的主版本号BYTEDDB_Dev_Minor_Version;/VxD的次版本号WORDDDB_Flags;/DDB标志位BYTEDDB_Name8;/VxD的名字,不足8个字节必须/以空格补满DWORDDDB_Init_Order;/指定VxD的
19、初始化顺序,如果没/有特别的初始化要求就使用/UNDEFINED_INIT_ORDERDWORDDDB_Control_Proc;/设备控制程序的地址DWORDDDB_V86_API_Proc;/V86API程序的入口地址,2.VxD的设备描述符块DDB,41,DWORDDDB_PM_API_Proc;/保护模式API程序的入口地址DWORDDDB_V86_API_CSIP/V86入口点的CS:IPDWORDDDB_PM_API_CSIP;/保护模式入口点的CS:IPDWORDDDB_Reference_Data;/实模式初始化代码设置的参/考资料DWORDDDB_VxD_Service_Ta
20、ble_Ptr;/VxD服务表的地址DWORDDDB_VxD_Service_Table_Size;/VxD服务表中提/供的VxD服务的数目 DDB;,42,3.VxD的加载与卸载,动态加载,hDevice=CreateFile(.myfirst.vxd,0,0,0,OPEN_EXISTING,FILE_FLAG_DELETE_ON_CLOSE,0);DeviceIoControl(hDevice,DIOC_MY_IO,NULL,0,NULL,0,NULL,NULL);CloseHandle(hDevice);,43,静态加载,44,10.4 Windows 2000/XP设备驱动程序设计,1
21、0.4.1 Windows 2000/XP的设备驱动程序,虚拟设备驱动程序(VDD),内核模式驱动程序,文件系统驱动程序,保留设备驱动程序,PnP驱动程序,显示驱动程序,WDM驱动程序,类驱动程序,迷你驱动程序,可以使DOS应用程序访问x86平台上的硬件,也可以支持Windows 9x下的对端口访问,是一种遵循电源管理协议并能在Windows 98和Windows 2000间实现源代码级兼容的PnP驱动程序,用于显示和打印设备的内核模式驱动程序,在本地硬盘或网络上实现标准PC文件系统模型(包括多层次目录结构和命名文件概念),主要包括Windows NT早期版本的驱动程序,它直接控制一个硬设备而
22、不用其他驱动程序帮助,可以不做修改地在Windows 2000中运行,45,10.4.2 WDM的基本结构,1.基本概念,设备对象:系统为帮助软件管理硬件而创建的一个数据结构。一个物理设备可以有多个这样的数据结构。物理设备对象:简称PDO,处于设备对象栈最底层的设备对象。每个物理设备被创建一个PDO功能设备对象:简称FDO,在PDO之上,描述设备功能的相关数据结构。过滤器设备对象:简称FiDOs,在FDO的上面或下面,分别称为上层过滤器和下层过滤器。用于修改现有功能驱动程序的行为。设备对象栈:设备对象栈代表处理请求的驱动程序层次。,46,FiDO,FDO,FiDO,PDO,上层过滤器驱动程序,
23、功能驱动程序,下层过滤器驱动程序,总线驱动程序,IRP,I/O系统服务,Win32子系统,应用程序,I/O管理器,用户态,核心态,设备对象栈,46页,47,WDM驱动程序模型中,每个硬件设备可以有多个驱动程序:功能驱动程序:管理FDO所代表的设备,负责其初始化、处理I/O操作完成时产生的中断事件并为用户提供一种适当的设备控制方式。过滤器驱动程序:用于监视和修改IRP流。硬件或软件人员可利用过滤器驱动程序修改现有功能驱动程序的行为。总线驱动程序:负责管理硬件和计算机之间的连接。这个驱动程序实际上和同类设备共同拥有。如PCI总线驱动程序。,2.硬件设备的驱动程序种类,48,总线驱动程序检测到新的硬
24、件,用户使用控制面板中的“添加新硬件”向导安装一个设备,PnP管理器为该设备和它的驱动程序在注册表的配置表中添加一些条目,PnP管理器可能需要调整已经分配给已存在设备的资源,使需要的资源对新设备可用,3.设备驱动程序安装的顺序,硬件接入,PnP管理器创建PDO,49,驱动程序被装入后,执行DriverEntry程序。来设置驱动程序中各个例程的入口地址,PnP管理器参照注册表中的信息查找与创建的PDO相关的过滤器和功能驱动程序,PnP管理器装入最底层的过滤器驱动程序并调用其AddDevice函数。该函数创建一个FiDO,从而在过滤器驱动程序和FiDO之间建立了水平连接,按照INF文件的指令安装驱
25、动程序,50,PnP管理器继续向上执行,依次装入并调用每个低层过滤器、功能驱动程序和每个高层过滤器,直到完成整个设备对象栈,AddDevice把PDO连接到FiDO上,PnP管理器给设备发送各种PnP IRP,PnP管理器给发送“启动设备”PnP IRP告诉驱动程序已经给它分配了哪些资源,驱动程序使用这些资源分配启动它的设备,驱动程序处于等待处理IRP的状态,51,当应用程序因要向驱动程序提出各类请求(如读、写数据等)而调用相关函数的时候,就会使得I/O管理器创建一个I/O请求包(IRP)。通常一个I/O请求包(IRP)先被送到设备对象栈的最上层驱动程序然后逐渐过滤到下面的驱动程序。每一层驱动
26、程序都可以决定如何处理IRP,既可以直接处理完该IRP就不再向下传,也可以处理完后继续传递,还可以只做向下传递的工作。当下层将请求处理完,返回的信息又通过该包的结构逐层向上传递。,4.IRP传递的顺序,46页,52,10.4.3 I/O请求包(IRP),I/O请求包(IRP)是驱动程序操作的中心,它是一个内核“对象”,是预先定义的数据结构,带有一组对它进行操作的I/O管理器程序。I/O管理器接收到一个I/O请求后,在把它传递到合适的驱动程序栈中的最高驱动程序之前,分配并初始化一个IRP。一个IRP有一个固定的首部和一个可变数目的I/O栈。,53,54,创建异步IRP的IoBuildAsynch
27、ronousFsdRequest创建同步IRP的IoBuildSynchronous-FsdRequest创建同步IRP_MJ_DEVICE_CONTROL或IRP_MJ_INTERNAL_DEVICE_CONTROL请求的IoBuildDeviceIoControlRequest创建其他种类IRP的IoAllocateIrp创建某些IRP的子IRP的IoMakeAssociatedIrp。,创建IRP的可以是I/O管理器,也可以是其他的驱动程序。能创建IRP的函数有:,55,在创建一个IRP时,同时还创建了一个与之关联的IO_STACK_LOCATION结构数组,它是I/O栈中的一项,它包含
28、的成员包括:MajorFunction(该IRP的主功能码)MinorFunction(该IRP的副功能码)Parameters(IRP参数)DeviceObject(与该栈单元对应的设备对象地址)FileObject(内核文件对象地址)CompletionRoutine(I/O完成程序地址)Context(任意的与上下文相关的值)。,56,在栈Parameters成员中,有几个常用的的参数:Create(IRP_MJ_CREATE请求,创建IRP)Close(IRP_MJ_CLOSE请求,关闭IRP)Read(IRP_MJ_READ请求,读IRP)Write(IRP_MJ_WRITE请求,写
29、IRP)StartDevice(IRP_MJ_PNP的IRP_MN_START_DEVICE请求,启动设备)DeviceIOControl(IRP_MJ_IOCTL请求,IOCTL IRP)。,57,大部分参数可以和Win32函数对应起来,返回,58,创建完IRP后,可以使用下面的代码做必要设置,并把IRP发送到设备驱动程序。PDEVICE_OBJECT DeviceObject;/设备对象结构PIO_STACK_LOCATION stack=IoGetNextIrpStackLocation(Irp);/获得该IRP第一个堆栈单元的指针stack-MajorFunction=IRP_MJ_X
30、xx;/填充MajorFunction代码/可以对栈做其他初始化的工作/这里可能运行StartIoNTSTATUS status=IoCallDriver(DeviceObject,Irp);/把IRP发送到设备驱动程序,返回,59,下面是IoCallDriver的执行过程:NTSTATUS IoCallDriver(PDEVICE_OBJECT device,PIRP Irp)IoSetNextIrpStackLocation(Irp);PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp);/获得栈单元指针 stack-Devi
31、ceObject=device;/设置设备对象结构地址 ULONG fcn=stack-MajorFunction;/得到主功能号 PDRIVER_OBJECT driver=device-DriverObject;/获得驱动程序对象的地址 return(*driver-MajorFunctionfcn)(device,Irp);/利用主功能号调用相应的派遣函数,*driver-MajorFunctionfcn是函数指针,它所指向的派遣函数是在DriverEntry例程中指定的。,返回Driverentry,返回,60,10.4.4 WDM驱动程序的结构,WDM驱动程序包含许多函数(例程),操
32、作系统调用这些例程来执行对IRP的各种操作。,基本驱动程序函数,I/O控制函数,派遣函数,DriverEntry,AddDevice,StartIO,AdapterControl,OnInterrupt,DpcForIsr,DispatchPnp,DispatchPower,DispatchWmi,DispatchRead,DispatchWrite,StartIO处理请求队列、AdapterControl处理DMA操作OnInterrupt处理中断。,61,在每个WDM驱动程序中,下列函数必须有:,DriverEntry函数:这个例程是每一个设备驱动程序的入口。在这个例程中完成某些全局初始化
33、工作,还要设置响应各种用户请求的分发例程与I/O控制例程的入口。AddDevice函数:对于功能驱动程序,其AddDevice函数的基本职责是创建一个设备对象并把它连接到以PDO为底的设备堆栈中。DispatchPnp函数:用于处理IRP_MJ_PNP消息,以便能实现即插即用的功能。DispatchPower函数:用于实现对电源管理的支持。DispatchWmi函数:WMI是微软实现的基于Web的企业管理工业标准,该函数用于处理有关的消息。,62,下面是一段DriverEntry程序的片段:extern C NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driv
34、erObject,IN PUNICODE_STRING RegistryPath)/初始化函数的入口地址 DriverObject-DriverUnload=DriverUnload;DriverObject-DriverExtension-AddDevice=AddDevice;DriverObject-DriverStartIo=StartIo;DriverObject-MajorFunctionIRP_MJ_PNP=DispatchPnp;DriverObject-MajorFunctionIRP_MJ_POWER=DispatchPower;DriverObject-MajorFunc
35、tionIRP_MJ_SYSTEM_CONTROL=DispatchWmi;/这里可以加入其他MajorFunction处理函数的入口地址,返回,63,/如果驱动程序需要访问设备的服务键,则备份RegistryPathservkey.Buffer=(PWSTR)ExAllocatePool(PagedPool,RegistryPath-Length+sizeof(WCHAR);if(!servkey.Buffer)return STATUS_INSUFFICIENT_RESOURCES;servkey.MaximumLength=RegistryPath-Length+sizeof(WCHAR
36、);RtlCopyUnicodeString(&servkey,RegistryPath);return STATUS_SUCCESS;,64,添加一个设备NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject,PDEVICE_OBJECT pdo)NTSTATUS status;PDEVICE_OBJECT fdo;Status=IoCreateDevice(DriveObject,sizeof(WDM_DEVICE_EXTENSION),NULL,FILE_DEVICE_UNKNOWN,0,FALSE,&fdo);/在fdo中产生我们的功能设备对象 i
37、f(NT_ERROR(status)Return status;,65,下面是IRP派遣函数的一个框架:NTSTATUS DispatchXxx(PDEVICE_OBJECT device,PIRP Irp)PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp);/获得栈单元指针 PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)device-DeviceExtension;/获得设备扩展/其他IRP处理操作 return STATUS_Xxx;/返回状态码,返回,66,对WDM请求包运行机制的总结,
38、应用程序通过CreateFile等Win32函数来进行有关的请求。I/O管理器创建IRP。设置IRP中的主功能代码和对IRP栈做各种初始化工作。如果需要对IRP排队,则调用StartIo处理IRP队列将IRP发送到派遣程序(按照DriverEntry中指定的入口地址来调用相关的派遣程序)。执行有关的派遣程序,实际处理对IPR的操作。,67,10.4.5 即插即用,支持即插即用主要是指实现一个AddDevice程序和一个IRP_MJ_PNP处理程序。这个PnP IRP有8个次功能代码(它们的主功能代码都是IRP_MJ_PNP)。,IRP_MN_START_DEVICE分配资源并启动设备IRP_M
39、N_QUERY_REMOVE_DEVICE询问一个设备是否可以删除IRP_MN_REMOVE_DEVICE设备被拔出,删除设备 IRP_MN_CANCEL_REMOVE_DEVICE取消查询删除请求IRP_MN_STOP_DEVICE停止设备进行资源重新分配IRP_MN_QUERY_STOP_DEVICE询问设备是否可以停止IRP_MN_CANCEL_STOP_DEVICE取消查询停止请求 IRP_MN_SURPRISE_REMOVAL用户在意外下拔出设备,68,NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo,PIRP Irp)PIO_STACK_LOCATIO
40、N stack=IoGetCurrentIrpStackLocation(Irp);ULONG fcn=stack-MinorFunction;/取副功能码 static NTSTATUS status=STATUS_SUCCESSswitch(fcn)/按照副功能码调用相关的处理函数 case IRP_MN_START_DEVICE:HandleStartDevice(fdo,Irp);break;case IRP_MN_QUERY_REMOVE_DEVICE:HandleQueryRemove(fdo,Irp);if(fcn=arraysize(fcntab)return DefaultP
41、npHandler(fdo,Irp);return status;,69,10.4.6 数据的读/写,WDM有4个标准的资源类型,分别是:CmResourceTypePort(端口资源)CmResourceTypeMemory(内存资源)CmResourceTypeInterrupt(中断资源)CmResourceTypeDma(DMA资源),70,1.内存与端口访问,尽管PC机的I/O端口是单独编址的,但为了做到和统一编址的机器兼容性,Windows 2000的设计者使用了硬件抽象层(HAL)的概念。无论是单独编址还是统一编址,只需要使用下表8中所给的函数就可以访问端口和内存了。,71,72
42、,2.响应中断,响应中断首先要配置中断,也就是截获中断,然后就需要编写中断处理程序。配置中断资源是在StartDevice函数中实现的,使用从CmResourceTypeInterrupt描述符中得到的参数来调用IoConnectInterrupt函数。和实模式下一样,在调用IoConnectInterrupt进行中断配置前应该禁止PC机的中断,调用之后再允许设备中断。,73,10.4.7 WDM驱动程序的安装文件,驱动程序根据INF文件中的指令安装。INF文件含有安装一个WDM设备驱动程序需要的所有必需的信息,包括要复制的文件列表和要创建的注册表项等。驱动程序可执行文件被复制到正确的位置,通常是WinntSystem32Drivers目录,然后创建各种注册表项。,INF文件是一个文本文件,它由节组成,每一节从括在方括号中的节名称开始,后面是节的内容,大部分段都含有一系列“keyword=value”形式的项。,74,75,