已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、三种类型的WDM驱动程序 总线驱动程序(bus driver) 功能驱动程序(function driver) 过滤驱动程序(filter driver)2、其他分类方法 类驱动程序(class driver) 端口驱动程序(port driver) 小端口驱动程序(miniort driver)3、驱动程序对象(DRIVER_OBJECT)主要成员 DeviceObject: 指向一个设备对相链表,每个设备对象代表一个设备。 DriverExtension: 一个结构体, 该结构只有AddDevice成员可以直接访问。 DriverStartIo: 指向驱动程序中处理I/O请求的函数。 DriverUnload: 指向驱动程序中的清除函数。 MajorFunction: 为一个函数指针表, 指向存在于驱动程序中的各个IRP处理函数, 它定义了I/O请求如何进入驱动程序。4、设备对象(DEVICE_OBJECT)主要成员 DriverObject: 指向与该设备对象相关的驱动程序对象。过滤驱动程序有时需要用这个指针来寻找被过滤设备的驱动程序对象。 CurrentIrp: 指向最近发往驱动程序StartIo函数的I/O请求包。 Flags: 包含一组标志位 DO_BUFFERED_IO: 读写操作使用缓冲方式(系统复制缓冲区)访问用户模式数据 DO_EXCLUSIVE: 一次只允许一个线程打开设备句柄 DO_DIRECT_IO: 读写操作使用直接方式(内存描述符表)访问用户模式数据 DO_DEVICE_INITIALIZING: 设备对象正在初始化 DO_POWER_PAGABLE: 必须在PASSIVE_LEVEL级上处理IRP_MJ_PNP请求 DO_POWER_INRUSH: 设备上电期间需要大电流 Characteristics: 包含另一组标志位,描述设备的可选特征 FILE_REMOVABLE_MEDIA: 可更换媒介设备 FILE_READ_ONLY_DEVICE: 只读设备 FILE_FLOPPY_DISKETTE: 软盘驱动器设备 FILE_WRITE_ONCE_MDEIA: 只写一次设备 FILE_REMOTE_DEVICE: 通过网络连接访问的设备 FILE_DEVICE_IS_MOUNTED: 物理媒介已在设备中 FILE_DEVICE_SECURE_OPEN: 在打开操作中检查设备对象的安全属性 DeviceType: 一个枚举常量,描述设备类型。 FILE_DEVICE_PRINTER: 打印机 FILE_DEVICE_SCANNER: 扫描仪 . FILE_DEVICE_UNKNOWN: 未知设备5、驱动程序对象与设备对象的关系 一方面, 驱动程序对象通常有多个与它相关的设备对象,因此它利用DeviceObject指针指向一个设备对象列表,该列表表示驱动程序可以控制的物理设备。 另一方面, 设备对象反过来指向它自己的驱动程序对象, 这样I/O管理器就知道在接收一个I/O请求时应该调用哪个驱动程序。每个功能码都对应一个驱动程序的入口点。6、I/O请求包(IRP) IRP是I/O系统用来存储处理I/O请求所需信息的地方, I/O管理器在IRP中保存一个指向调用者文件对象的指针。从编程的角度看, IRP是I/O管理器在响应一个I/O请求时从非分页系统内存中分配的一块可变大小的数据结构内存, I/O管理器每收到一个来自用户的请求就创建一个该结构,并将其作为参数传给驱动程序的DispatchXxx、StartIo等例程。该结构中存放有请求的类型、用户缓冲区的首地址、用户请求数据的长度等信息。驱动程序处理完这个请求后, 也在该结构中添加处理结果的有关信息, 然后调用IoCompleteRequest将其返回给I/O管理器, 用户程序的请求随即返回。 每个IRP可以被看成由两部分组成: 固定部分和一个I/O堆栈。IRP的固定部分包含关于请求的信息, I/O堆栈则包含一系列I/O堆栈单元(I/O Stack location), 单元的数目应与驱动程序堆栈中处理这一请求的驱动程序数目相同, 每个单元对应一个将处理该IRP的驱动程序。 IRP固定部分的域 MdlAddress(Memory Descriptor List, MDL): 指向一个内存描述表。当驱动程序使用直接I/O时, MDL用来描述一个与该请求相关联的用户模式缓冲区 AssociatedIrp: 该域是一个三指针联合, 其中与WDM驱动程序相关的指针是AssociatedIrp.SystemBuffer。如果设备执行缓冲I/O, 则SystemBuffer指针指向系统空间缓冲区, 否则为NULL。 RequestorMode: 取值为一个枚举常量UserMode或KernelMode, 指定请求初始化的模式为用户模式还是核心模式。驱动程序有时需要查看这个值来决定是否需要信任某些参数 Cancel: 该域为BOOLEAN类型。如果为TRUE, 则表明IoCancelIrp已被调用, 该函数用于取消这个请求。如果为FALSE, 则表明没有调用IoCancelIrp函数 CancelIrql: 一个IRQL(I/O Request Query Level)值, 表明那个专用的取消自旋锁是在这个IRQL上获取的。当驱动程序在取消例程中释放自旋锁时应该参考这个域 CancelRoutine: 指向驱动程序取消例程的地址。应该使用IoSetCancelRoutine函数设置CancelRoutine域而不是直接修改该域 IRP堆栈单元中的域 任何内核模式程序在创建一个IRP时, 同时还创建了一个与之关联的I/O堆栈。堆栈中的I/O堆栈单元由IO_STACK_LOCATION结构定义, 每个堆栈单元都对应一个将处理的IRP的驱动程序。为了在一个给定的IRP中确定当前的IRP I/O堆栈单元, 驱动程序可以调用IoGetCurrentIrpStackLocation函数, 该函数返回当前I/O堆栈单元的指针。 MajorFunction: 该IRP的主要功能代码, 它指出所要执行的I/O操作类型。例如: 主功能代码IRP_MJ_READ表示通过Win32 API函数CreateFile发送的请求。主功能代码与驱动程序对像的MajorFunction表中的某个分发函数指针相对应。 MinorFunction: 该IRP的副功能代码, 它进一步指出该IRP属于哪个主功能类。例如: IRP_MJ_PNP请求有十几个副功能代码, 包括IRP_MN_START_DEVICE、IRP_MN_REMOVE_DEVICE等。 DeviceObject: 指向该堆栈单元对应的设备对象地址, 该域由IoCallDriver函数负责填写。 FileObject: 指向与一个I/O请求有关的文件对象地址。 I/O功能代码 IRP_MJ_CREATE: 打开设备 CreateFile IRP_MJ_CLEANUP: 在关闭设备时, 取消挂起的I/O请求 CloseHandle IRP_MJ_CLOSE: 关闭设备 CloseHandle IRP_MJ_READ: 从设备获得数据 ReadFile IRP_MJ_WRITE: 向设备发送数据 WriteFile IRP_MJ_DEVICE_CONTROL: 对用户模式或内核模式客户可用的控制操作 DeviceControl IRP_MJ_INTERNAL_DEVICE_CONTROL: 只对内核模式客户程序可用的控制操作 没有对应的Win32 API IRP_MJ_QUERY_INFORMATION: 得到文件的长度 GetFileLength IRP_MJ_SET_INFORMATION: 设置文件的长度 SetFileLength IRP_MJ_FLUSH_BUFFERS: 写输出缓冲区或丢弃输入缓冲区 FlushFileBuffers FlushConsoleInputBuffer PureComm IRP_MJ_SHUTDOWN: 系统关闭 InitialSystemShutdown7、单层驱动程序的I/O请求 I/O请求经过子系统DLL 子系统DLL调用I/O管理器的NtWriteFile服务 I/O管理器分配一个描述该请求的IRP, 并通过调用IoCallDriver函数向驱动程序(这里指设备驱动程序)发送请求 驱动程序将IRP中的数据传输到设备并启动I/O操作 通过中断CPU, 驱动程序发信号进行I/O完成操作 在设备完成操作并且中断CPU时, 设备驱动程序服务于中断 驱动程序调用IoCompleteRequest函数表明它已经处理完IRP请求, 接管I/O管理器完成I/O请求 驱动程序可用的内核态例程:Ex. 执行支持Hal. 硬件抽象层(仅NT/Windows 2000)Io. I/O管理器(包括即插即用例程)Ke. 内核Mm. 内存管理器Ob. 对象管理器Po. 电源管理Ps. 进程结构Rtl. 运行时库Se. 安全引用监视Zw. 其他例程总线驱动程序和类特定的例程:BatteryClass. 小类驱动程序的电池类例程Hid. 人工输入设备(HID)例程Pc. 用于小端口驱动程序的SCSI Tape类例程Usb. 用于USB客户驱动程序的通用串行总线驱动程序接口例程IRP_MJ_CREATE 创建或打开设备文件IRP_MJ_CLOSE 关闭句柄IRP_MJ_READ 读IRP_MJ_WRITE 写IRP_MJ_CLEANUP 取消文件句柄上的任何等待的IRPIRP_MJ_DEVICE_CONTROL 设备I/O控制IRP_MJ_INTERNAL_DEVICE_CONTROL 来自高层驱动程序的I/O控制IRP_MJ_SYSTEM_CONTROL WMIIRP_MJ_POWER 电源管理请求IRP_MJ_PNP 即插即用消息IRP_MJ_SHUTDOWN 关闭通知UNICODE_STRING结构定义:typedef struct _UNICODE_STRING USHORT Length; USHORT MaximumLength; PWSTR Buffer; UNICODE_STRING, *PUNICODE_STRING;Buffer域指向一个宽16位字符(双字节)缓冲区,该字符串通常不是NULL终止的,而是由Length域指定字符串的当前大小(字符数)UNICODE_STRING函数:RtlAnsiStringToUnicodeString: 把ANSI字符串转换成Unicode字符串,可选地分配一个缓冲区RtlAppendUnicodeStringToString: 把一个Unicode字符串追加到另一个Unicode字符串,直到目标缓冲区的最大长度RtlAppendUnicodeToString: 追加一个宽字符串到Unicode字符串,直到目标缓冲区的最大长度RtlCompareUnicodeString: 比较两个Unicode字符串,可选择不区分大小写RtlCopyUnicodeString: 把一个Unicode字符串复制到另一个Unicode字符串,直到目标缓冲区的最大长度RtlEqualUnicodeString: 如果两个Unicode字符串相等,返回TRUE,可选择不区分大小写RtlInitUnicodeString: 设置Unicode字符串缓冲区指向指定的宽字符串,并设置长度域为匹配值RtlIntegerToUnicodeString: 把ULong值转换成指定基的Unicode字符串,字符串缓冲区必须提前初始化RtlPrefixUnicodeString: 检查一个Unicode字符串是否是另一个Unicode字符串的前缀,可选择不区分大小写RtlUnicodeStringToAnsiString: 把Unicode字符串转换成ANSI,如果分配目标ANSI缓冲区,最终使用RtlFreeAnsiString释放它RtlUnicodeStringToInteger: 把Unicode字符串转换成一个整数RtlUpcaseUnicodeString: 把Unicode字符串转换成大写,可选地分配缓冲区 IoCreateDevice函数:NTSTATUS IoCreateDevice IRQL = PASSIVE_LEVELIN PDRIVER_OBJECT DriverObject 驱动程序对象IN ULONG DeviceExtensionSize 要求的设备扩展的大小IN PUNICODE_STRING DeviceName 设备名称,或者NULLIN DEVICE_TYPE DeviceType 设备的类型,标准头文件WDM.H或NTDDK.H中列出的FILE_DEVICE_XXX值之一IN ULONG DeviceCharacteristics 各种常量用OR组合在一起,指示可删除介质、只读等IN BOOLEAN Exclusive 如果一次只有一个线程可以访问该设备,为TRUEOUT PDEVICE_OBJECT* DeviceObject 返回的设备对象 IoRegisterDeviceInterface函数NTSTATUS IoRegisterDeviceInterface IRQL = PASSIVE_LEVEL参数 描述IN PDEVICE_OBJECT PhysicalDeviceObject 设备PDOIN CONST GUID* InterfaceClassGuid 被注册的GUIDIN PUNICODE_STRING ReferenceString 通常是NULL,引用字符串或成为接口名称的一部分,所以可以用于区分同一设备的不同接口OUT PUNICODE_STRING SymbolicLinkName 输出接口符号连接名,完成使用时,不要忘记使用RtlFreeUnicodeString释放这个Unicode字符串 IoRegisterDeviceInterface函数NTSTATUS IoRegisterDeviceInterface参数 描述IN PDEVICE_OBJECT PhysicalDeviceObject 设备PDOIN CONST GUID* InterfaceClassGuid 被注册的GUIDIN PUNICODE_STRING ReferenceString 通常是NULL,引用字符串成为接口名称的一部分,所以可以用于区分统一设备的不同接口OUT PUNICODE_STRING SymbolicLinkName 输出接口符号链接名。完成使用时,不要忘记使用RtlFreeUnicodeString释放这个Unicode字符串设备名:符号链接:这个名字向内核标识设备,而不是向Win32标识设备。根据约定,内核设备名从0开始编号,而符号链接名从1开始编号。用IoCreateSymbolicLink创建。设备接口:驱动程序使用设备接口使它的设备对Win32程序可见,主要思想是:每个设备使一个定义的应用程序编程接口(API)可用,全局唯一标识符(GUID)用于标识这个接口。操作系统版本的确定:可以使用注册表设置在运行时确定是否正运行Windows 98。在NT和Windows 2000中,可用以下注册表值:HKLMSystemCurrentControlSetControlProductOptionsProductType。对Workstation/Professional Windows版本,这个值是WinNT;对于Server/Enterprise版本,这个值是LanmanNT或者是ServerNT。在Windows 98中,这个注册表值不可用。驱动程序出错的方式:1、操作系统崩溃( 访问不存在的内存,在DISPATCH_LEVEL或以上的中断级访问分页内存 )2、内核转储3、驱动程序不启动4、挂起5、遗漏资源6、时间依赖性检查版本:#if DGB DbgPrint( Wdm1 checked );#else DbgPrint( Wdm1 free );可重入性:就是说它可以被同时调用处理连个不同的IRP。在多处理器的Windows 2000系统中,一个处理器可能是用一个IRP调用Wdm1Read,另一个CPU上的第二个进程也同时使用另一个IRP调用Wdm1Read。使一个例程是可重入的第一个技术是使用局部变量, DebugPrint格式说明符符号 格式说明符 类型%c ANSI字符 char%C 宽字符 wchar_t%d,%i 十进制有符号整数 int%D 十进制_int64 _int64%I IRP主功能代码和次功能代码 PIRP%L 十六进制的LARGE_INTEGER LARGE_INTEGER%s NULL终止的ANSI字符串 char*%S NULL终止的宽字符串 wchar_t*%T UNICODE_STRING PUNICODE_STRING%u 十进制的ULONG ULONG%x 十六进制的ULONG ULONG 一些IRP首部结构域域 描述IO_STATUS_BLOCK IoStatus IRP的完成状态PVOID AssociatedIrp.SystemBuffer 系统空间缓冲区(用于缓冲I/O)BOOLEAN Cancel 设置IRP是否已经被取消ULONG Flags IRP标志 CTL_CODE宏参数参数 描述DeviceType 指定IoCreateDevice的FILE_DEVICE_XXX值ControlCode IOCTL功能代码 0x000 0x7FF 为Microsoft保留 0x800 0xFFF是私有代码TransferType METHOD_BUFFERED METHOD_IN_DIRECT METHOD_OUT_DIRECT METHOD_OUT_DIRECT METHOD_NEITHERRequiredAccess FILE_ANY_ACCESS FILE_READ_DATA FILE_WRITE_DATA FILE_READ_DATA | FILE_WRITE_DATA缓冲I/O: 驱动程序可以使用两个主要的方法访问用户缓冲区,这两个方法是缓冲I/O和直接I/O。在创建设备时,必须设置新设备对象的Flags域中的DO_BUFFERED_IO位来使用缓冲I/O,或设置DO_DIRECT_IO位来使用直接I/O。如果使用缓冲I/O,内核使用户的缓冲区在某个非分页内存中可用,并在IRP首部的AssociatedIrp.SystemBuffer域中存储合适的指针。在驱动程序中简单地读或写这个内存。这个技术是驱动程序开发者最容易使用的一个技术。但是,它总体上速度要慢些,因为操作系统通常必须要把用户缓冲区复制到非分页内存或者从非分页内存复制出来。直接I/O: 使用内存描述符列表(MDL)速度要快些,但这仅可用于执行直接内存访问(DMA)的硬件。用户缓冲区的MDL放在IRP首部的MdlAddress域中。DeviceIoControl缓冲区自旋锁:内核自旋锁在BufferLock提供这个保护。自旋锁可以用在代码需要短时访问某种资源的地方。KSPIN_LOCK BufferLock; / 声明一个自旋锁对象KeInitializeSpinLock( &BufferLock ); / 初始化KeAcquireSpinLock( &BufferLock, XXX ); / 获得自旋锁KeReleaseSpinLock( &BufferLock, XXX ); / 释放自旋锁自旋(spin)是指KeAcquireSpinLock不断进行监视。由于这个原因,我们只能持有一个自旋锁很短的时间。DDK建议不要持有自旋锁超过25微秒。我们在KeAcquireSpinLock的调用中,必须提供一个指向KIRQL变量的指针,这个变量存储在提升到DISPATCH_LEVEL之前的原始IRQL级。在必要时,KeReleaseSpinLock的调用降低IRQL。如果肯定代码在DISPATCH_LEVEL IRQL运行,可以使用KeAcquireSpinLockAtDpcLevel和KeReleaseSpinLockFromDpcLevel例程得到更好的性能。在持有一个自旋锁时,不要访问分页代码或数据,因为系统几乎肯定会崩溃。在持有一个自旋锁时,千万不要退出主分发例程。设备驱动程序工作的次序:1) 一个标准总线驱动程序检测何时添加一个设备2) 设备标识符用于发现驱动程序。3) 驱动程序被装入,并告诉它添加了一个新设备。4) 进一步的消息告诉用户使用了哪些资源。5) 然后驱动程序与设备通信,这可能要使用一个标准驱动程序的服务来实现。当一个设备拔出时,Windows检测到这个事件,并告诉驱动程序该设备已经不存在。 即插即用设备检测目标 在加电时检测全部设备 装入最合适的驱动程序 为每个驱动程序分配资源 对于可热插拔的设备,在添加或删除设备时处理解决方案 提供枚举器总线驱动程序,发现新设备,并检测何时添加或删除设备 每个设备提供标识符,用于发现最合适的驱动程序 总线驱动程序或INF文件提供设备的资源分配 提供仲裁器确定给每个设备分配哪些资源 发送消息指示设备事件缺点 正在运行的设备可能必须停止,这样才可以重新分配它们资源过滤驱动程序只是在设备第一次安装时安装,所以在设备栈构造后就不能插入过滤驱动程序。单一驱动程序和分层驱动程序:键盘驱动程序为单一驱动程序,因为它接管处理键盘要求的所有处理(即它不是用其它的驱动程序)。相反,USB驱动程序使用分层方法,为了使用USB键盘,键盘驱动程序需要使用USB类驱动程序的服务。 即插即用次功能代码常用PnP IRP 功能IRP_MN_START_DEVICE 分配资源并启动一个设备IRP_MN_QUERY_REMOVE_DEVICE 询问一个设备是否可以被删除IRP_MN_CANCEL_REMOVE_DEVICE 取消查询删除请求IRP_MN_REMOVE_DEVICE 设备被拔出或卸下取消资源分配并删除设备IRP_MN_SURPRISE_REMOVAL(仅Windows 2000) 用户在意外的情况下拔出设备IRP_MN_QUERY_STOP_DEVICE 取消查询停止请求IRP_MN_STOP_DEVICE 停止设备进行资源重新分配不常用PnP IRPIRP_MN_QUERY_DEVICE_RELATIONS 查询有特定特征的PDOIRP_MN_QUERY_INTERFACE 让驱动程序导出直接调用接口IRP_MN_QUERY_CAPABILITIES 查询设备功能(如它是否可以被锁定货弹出)IRP_MN_QUERY_RESOURCES 取出设备的引导配置资源IRP_MN_QUERY_RESOURCE_REQUIREMENTS 查询设备的资源要求IRP_MN_QUERY_DEVICE_TEXT 得到设备的描述或位置字符串IRP_MN_FILTER_RESOURCE_REQUIREMENTS 让过滤驱动程序和功能驱动程序过滤设备的资源要求IRP_MN_READ_CONFIG 读配置空间信息IRP_MN_WRITE_CONFIG 设置配置空间信息IRP_MN_EJECT 从设备槽弹出设备IRP_MN_SET_LOCK 设置设备锁定状态IRP_MN_QUERY_ID 设置设备的硬件、兼容性和实例IDIRP_MN_QUERY_PNP_DEVICE_STATE 设置设备状态位映射中的位IRP_MN_QUERY_BUS_INFORMATION 得到副总线的类型和实例号IRP_MN_DEVICE_USAGE_NOTIFICATION 通知设备是在分页文件、休眠文件还是崩溃转储文件的路径中IRP_MN_QUERY_LEGACY_BUS_INFORMATION 返回遗留总线信息(仅Windows 2000)当一个设备被添加到系统时,Windows查找正确的驱动程序,并调用它的DriverEntry例程,告诉它添加了一个设备。就是这个时候,驱动程序创建他自己的的设备对象,即功能设备对象(FDO)。但是驱动程序还不试图访问它的设备硬件。在处理的过程中,驱动程序收到一个IRP_MN_START_DEVICE IRP,包括设备被分配的资源的信息,然后他开始与设备硬件进行合适的对话。如果一个设备要被拔出,Windows使用IRP_MN_REMOVE_DEVICE IRP查询驱动程序设备是否可以被删除。如果驱动程序同意,则发送一个IRP_MN_REMOVE_DEVICE IRP删除设备。如果驱动程序不希望设备被删除(如它正处于一个长的传输过程中),它将拒绝删除请求,然后发送IRP_MN_CANCEL_REMOVE_DEVICE IRP,使它回到开始的状态。如果用户偶然拔出一个设备,在Windows 98中给驱动程序发送一个IRP_MN_REMOVE_DEVICE IRP,在Windows 2000中发送IRP_MN_SUPPRISE_REMOVE IRP。我们必须处理好中断的传输。在删除请求的响应中,IRP_MN_QUERY_STOP_DEVICE IRP询问是否可以停止设备。如果可以停止设备,则发出IRP_MN_STOP_DEVICE IRP,使设备进入停止状态。如果不能停止设备,则发出IRP_MN_CANCEL_STOP_DEVICE IRP,使设备回到启动状态。当设备停止时,驱动程序不能访问它的设备,一个IRP_MN_START_DEVICE IRP通知驱动程序设备的新资源并再次启动设备。注意:当设备处于停止状态或等待状态时可能会收到删除设备消息。PnP配置管理器为驱动程序将基本的系统资源分类为:I/O端口、内存地址、DMA通道和中断。当Windows启动时,它并不知道哪些设备连接到计算机上。它可以发现自己的一些基本信息,如有多少内存,但是如何发现其他的信息呢?Windows使用驱动程序枚举可用的硬件。枚举是指查找并列出任何可用的设备,然后使用仲裁器调整所有的资源要求。对每个设备插找合适的驱动程序,然后告诉这些驱动程序使用哪些资源,并运行这些驱动程序。 查找根设备 |_ 串行设备 | |查找 |_ 键盘 |查找 查找 查找 |_ PCI总线 _ PnP ISA 总线 _ 声卡 | | |查找 查找 |_ USB 总线 _ USB 键盘 | | | 查找 |_ USB 打印机有两类电路可以用于PC到物理USB总线的接口:开放主机控制接口(OpenHCI)和通用主机控制器接口(UHCI)。Windows选择OpenHCI.sys驱动程序或者UHCI.sys驱动程序作为到这些电路接口的驱动程序层。为一个设备服务的主驱动程序称为功能驱动程序。安装INF文件可能指定多个功能驱动程序放在一个设备栈中。每个功能驱动程序或过滤驱动程序中的AddDevice例程在创建新的设备栈时调用。对每个AddDevice例程传递一个指向相同总线驱动程序PDO的指针,然后AddDevice创建一个FDO,挂接到该设备栈。AddDevice例程的调用顺序确定设备栈中驱动程序的顺序。这样,设备栈自底向上构造。类似地,当一个设备被删除时,设备栈通过先删除最上面的驱动程序来析构。PDO作为这个设备栈的固定点,因为设备栈中的每个驱动程序有相同的PDO指针。 USB 键盘设备栈驱动程序 设备栈HID键盘驱动程序 HID键盘设备FDO HID类设备FDO PDO(由USB集线器总线驱动程序创建)USB集线器 USB集线器设备FDO PDO(由USB主机控制器总线驱动程序创建)USB主机控制器 USB主机控制器设备FDO FDO(由PCI总线驱动程序创建)PCI适配器 PCI设备FDO PDO(由根总线驱动程序创建)支持即插即用主要是指实现一个AddDevice例程和一个IRP_MJ_PNP处理程序。这个PnP IRP有8个次功能代码,大多数的WDM驱动程序需要支持这些次功能代码:IRP_MN_START_DEVICE(启动设备)IRP_MN_QUERY_REMOVE_DEVIE(查询删除)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_SURPPISE_REMOVE(意外删除)PnP的处理:处理设备的添加和删除得到分配的资源处理查询停止和查询删除消息处理停止设备消息处理意外删除消息。但是,上面只是一些基本的处理功能,驱动程序显然还要做以下的工作:仅在设备启动时允许I/O请求在有任何打开的句柄时不允许删除设备在设备每次启动时,排队I/O请求在处理删除请求前,等待任何I/O请求完成在低层设备启动后处理启动0设备消息沿设备栈向下传递不支持的IRPAddDevice例程的工作是创建和初始化一个设备对象供当前驱动程序使用,并把该对象连接到设备栈。如果一个驱动程序的AddDevice例程失败,将给它下面的任何驱动程序(其AddDeivice已成功)发送一个删除设备消息。在AddDevice例程完成后,准备好接收删除设备消息。当添加一个Wdm2设备时,Unknown总线驱动程序为它创建一个PDO。PnP管理器把这个PDO传递
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年中国铝合金升降机专用泵站行业市场前景预测及投资价值评估分析报告
- 2026年中国大型机床液压站行业市场前景预测及投资价值评估分析报告
- 2025年六安霍山县消防救援局招聘政府专职消防员9人考试笔试参考题库附答案解析
- 2025辽宁农业职业技术学院面向社会招聘高层次人才2人(第三批)笔试考试参考试题及答案解析
- 2025浙江宁波市北仑区交通投资集团有限公司招聘矿山专职技术人员6人笔试考试参考题库及答案解析
- 2025年11月广东广州市天河区童时光幼儿园招聘编外聘用制专任教师1人考试笔试模拟试题及答案解析
- 《电网安全风险管控办法》
- B端产品经理职业规划
- 外科股骨骨折术后康复教程
- 感染科院内感染管理要点
- 屠宰监管培训课件
- 2025年如法网考试试题及答案
- 校园垃圾清运实施方案
- 医院药房岗位应聘展示
- 2025至2030少儿艺术培训行业发展分析及有效策略与实施路径评估报告
- 手持电动工具安全技术
- 中成药课件教学课件
- 2025至2030中国军事照明行业产业运行态势及投资规划深度研究报告
- 临沂职称考试题库及答案
- 肺癌防治教学课件
- 反间防谍宣传课件
评论
0/150
提交评论