zoukankan      html  css  js  c++  java
  • 设备IO控制操作 之 直接内存模式IOCTL

    在调用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;

    }

  • 相关阅读:
    paip.禁用IKAnalyzer 的默认词库.仅仅使用自定义词库.
    paip.语义分析分词常见的单音节字词 2_deDuli 单字词 774个
    IFL嵌入式小组技术博客入口导航
    devc++5.0.0.9的调试方法
    getch()、getche()和getchar()之间的区别
    devc++5.0.0.9的调试方法
    声明和定义的区别
    IFL嵌入式小组技术博客入口导航
    C/C++程序到内存分配个人总结
    getch()、getche()和getchar()之间的区别
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1881924.html
Copyright © 2011-2022 走看看