Windows驱动开发 - 派遣函数
一 派遣函数
驱动程序的主要功能是负责处理I/O请求。
其中大部分I/O请求是在派遣函数中处理的。
用户模式下所有对驱动程序的I/O请求,全部由操作系统转化为一个叫做IRP的数据结构,不同的IRP数据会被“派遣”到不同的派遣函数中。
二 IRP与派遣函数
IRP的全称是输入输出请求包。
其部分结构如下:
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {CSHORT Type;USHORT Size;//// Define the common fields used to control the IRP.////// Define a pointer to the Memory Descriptor List (MDL) for this I/O// request. This field is only used if the I/O is "direct I/O".//PMDL MdlAddress;//// Flags word - used to remember various flags.//ULONG Flags;//// The following union is used for one of three purposes://// 1. This IRP is an associated IRP. The field is a pointer to a master// IRP.//// 2. This is the master IRP. The field is the count of the number of// IRPs which must complete (associated IRPs) before the master can// complete.//// 3. This operation is being buffered and the field is the address of// the system space buffer.//union {struct _IRP *MasterIrp;__volatile LONG IrpCount;PVOID SystemBuffer;} AssociatedIrp;//// Thread list entry - allows queueing the IRP to the thread pending I/O// request packet list.//LIST_ENTRY ThreadListEntry;//// I/O status - final status of operation.//IO_STATUS_BLOCK IoStatus;//// Requestor mode - mode of the original requestor of this operation.//KPROCESSOR_MODE RequestorMode;//// Pending returned - TRUE if pending was initially returned as the// status for this packet.//BOOLEAN PendingReturned;//// Stack state information.//CHAR StackCount;CHAR CurrentLocation;//// Cancel - packet has been canceled.//BOOLEAN Cancel;//// Cancel Irql - Irql at which the cancel spinlock was acquired.//KIRQL CancelIrql;//// ApcEnvironment - Used to save the APC environment at the time that the// packet was initialized.//CCHAR ApcEnvironment;//// Allocation control flags.//UCHAR AllocationFlags;//// User parameters.//PIO_STATUS_BLOCK UserIosb;PKEVENT UserEvent;union {struct {union {PIO_APC_ROUTINE UserApcRoutine;PVOID IssuingProcess;};PVOID UserApcContext;} AsynchronousParameters;LARGE_INTEGER AllocationSize;} Overlay;//// CancelRoutine - Used to contain the address of a cancel routine supplied// by a device driver when the IRP is in a cancelable state.//__volatile PDRIVER_CANCEL CancelRoutine;//// Note that the UserBuffer parameter is outside of the stack so that I/O// completion can copy data back into the user's address space without// having to know exactly which service was being invoked. The length// of the copy is stored in the second half of the I/O status block. If// the UserBuffer field is NULL, then no copy is performed.//PVOID UserBuffer;//// Kernel structures//// The following section contains kernel structures which the IRP needs// in order to place various work information in kernel controller system// queues. Because the size and alignment cannot be controlled, they are// placed here at the end so they just hang off and do not affect the// alignment of other fields in the IRP.//union {struct {union {//// DeviceQueueEntry - The device queue entry field is used to// queue the IRP to the device driver device queue.//KDEVICE_QUEUE_ENTRY DeviceQueueEntry;struct {//// The following are available to the driver to use in// whatever manner is desired, while the driver owns the// packet.//PVOID DriverContext[4];} ;} ;//// Thread - pointer to caller's Thread Control Block.//PETHREAD Thread;//// Auxiliary buffer - pointer to any auxiliary buffer that is// required to pass information to a driver that is not contained// in a normal buffer.//PCHAR AuxiliaryBuffer;//// The following unnamed structure must be exactly identical// to the unnamed structure used in the minipacket header used// for completion queue entries.//struct {//// List entry - used to queue the packet to completion queue, among// others.//LIST_ENTRY ListEntry;union {//// Current stack location - contains a pointer to the current// IO_STACK_LOCATION structure in the IRP stack. This field// should never be directly accessed by drivers. They should// use the standard functions.//struct _IO_STACK_LOCATION *CurrentStackLocation;//// Minipacket type.//ULONG PacketType;};};//// Original file object - pointer to the original file object// that was used to open the file. This field is owned by the// I/O system and should not be used by any other drivers.//PFILE_OBJECT OriginalFileObject;} Overlay;//// APC - This APC control block is used for the special kernel APC as// well as for the caller's APC, if one was specified in the original// argument list. If so, then the APC is reused for the normal APC for// whatever mode the caller was in and the "special" routine that is// invoked before the APC gets control simply deallocates the IRP.//KAPC Apc;//// CompletionKey - This is the key that is used to distinguish// individual I/O operations initiated on a single file handle.//PVOID CompletionKey;} Tail;} IRP;
当然,此结构是微软定义的;字段含义参见驱动开发相关资料;
三 简单示例代码
在驱动入口函数 DriverEntry 中注册派遣函数的代码如下:
//设置派遣函数pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutin;pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HelloDDKDispatchRoutin;
对派遣函数做简单的处理
NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) {KdPrint(("Enter HelloDDKDispatchRoutin\n"));PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);UCHAR type = stack->MajorFunction;
......NTSTATUS status = STATUS_SUCCESS;// 完成IRPpIrp->IoStatus.Status = status;pIrp->IoStatus.Information = 0; // bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("Leave HelloDDKDispatchRoutin\n"));return status;
}
这个派遣函数仅仅是设置了IRP的完成状态,并通过IoCompleteReques结束请求。
Windows驱动开发 - 派遣函数相关推荐
- Windows驱动开发学习笔记(四)—— 3环与0环通信(常规方式)
Windows驱动开发学习笔记(四)-- 3环与0环通信(常规方式) 设备对象 创建设备对象 设置数据交互方式 创建符号链接 IRP与派遣函数 IRP的类型 其它类型的IRP 派遣函数 派遣函数注册位 ...
- 15、Windows驱动开发技术详解笔记(11) 基本概念
9.Windows驱动程序的入口函数规定为_DriverEntry@8,所以用C++编写时要用extern. 驱动程序中,不能使用编译器运行时函数,甚至C语言中的malloc,C++的new函数都不能 ...
- 《Windows驱动开发技术详解》学习笔记
Abstract 如果推荐 Windows 驱动开发的入门书,我强烈推荐<Windows驱动开发技术详解>.但是由于成书的时间较早,该书中提到的很多工具和环境都已不可用或找不到,而本文 ...
- Windows驱动开发WDM (1) - 基本结构
陆陆续续做过一些驱动的开发,但是一直以来都没有系统的学习过.这次重新阅读<windows驱动开发技术详解>(张帆,史彩成等编著),写博客记录一下,用以加深自己对驱动的理解. 驱动对象(DR ...
- c语言windows驱动编程入门,Windows驱动开发技术详解 PDF扫描版[175MB]
Windows驱动开发技术详解由浅入深.循序渐进地介绍了windows驱动程序的开发方法与调试技巧.本书共分23章,内容涵盖了windows操作系统的基本原理.nt驱动程序与wdm驱动程序的构造.驱动 ...
- 关于《竹林蹊径 深入浅出Windows驱动开发》第一个例子在Win7下蓝屏
在尝试运行<竹林蹊径 深入浅出Windows驱动开发>的第一个例子-HelloDRIVER时,在XP下没有问题,但在Win7下却发生蓝屏,蓝屏发生点在于卸载函数DriverUnload. ...
- Windows驱动开发基础(五)驱动程序的数据结构
Windows驱动开发基础:驱动程序的数据结构.转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38794405 I/O管理器定义了一些数据 ...
- 转:Windows驱动开发(中间层)
Windows驱动开发(中间层) - 慧由心生 - 博客园Windows驱动开发一.前言依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发.二.初步环境1.下载安装W ...
- 9、Windows驱动开发技术详解笔记(5) 基本语法回顾
5.在驱动中获取系统时间 1)获取启动毫秒数 在ring3 我们可以通过一个GetTickCount 函数来获得自系统启动开始的毫秒数,在ring0也有一个与之对应的KeQueryTickCount ...
最新文章
- 记一次 Kubernetes 集群被入侵,服务器变矿机
- python画动态爱心-python绘制动态爱心
- MS SQL SERVER导出表结构到Excel
- 科学地花钱:基于端智能的在线红包分配方案 (CIKM2020)
- linux oracle swd.oui,centos7安装oracle11g报错,请问怎么解?
- [css] 用css实现饼图效果
- jdk和maven配置
- 【Git】Git提交代码到GitHub的基本操作流程
- 分分钟实现底部导航栏:BottomNavigationBar快速集成
- bzoj2245 [SDOI2011]工作安排 费用流
- 去除程序名称 去除程序属性详细信息中的程序名称 创建时间等信息
- 天下的母亲都是一样的
- html5 逐帧播放 代码,html5-video – 使用媒体源扩展进行逐帧解码
- 《OpenCV3编程入门》毛星云编著
- 广州规划新增30条地铁 来看看线路图?
- layui layer btn
- Vray材质学习笔记08——陶瓷材质
- Racket编程指南——13 类和对象
- 计算机怎么样返回桌面,电脑如何快速返回桌面
- 关于未名湖边的烦恼问题
热门文章
- delimiter mysql报错_MySql中的DELIMITER错误
- python nonetype_【已解决】Python程序错误:TypeError: ‘NoneType’ object is not iterable
- IAR J-Link下载程序出现错误提示:Failed to get CPU status after 4 retries Retry?
- [YTU]_1998( C语言实验——删除指定字符)
- matlab读取/播放视频的函数(2)
- 【shell】docker images 拿到ID
- mysql设置check
- shell处理curl返回数据_shell神器curl用法笔记
- maven和gradle中,dependency和plugin的区别
- SpringMVC访问静态资源的三种方式