一 派遣函数

驱动程序的主要功能是负责处理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驱动开发 - 派遣函数相关推荐

  1. Windows驱动开发学习笔记(四)—— 3环与0环通信(常规方式)

    Windows驱动开发学习笔记(四)-- 3环与0环通信(常规方式) 设备对象 创建设备对象 设置数据交互方式 创建符号链接 IRP与派遣函数 IRP的类型 其它类型的IRP 派遣函数 派遣函数注册位 ...

  2. 15、Windows驱动开发技术详解笔记(11) 基本概念

    9.Windows驱动程序的入口函数规定为_DriverEntry@8,所以用C++编写时要用extern. 驱动程序中,不能使用编译器运行时函数,甚至C语言中的malloc,C++的new函数都不能 ...

  3. 《Windows驱动开发技术详解》学习笔记

    Abstract   如果推荐 Windows 驱动开发的入门书,我强烈推荐<Windows驱动开发技术详解>.但是由于成书的时间较早,该书中提到的很多工具和环境都已不可用或找不到,而本文 ...

  4. Windows驱动开发WDM (1) - 基本结构

    陆陆续续做过一些驱动的开发,但是一直以来都没有系统的学习过.这次重新阅读<windows驱动开发技术详解>(张帆,史彩成等编著),写博客记录一下,用以加深自己对驱动的理解. 驱动对象(DR ...

  5. c语言windows驱动编程入门,Windows驱动开发技术详解 PDF扫描版[175MB]

    Windows驱动开发技术详解由浅入深.循序渐进地介绍了windows驱动程序的开发方法与调试技巧.本书共分23章,内容涵盖了windows操作系统的基本原理.nt驱动程序与wdm驱动程序的构造.驱动 ...

  6. 关于《竹林蹊径 深入浅出Windows驱动开发》第一个例子在Win7下蓝屏

    在尝试运行<竹林蹊径 深入浅出Windows驱动开发>的第一个例子-HelloDRIVER时,在XP下没有问题,但在Win7下却发生蓝屏,蓝屏发生点在于卸载函数DriverUnload. ...

  7. Windows驱动开发基础(五)驱动程序的数据结构

    Windows驱动开发基础:驱动程序的数据结构.转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38794405 I/O管理器定义了一些数据 ...

  8. 转:Windows驱动开发(中间层)

    Windows驱动开发(中间层) - 慧由心生 - 博客园Windows驱动开发一.前言依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发.二.初步环境1.下载安装W ...

  9. 9、Windows驱动开发技术详解笔记(5) 基本语法回顾

    5.在驱动中获取系统时间 1)获取启动毫秒数 在ring3 我们可以通过一个GetTickCount 函数来获得自系统启动开始的毫秒数,在ring0也有一个与之对应的KeQueryTickCount ...

最新文章

  1. 记一次 Kubernetes 集群被入侵,服务器变矿机
  2. python画动态爱心-python绘制动态爱心
  3. MS SQL SERVER导出表结构到Excel
  4. 科学地花钱:基于端智能的在线红包分配方案 (CIKM2020)
  5. linux oracle swd.oui,centos7安装oracle11g报错,请问怎么解?
  6. [css] 用css实现饼图效果
  7. jdk和maven配置
  8. 【Git】Git提交代码到GitHub的基本操作流程
  9. 分分钟实现底部导航栏:BottomNavigationBar快速集成
  10. bzoj2245 [SDOI2011]工作安排 费用流
  11. 去除程序名称 去除程序属性详细信息中的程序名称 创建时间等信息
  12. 天下的母亲都是一样的
  13. html5 逐帧播放 代码,html5-video – 使用媒体源扩展进行逐帧解码
  14. 《OpenCV3编程入门》毛星云编著
  15. 广州规划新增30条地铁 来看看线路图?
  16. layui layer btn
  17. Vray材质学习笔记08——陶瓷材质
  18. Racket编程指南——13 类和对象
  19. 计算机怎么样返回桌面,电脑如何快速返回桌面
  20. 关于未名湖边的烦恼问题

热门文章

  1. delimiter mysql报错_MySql中的DELIMITER错误
  2. python nonetype_【已解决】Python程序错误:TypeError: ‘NoneType’ object is not iterable
  3. IAR J-Link下载程序出现错误提示:Failed to get CPU status after 4 retries Retry?
  4. [YTU]_1998( C语言实验——删除指定字符)
  5. matlab读取/播放视频的函数(2)
  6. 【shell】docker images 拿到ID
  7. mysql设置check
  8. shell处理curl返回数据_shell神器curl用法笔记
  9. maven和gradle中,dependency和plugin的区别
  10. SpringMVC访问静态资源的三种方式