李sir_Blog

博客园 首页 联系 订阅 管理
  705 随笔 :: 58 文章 :: 134 评论 :: 193万 阅读

在调用DeviceIoControl时,应用层的输入缓冲区的内容被复制到IRP中的Irp->AssociatedIrp.SystemBuffer内存地址中。这个步骤和缓冲区模式IOCTL处理一样。

 

但是,对于DeviceIoControl指定的输出缓冲区的处理,操作系统将该缓冲区锁定,然后在内核模式地址空间中重新映射一段地址。

 

在驱动程序中,METHOD_IN_DIRECT 和 METHOD_OUT_DIRECT模式都以相同方式处理,仅有的不同是它们访问用户模式缓冲区所需要的访问权限:

 

METHOD_IN_DIRECT: 需要读权限

METHOD_OUT_DIRECT:需要读和写权限。

 

使用这两种模式,IO管理器会为输入数据提供一个内核模式拷贝缓冲区,该缓冲区地址存放在Irp->AssociatedIrp.SystemBuffer中,将应用层传递的数据拷贝到该内核缓冲区中。但是为输出数据缓冲区创建一个MDL。我们可以使用MmGetSystemAddressForMdlSafe来获得该应用层虚拟缓冲区所对应的内核地址。从而对其进行访问。

 

例子:

NTSTATUS DeviceIoControl(IN PDEVICE_OBJECT DeviceObject,

                         IN PIRP           Irp)

{

PIO_STACK_LOCATION IrpSp;

ULONG InputLength;

    PVOID InputBuffer;

    ULONG OutputLength;

    PVOID OutputBuffer;

 

// 获得当前堆栈位置

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

 

// 得到输入缓冲区的大小

InputLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;

// 得到输入缓冲区的地址

InputBuffer = Irp->AssociatedIrp.SystemBuffer;

 

// 得到输出缓冲区的大小

OutputLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;

// 得到输出缓冲区在内核层的映射地址

     OutputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress);

 

     Irp->IoStatus.Status = STATUS_SUCCESS;

     Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp,IO_NO_INCREMENT);

    return STATUS_SUCCESS;

}

posted on   李sir  阅读(1634)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示