2022年驱动开发学习笔记 .pdf
《2022年驱动开发学习笔记 .pdf》由会员分享,可在线阅读,更多相关《2022年驱动开发学习笔记 .pdf(14页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1、三种类型的 WDM 驱动程序总线驱动程序 (bus driver) 功能驱动程序 (function driver) 过滤驱动程序 (filter driver) 2、其他分类方法类驱动程序 (class driver) 端口驱动程序 (port driver) 小端口驱动程序 (miniort driver) 3、驱动程序对象 (DRIVER_OBJECT)主要成员DeviceObject: 指向一个设备对相链表,每个设备对象代表一个设备。DriverExtension: 一个结构体 , 该结构只有 AddDevice 成员可以直接访问。DriverStartIo: 指向驱动程序中处理I
2、/O 请求的函数。DriverUnload: 指向驱动程序中的清除函数。MajorFunction: 为一个函数指针表 , 指向存在于驱动程序中的各个IRP 处理函数, 它定义了 I/O 请求如何进入驱动程序。4、设备对象 (DEVICE_OBJECT)主要成员DriverObject: 指向与该设备对象相关的驱动程序对象。过滤驱动程序有时需要用这个指针来寻找被过滤设备的驱动程序对象。CurrentIrp: 指向最近发往驱动程序StartIo 函数的 I/O 请求包。Flags: 包含一组标志位DO_BUFFERED_IO: 读写操作使用缓冲方式(系统复制缓冲区 )访问用户模式数据DO_EXC
3、LUSIVE: 一次只允许一个线程打开设备句柄DO_DIRECT_IO: 读写操作使用直接方式 (内存描述符表 )访问用户模式数据DO_DEVICE_INITIALIZING: 设备对象正在初始化DO_POWER_PAGABLE: 必 须 在PASSIVE_LEVEL级 上 处 理IRP_MJ_PNP请求DO_POWER_INRUSH: 设备上电期间需要大电流Characteristics: 包含另一组标志位,描述设备的可选特征FILE_REMOVABLE_MEDIA: 可更换媒介设备FILE_READ_ONL Y_DEVICE: 只读设备FILE_FLOPPY_DISKETTE: 软盘驱动器
4、设备FILE_WRITE_ONCE_MDEIA: 只写一次设备FILE_REMOTE_DEVICE: 通过网络连接访问的设备FILE_DEVICE_IS_MOUNTED: 物理媒介已在设备中FILE_DEVICE_SECURE_OPEN: 在打开操作中检查设备对象的安全属性DeviceType: 一个枚举常量,描述设备类型。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 14 页 - - - - - - - - - FILE_DEVICE_PRINTER: 打印机FILE
5、_DEVICE_SCANNER: 扫描仪. FILE_DEVICE_UNKNOWN: 未知设备5、驱动程序对象与设备对象的关系一 方面 , 驱 动 程序 对 象通 常 有 多 个与它 相关 的设 备对 象,因 此 它利 用DeviceObject指针指向一个设备对象列表,该列表表示驱动程序可以控制的物理设备。另一方面 , 设备对象反过来指向它自己的驱动程序对象, 这样 I/O管理器就知道在接收一个 I/O 请求时应该调用哪个驱动程序。 每个功能码都对应一个驱动程序的入口点。6、I/O 请求包 (IRP) IRP 是 I/O 系统用来存储处理I/O 请求所需信息的地方 , I/O 管理器在 IR
6、P 中保存一个指向调用者文件对象的指针。从编程的角度看, IRP 是 I/O 管理器在响应一个 I/O 请求时从非分页系统内存中分配的一块可变大小的数据结构内存, I/O管理器每收到一个来自用户的请求就创建一个该结构,并将其作为参数传给驱动程序的 DispatchXxx、StartIo 等例程。该结构中存放有请求的类型、用户缓冲区的首地址、用户请求数据的长度等信息。驱动程序处理完这个请求后, 也在该结构中添加处理结果的有关信息, 然后调用 IoCompleteRequest 将其返回给 I/O 管理器, 用户程序的请求随即返回。每个 IRP 可以被看成由两部分组成: 固定部分 和一个 I/O
7、堆栈。 IRP 的固定部分包含关于请求的信息 , I/O 堆栈则包含一系列I/O 堆栈单元 (I/O Stack location), 单元的数目应与驱动程序堆栈中处理这一请求的驱动程序数目相同, 每个单元对应一个将处理该IRP 的驱动程序。IRP 固定部分的域MdlAddress(Memory Descriptor List, MDL): 指向一个 内存描述表 。 当驱动程序使用 直接 I/O 时, MDL 用来描述一个与该请求相关联的用户模式缓冲区AssociatedIrp: 该域是一个三指针联合, 其中与 WDM 驱动程序相关的指针是 AssociatedIrp.SystemBuffer
8、。 如果设备执行缓冲I/O, 则 SystemBuffer 指针指向系统空间缓冲区 , 否则为 NULL 。RequestorMode: 取值为一个枚举常量UserMode或 KernelMode, 指定请求初始化的模式为用户模式还是核心模式。驱动程序有时需要查看这个值来决定是否需要信任某些参数Cancel: 该域为 BOOLEAN 类型。如果为 TRUE, 则表明 IoCancelIrp 已被调用, 该函数用于取消这个请求。如果为FALSE, 则表明没有调用IoCancelIrp函数CancelIrql: 一个 IRQL(I/O Request Query Level)值, 表明那个专用的取
9、消自旋锁是在这个 IRQL 上获取的。当驱动程序在取消例程中释放自旋锁时应该参名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 14 页 - - - - - - - - - 考这个域CancelRoutine: 指 向 驱 动 程 序 取 消 例 程 的 地 址 。 应 该 使 用IoSetCancelRoutine函数设置 CancelRoutine域而不是直接修改该域IRP 堆栈单元中的域任何内核模式程序在创建一个IRP 时, 同时还创建了一个与之关联的I/O堆栈。堆栈
10、中的I/O 堆栈单元由 IO_STACK_LOCA TION 结构定义 , 每个堆栈单元都对应一个将处理的IRP 的驱动程序。为了在一个给定的IRP 中确定当前的IRP I/O 堆栈单元 , 驱动程序可以调用IoGetCurrentIrpStackLocation函数, 该函数返回当前 I/O 堆栈单元的指针。MajorFunction: 该 IRP的主要功能代码 , 它指出所要执行的 I/O 操作类型。例如: 主功能代码 IRP_MJ_READ 表示通过 Win32 API 函数 CreateFile发送的请求。主功能代码与驱动程序对像的MajorFunction 表中的某个分发函数指针相对
11、应。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: 在关闭设备时 , 取消挂起的
12、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_INFORMA TION: 得到文件的长度GetFileLength IRP_MJ_SET_INFORMATION:
13、 设置文件的长度SetFileLength IRP_MJ_FLUSH_BUFFERS: 写 输 出 缓 冲 区 或 丢 弃 输 入 缓 冲 区FlushFileBuffers FlushConsoleInputBuffer PureComm IRP_MJ_SHUTDOWN: 系统关闭InitialSystemShutdown 7、单层驱动程序的I/O 请求I/O 请求经过子系统DLL 子系统 DLL 调用 I/O 管理器的 NtWriteFile 服务I/O 管理器分配一个描述该请求的IRP, 并通过调用 IoCallDriver 函数向驱动程序 (这里指设备驱动程序 )发送请求驱动程序将 I
14、RP 中的数据传输到设备并启动I/O 操作名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 14 页 - - - - - - - - - 通过中断 CPU, 驱动程序发信号进行I/O 完成操作在设备完成操作并且中断CPU 时, 设备驱动程序服务于中断驱动程序调用IoCompleteRequest函数表明它已经处理完IRP 请求, 接管I/O 管理器完成 I/O 请求驱动程序可用的内核态例程:Ex. 执行支持Hal. 硬件抽象层 (仅 NT/Windows 2000) Io.
15、 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 取消文件句柄上的任何
16、等待的IRP IRP_MJ_DEVICE_CONTROL 设备 I/O 控制IRP_MJ_INTERNAL_DEVICE_CONTROL 来自高层驱动程序的I/O 控制IRP_MJ_SYSTEM_CONTROL WMI IRP_MJ_POWER 电源管理请求IRP_MJ_PNP 即插即用消息IRP_MJ_SHUTDOWN 关闭通知UNICODE_STRING 结构定义:typedef struct _UNICODE_STRING USHORT Length; USHORT MaximumLength; PWSTR Buffer; UNICODE_STRING, *PUNICODE_STRING
17、; Buffer 域指向一个宽 16 位字符 (双字节)缓冲区,该字符串通常不是NULL 终止名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 14 页 - - - - - - - - - 的,而是由 Length域指定字符串的当前大小(字符数)UNICODE_STRING 函数:RtlAnsiStringToUnicodeString: 把 ANSI 字符串转换成Unicode字符串,可选地分配一个缓冲区RtlAppendUnicodeStringToString: 把一
18、个 Unicode 字符串追加到另一个Unicode字符串,直到目标缓冲区的最大长度RtlAppendUnicodeToString: 追加一个宽字符串到Unicode 字符串,直到目标缓冲区的最大长度RtlCompareUnicodeString: 比较两个 Unicode字符串,可选择不区分大小写RtlCopyUnicodeString: 把一个 Unicode 字符串复制到另一个Unicode 字符串,直到目标缓冲区的最大长度RtlEqualUnicodeString: 如果两个 Unicode 字符串相等, 返回 TRUE,可选择不区分大小写RtlInitUnicodeString :
19、 设置 Unicode 字符串缓冲区指向指定的宽字符串,并设置长度域为匹配值RtlIntegerToUnicodeString: 把 ULong 值转换成指定基的Unicode 字符串,字符串缓冲区必须提前初始化RtlPrefixUnicodeString: 检查一个 Unicode字符串是否是另一个Unicode字符串的前缀,可选择不区分大小写RtlUnicodeStringToAnsiString: 把 Unicode 字符串转换成ANSI,如果分配目标ANSI 缓冲区,最终使用RtlFreeAnsiString 释放它RtlUnicodeStringToInteger: 把 Unicod
20、e 字符串转换成一个整数RtlUpcaseUnicodeString: 把 Unicode 字符串转换成大写,可选地分配缓冲区IoCreateDevice函数:NTSTATUS IoCreateDevice IRQL = PASSIVE_LEVEL IN PDRIVER_OBJECT DriverObject 驱动程序对象IN ULONG DeviceExtensionSize 要求的设备扩展的大小IN PUNICODE_STRING DeviceName 设备名称,或者 NULL IN DEVICE_TYPE DeviceType 设备的类型, 标准头文件 WDM.H 或 NTDDK.H中列
21、出的 FILE_DEVICE_XXX值之一IN ULONG DeviceCharacteristics 各种常量用 OR组合在一起,指示可删除介质、只读等IN BOOLEAN Exclusive 如果一次只有一个线程可以访问该设备,为TRUE OUT PDEVICE_OBJECT* DeviceObject 返回的设备对象名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 14 页 - - - - - - - - - IoRegisterDeviceInterface函数NT
22、STATUS IoRegisterDeviceInterface IRQL = PASSIVE_LEVEL 参数描述IN PDEVICE_OBJECT PhysicalDeviceObject 设备 PDO IN CONST GUID* InterfaceClassGuid 被注册的 GUID IN PUNICODE_STRING ReferenceString 通常是NULL, 引用字符串或成为接口名称的一部分,所以可以用于区分同一设备的不同接口OUT PUNICODE_STRING SymbolicLinkName 输出接口符号连接名,完成使用时,不要忘记使用RtlFreeUnicodeS
23、tring释放这个 Unicode 字符串IoRegisterDeviceInterface函数NTSTATUS IoRegisterDeviceInterface 参数描述IN PDEVICE_OBJECT PhysicalDeviceObject 设备 PDO IN CONST GUID* InterfaceClassGuid 被注册的 GUID IN PUNICODE_STRING ReferenceString 通常是 NULL ,引用字符串成为接口名称的一部分,所以可以用于区分统一设备的不同接口OUT PUNICODE_STRING SymbolicLinkName 输出接口符号链接
24、名。完成使用时,不要忘记使用RtlFreeUnicodeString释放这个 Unicode 字符串设备名:符号链接:这个名字向内核标识设备,而不是向Win32 标识设备。根据约定,内核设备名从 0 开始编号,而符号链接名从 1 开始编号。用 IoCreateSymbolicLink创建。设备接口:驱动程序使用设备接口使它的设备对Win32 程序可见,主要思想是:每个设备使一个定义的应用程序编程接口(API)可用,全局唯一标识符(GUID) 用于标识这个接口。操作系统版本的确定:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名
25、师精心整理 - - - - - - - 第 6 页,共 14 页 - - - - - - - - - 可以使用注册表设置在运行时确定是否正运行Windows 98。在 NT 和 Windows 2000中,可用以下注册表值:HKLMSystemCurrentControlSetControlProductOptionsProductType。对Workstation/Professional Windows版本, 这个值是 WinNT ; 对于 Server/Enterprise版本,这个值是 LanmanNT或者是 ServerNT。在 Windows 98 中,这个注册表值不可用。驱动程序
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年驱动开发学习笔记 2022 驱动 开发 学习 笔记
限制150内