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;

    }

  • 相关阅读:
    topcoder srm 320 div1
    topcoder srm 325 div1
    topcoder srm 330 div1
    topcoder srm 335 div1
    topcoder srm 340 div1
    topcoder srm 300 div1
    topcoder srm 305 div1
    topcoder srm 310 div1
    topcoder srm 315 div1
    如何统计iOS产品不同渠道的下载量?
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1881924.html
Copyright © 2011-2022 走看看