• windows驱动程序wdf--KMDF获取应用程序数据缓冲区地址 分类: windows驱动程序WDM 2015-01-04 16:19 353人阅读 评论(0) 收藏


    有3种常用方式:METHOD_BUFFERED  METHOD_IN_DIRECT  METHOD_OUT_DIRECT
      还有METHOD_NEITHER,《windows设备驱动WDF开发》描述为:源自win 9x的VxD的模式,不建议读者掌握。这个就不管了。
      METHOD_BUFFERED:无论读和写都对应同一缓冲区
      METHOD_IN_DIRECT METHOD_OUT_DIRECT:输入缓冲区可作为附加输出缓冲区,输出缓冲区可作为附加输入缓冲区,两者区别只在DMA读写要分清,详见《windows设备驱动WDF开发》的DMA_Sample

      举简例:
      应用层DeviceIoControl传两个UNCHAR数(2 和 4)的地址给驱动。
      驱动读取地址提取数值,两数相加完成请求返还给应用层。
      以上过程分别以:METHOD_BUFFERED    METHOD_IN_DIRECT  METHOD_OUT_DIRECT 各执行一次
      
      结果:KMDF获取应用程序数据缓冲区地址

       驱动层EvtDeviceIoControl例程读取处理部分:
       
    #define IOSample_IOCTL_BUFFERED CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
    #define IOSample_IOCTL_IN_DIRECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
    #define IOSample_IOCTL_OUT_DIRECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)

        switch(IoControlCode)
       {

        case IOSample_IOCTL_BUFFERED:
        case IOSample_IOCTL_IN_DIRECT:
        case IOSample_IOCTL_OUT_DIRECT:
    if (InputBufferLength  == 0 || OutputBufferLength == 0)
    { //检查输入、输出参数有效性
    WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
    }
    else
    {
    //METHOD_BUFFERED,METHOD_OUT_DIRECT,METHOD_IN_DIRECT三种方式,
    //输入缓冲区地址可通过调用WdfRequestRetrieveInputBuffer函数获得
    //输出缓冲区地址可通过调用WdfRequestRetrieveOutputBuffer函数获得

    //获取输入缓冲区地址buffer
    status = WdfRequestRetrieveInputBuffer(Request, 1, &buffer, NULL);
    if (!NT_SUCCESS(status))
    {
    WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
            break;
    }

    //buffer表示输入缓冲区地址
    //输入x1=应用程序传给驱动程序的数字
    x1 = *(UCHAR *)buffer;

    //获取输出缓冲区地址buffer
    status = WdfRequestRetrieveOutputBuffer(Request, 1, &buffer, NULL);
    if (!NT_SUCCESS(status)) 
    {
    WdfRequestComplete(Request, STATUS_UNSUCCESSFUL);
    break;
    }
    //输入x2=应用程序通过输出缓冲区传给驱动程序的数字
    x2 = *(UCHAR *)buffer;

    *(UCHAR *)buffer=x1+x2;

    //完成I/O请求,驱动程序传给应用程序的数据长度为1字节
    WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 1);
    }
            break;

        default :
            status = STATUS_INVALID_DEVICE_REQUEST;
    WdfRequestCompleteWithInformation(Request, status, 0);
            break;
        }


    分析:对于METHOD_BUFFERED:
      驱动层输入输出缓冲区对应应用层的输入缓冲区和输出缓冲区,WdfRequestRetrieveInputBuffer和WdfRequestRetrieveOutputBuffer都读取同一位置,所以2+2=4。那个6的地址在驱动层是不可读的,他只是应用层接受来自驱动的输出结果

    对于METHOD_OUT_DIRECT,METHOD_IN_DIRECT:
      驱动层输入缓冲区,驱动层输出缓冲区分别于应用层对应。所以那个6的地址对于驱动层是可读的,实际上这就是所谓“输出缓冲区可作为附加的输入缓冲区”

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    算法习题---线性表之控制变量个数获取数据最小值
    C语言复习---矩形法求定积分函数
    sql server系统表详细说明
    sp_addlinkedserver 方法应用
    ipseccmd命令解析
    缓存淘汰算法(LFU、LRU、ARC、FIFO、MRU)分析
    uml定义的使用的关系
    GIS公交查询-flex/java
    arcgis软件集合
    arcgis地图数据集合
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706469.html
Copyright © 2020-2023  润新知