zoukankan      html  css  js  c++  java
  • 用户层与内核层通讯——控制码方式通讯

    前言:

      此文是记录我遇到的问题及解决办法

    环境相关:

      使用的直接读写方式,这种方式会创建一个MDL,将用户空间的地址重新映射到了内核空间,这样不会发生拷贝也不会造成地址访问错误。MDL被I/O管理器创建好之后,放置在下面这个字段中

    irp->MdlAddress

    //获取缓冲区地址需要使用MDL操作函数
    MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
        //创建设备对象
        status = IoCreateDevice(
            driver,            //驱动对象(新创建的设备对象所属驱动对象)
            0,                //设备扩展大小
            &devName,        //设备名称
            FILE_DEVICE_UNKNOWN,    //设备类型(未知类型)
            0,                //设备特征信息
            FALSE,            //设备是否为独占的
            &pDevice        //创建完成的设备对象指针
        );
    
        if (!NT_SUCCESS(status))
        {
            KdPrint(("创建设备失败,错误码:0x%08X
    ", status));
            return status;
        }
    
        //读写方式为直接读写方式
        pDevice->Flags = DO_DIRECT_IO;

      控制码的传输类型为METHOD_OUT_DIRECT

    //控制码
    #define MYCTLCODE(code) CTL_CODE(FILE_DEVICE_UNKNOWN,0x800+(code),METHOD_OUT_DIRECT,FILE_ANY_ACCESS)

     

    问题:

      错将输出内容复制到输入缓冲区(其实是对输出输入缓冲区比较模糊,以为它们共用)

    解决:

      输入缓冲区通过irp‐>AssociatedIrp.SystemBuffer获取(无论传递的是哪种方式, 在内核层中都可以通过 irp‐>AssociatedIrp.SystemBuffer 来获取到输入缓冲区)

      输出缓冲区通过MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority)获取

        //获取输入缓冲区(如果存在)
        if (pIrp->AssociatedIrp.SystemBuffer != NULL)
        {
            pInputBuff = pIrp->AssociatedIrp.SystemBuffer;
        }
        //获取输出缓冲区(如果存在)
        if (pIrp->MdlAddress != NULL)
        {
            //获取MDL缓冲区在内核中的映射
            pOutBuff = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
        }
  • 相关阅读:
    CentOS 6.3下安装腾达USB无线网卡遇到的问题及解决方法
    验证resneXt,densenet,mobilenet和SENet的特色结构
    比较语义分割的几种结构:FCN,UNET,SegNet,PSPNet和Deeplab
    比较 VGG, resnet和inception的图像分类效果
    强化学习基础
    深度学习的知识点
    卷积神经网络CNN
    信息论的知识点
    理论机器学习
    计算理论基础
  • 原文地址:https://www.cnblogs.com/ndyxb/p/12942118.html
Copyright © 2011-2022 走看看