Windows内核-7-(IRP)I/O请求包

IRP(I/O Request Packet)就是一个进行I/O操作的请求包。

IRP是一个结构体,谁分配谁就得释放,通常由执行体里的管理器,获取内核驱动程序来分配。

IRP不是单独的,只要创建了IRP就会跟着创建IRP的I/O栈,有一个栈是给内核驱动用的:

驱动需要调用IoGetCurrentIrpStackLocation函数来获取内驱驱动对应的I/O栈。

I/O传递

I/O系统是以设备对象为中心,而不是以驱动对象为中心的。IRP可以在设备对象中传来传去:

有点类似于计算机网络的体系结构。但是不可否认的是I/O可以在设备直接进行各种传递,所以通常用来作为读取文本数据。

具体的传递过程有点类似于栈。

IRP和I/O栈

这张图是对前面第一张图的细化。

分发例程(dispatch routine)

IRP最主要的一个作用就是拿来做分发例程,其实也就是分发的实例函数,就是对文件数据的传递。在我的理解里,就是对信息的分发,让大家一起用到数据。

所有的分发例程都有一个原型:

typedef NTSTATUS DRIVER_DISPATCH (
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp);

分发例程必须保存在驱动对象的MajorFunction里面,且需要对应和驱动的连接状态:

状态 描述
IRP_MJ_CREATE 获取文件句柄,对应User下的CreateFile
IRP_MJ_CLOSE 关闭文件句柄,对应User下的CloseHandle
IRP_MJ_READ 对应ReadFile
IRP_MJ_WRITE 对应WriteFile
IRP_MJ_DEVICE_CONTROL 对应DeviceIoControl,即可读又可写
IRP_MJ_INTERNAL_DEVICE_CONTROL 和IRP_MJ_DEVICE_CONTROL差不多,但是只有Kernel可用

完成请求

一旦决定要处理IRP(意味着不会把该IRP传递给下一个设备对象),就必须要完成它。

比如:

NTSTATUS MyDispatchRoutine(PDEVICE_OBJECT, PIRP Irp) {
//...
Irp->IoStatus.Status = STATUS_XXX;
Irp->IoStatus.Information = NumberOfBytesTransfered; // depends on request type
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_XXX;
}
//这里的IoCompleteRequest就是必须的

安全IRP操作

由于线程原因,很有可能一个去读一个去写,导致两个只有一个拿到了想要的数据。

还有页面内存的原因,修改的时候有可能一起修改了。

内核提供了两种比较安全的处理方式:

1 缓冲I/O

2 直接I/O

缓冲I/O

要使用缓冲I/O只需要在设备对象的Flag字段里面添加一个DO_BUFFERED_IO

DeviceObject->Flags |= DO_BUFFERED_IO

缓冲I/O的原理就是在系统内存中开辟一段缓冲区,作为一个中间人。

比如说要写,就先把内容写到系统内存缓冲区里,然后系统内存缓冲区再写入/读取到缓冲区里面。

直接I/O

直接缓冲采用物理内存映射来处理,将User和Kernel的缓冲区都指向物理内存里面,并且锁定在内存里,然后读写都采用它。这样的好处是减少了调用的开销。但是占了部分内存。

IRP_MJ_DEVICE_CONTROL 调度

前面的缓冲和直接I/O是读或写操作,这里的IRP_MJ_DEVICE_CONTROL操作是基于控制代码来选择读或写两个都可以的。

User态的IRP_MJ_DEVICE_CONTROL 和Kernel态的调用函数原型差不多:

BOOL DeviceIoControl(
HANDLE       hDevice,
DWORD       dwIoControlCode,
LPVOID       lpInBuffer,
DWORD       nInBufferSize,
LPVOID       lpOutBuffer,
DWORD       nOutBufferSize,
LPDWORD     lpBytesReturned,
LPOVERLAPPED lpOverlapped
);

dwIoControlCode:控制代码,由CTL_CODE宏的四个参数来处理。

Zero驱动程序

Client+Kernel的一个练手项目:

对于读请求,会将提供的缓冲区清零然后输出

对于写请求,会把缓冲区消耗掉

源代码zodiacon/windowskernelprogrammingbook: The Windows Kernel Programming book samples (github.com)

Windows内核-7-(IRP)I/O请求包的更多相关文章

  1. 《天书夜读:从汇编语言到windows内核编程》六 驱动、设备、与请求

    1)跳入到基础篇的内核编程第7章,驱动入口函数DriverEnter的返回值决定驱动程序是否加载成功,当打算反汇编阅读驱动内核程序时,可寻找该位置. 2)DRIVER_OBJECT下的派遣函数(分发函 ...

  2. Windows环境中,通过Charles工具,抓取安卓手机、苹果手机中APP应用的http、https请求包信息

    Windows环境中,通过Charles工具,抓取安卓手机.苹果手机中APP应用的http.https请求包信息1.抓取安卓手机中APP应用的http请求包信息1)在电脑上操作,查看Windows机器 ...

  3. windows内核驱动内存管理之Lookaside使用

    Windows内存管理中使用了类似于容器的东西,叫做Lookaside对象,每次程序员申请内存都会从Lookaside里面申请,只有不足的时候,Lookaside才会向内存又一次申请内存空间,这样减少 ...

  4. [14]Windows内核情景分析 --- 文件系统

    文件系统 一台机器上可以安装很多物理介质来存放资料(如磁盘.光盘.软盘.U盘等).各种物理介质千差万别,都配备有各自的驱动程序,为了统一地访问这些物理介质,windows设计了文件系统机制.应用程序要 ...

  5. Windows内核原理-同步IO与异步IO

    目录 Windows内核原理-同步IO与异步IO 背景 目的 I/O 同步I/O 异步I/O I/O完成通知 总结 参考文档 Windows内核原理-同步IO与异步IO 背景 在前段时间检查异常连接导 ...

  6. Windows驱动开发-IRP结构体

    IRP的全名是I/O Request Package,即输入输出请求包,它是Windows内核中的一种非常重要的数据结构. 上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的 ...

  7. Windows内核-7-IRP和派遣函数

    Windows内核-7-IRP和派遣函数 IRP以及派遣函数是Windows中非常重要的概念.IRP 是I/O Request Pocket的简称,意思是I/O操作的请求包,Windows中所有Use ...

  8. 【windwos 操作系统】关键的Windows内核数据结构一览(下)

    I/O管理器 nt!_IRP IRP表示一个I/O请求包结构体,它用来封装执行一个特定I/O操作所需要的所有参数以及I/O操作的状态.IRP的表现也类似于一个线程独立调用栈因此它可以从一个线程传递到另 ...

  9. Windows内核 WDM驱动程序的基本结构和实例

    WDM驱动的基本结构: WDM驱动模型是建立在NT式驱动程序模型基础之上的.对于WDM驱动程序来说,一般都是基于分层的,即完成一个设备的操作,至少要由两个驱动设备共同完成. 1)物理设备对象和功能设备 ...

随机推荐

  1. docker基本操作和部署

    #安装所需的软件包.yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data ...

  2. 文末送书四本 | 这篇Java反射机制太经典!不看后悔!

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员. 价值:Java技能,面试经验指导,简历优化,职场规划指导,技能提升方法,讲不完的职场故事,个人成长经 ...

  3. Mysql-5.7.28 Windows安装

    1.下载mysql-5.7.28-winx64社区版并解压 2.解压后配置环境变量 3.my.ini配置文件及初始化mysql命令 4.登录mysql 每次windows安装mysql时都需要百度,自 ...

  4. windows下命令

    shutdown -s -t 0 关机 shutdown -r -t 0 重启 mstsc 远程桌面 notepad 记事本 regedit 注册表 calc 计算器 start applicatio ...

  5. python操作elasticsearch增、删、改、查

    最近接触了个新东西--es数据库 这东西虽然被用的很多,但我是前些天刚刚接触的,发现其资料不多,学起来极其痛苦,写个文章记录下 导入库from elasticsearch import Elastic ...

  6. AI 预测蛋白质结构「GitHub 热点速览 v.21.29」

    作者:HelloGitHub-小鱼干 虽然 AI 领域藏龙卧虎,但是本周预测蛋白质结构的 alphafold 一开源出来就刷爆了朋友圈,虽然项目与我无关,但是看着科技进步能探寻到生命机理,吃瓜群众也有 ...

  7. python chrome

    from selenium.webdriver.chrome.options import Options from selenium import webdriver wd = webdriver. ...

  8. vivo x9i ADB 模拟点击

    手机连接电脑无反应,安装360驱动大师 更多设置--关于---多次点击软件版本号--开启开发者选项 USB调试--USB模拟点击(需要密码开启)

  9. 备战-Java IO

    备战-Java IO 君如载酒须尽醉,醉来不复思天涯. 简介:备战-Java IO. 一.概述 Java 的 I/O 大概可以分成以下几类: 磁盘操作:File 字节操作:InputStream 和 ...

  10. FreeRTOS-01-任务相关函数

    3 任务相关API函数 任务相关函数如下: 任务创建和删除API函数 任务创建和删除实验(动态方法) 任务创建和删除实验(静态方法) 任务挂起和恢复API函数 任务挂起和恢复实验 3.1 任务创建AP ...