关于METHOD_BUFFERED驱动通信方式

"缓冲"方法(METHOD_BUFFERED)
备注:在下面的讨论中,"输入"表示数据从用户模式的应用程序到驱动程序,"输出"表示数据从驱动程序到应用程序。

对于读取请求,I/O 管理器分配一个与用户模式的缓冲区大小相同的系统缓冲区。IRP 中的 SystemBuffer 字段包含系统地址。 UserBuffer 字段包含初始的用户缓冲区地址。当完成请求时,I/O 管理器将驱动程序已经提供的数据从系统缓冲区复制到用户缓冲区。对于写入请求,会分配一个系统缓冲区并将 SystemBuffer 设置为地址。用户缓冲区的内容会被复制到系统缓冲区,但是不设置 UserBuffer。对于 IOCTL 请求,会分配一个容量大小足以包含输入缓冲区或输出缓冲区的系统缓冲区,并将 SystemBuffer 设置为分配的缓冲区地址。输入缓冲区中的数据复制到系统缓冲区。UserBuffer 字段设置为用户模式输出缓冲区地址。内核模式驱动程序应当只使用系统缓冲区,且不应使用 UserBuffer 中存储的地址。

对于 IOCTL,驱动程序应当从系统缓冲区获取输入并将输出写入到系统缓冲区。当完成请求时,I/O 系统将输出数据从系统缓冲区复制到用户缓冲区。

 

2K中的源码实现是这样的:

        irpSp->Parameters.DeviceIoControl.Type3InputBuffer = (PVOID) NULL;

        try {

            if (InputBufferLength || OutputBufferLength) {
                irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota( poolType, (InputBufferLength > OutputBufferLength) ? nputBufferLength : OutputBufferLength );

                if (ARGUMENT_PRESENT( InputBuffer )) {
                    RtlCopyMemory( irp->AssociatedIrp.SystemBuffer, InputBuffer, InputBufferLength );
                }
                irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
                irp->UserBuffer = OutputBuffer;
                if (ARGUMENT_PRESENT( OutputBuffer )) {
                    irp->Flags |= IRP_INPUT_OPERATION;
                }
            } else {
                irp->Flags = 0;
                irp->UserBuffer = (PVOID) NULL;
            }
可以看出ExAllocatePoolWithQuota先分配了一块系统内存,把用户态输入缓冲区的数据拷贝到系统内存irp->AssociatedIrp.SystemBuffer 中。而irp->UserBuffer 则保存了当前的输出缓冲区。

 

所以我们可以用irp->UserBuffer来传递具有多个参数的驱动 IOCTL请求的第二个参数来使用。

 Param1Buffer = Irp->AssociatedIrp.SystemBuffer;

 Param2Buffer = Irp->UserBuffer;

最后还是要把要输出的数据放到Irp->AssociatedIrp.SystemBuffer中输出。Irp->AssociatedIrp.SystemBuffer中的数据会复制到Irp->UserBuffer。

 

这种使用方式要注意Irp->UserBuffer作为输出缓冲区时,最好不要直接赋值。除非Irp->UserBuffer=Irp->AssociatedIrp.SystemBuffer

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 根据您提供的引用内容,编译器内部错误:段错误通常是由于编译器或代码中的错误导致的。段错误是指程序访问了无效的内存地址,这可能是由于指针错误、内存越界或者其他内存相关的问题引起的。要解决这个问题,您可以尝试以下几个步骤: 1. 检查代码:首先,请确保您的代码没有明显的错误,比如指针未初始化、数组越界等。检查相关的代码行,特别是在/home/leb/brpc-1.6.0/src/butil/containers/doubly_buffered_data.h文件的第368行附近。 2. 更新编译器:如果您正在使用的是旧版本的编译器,尝试更新到最新版本,以确保您使用的是稳定的编译器版本。 3. 检查依赖项:根据您提供的引用内容,您正在使用的是一些第三方库。请确保这些库的版本与您的代码兼容,并且已正确安装和配置。 4. 检查系统环境:有时,系统环境中的问题也可能导致段错误。请确保您的系统环境配置正确,并且没有其他冲突或错误。 如果以上步骤都没有解决问题,您可能需要进一步调试代码或寻求更专业的技术支持来解决这个问题。 #### 引用[.reference_title] - *1* *2* *3* [yarn.lock · TeddyYoung/locker_vue - Gitee.com](https://blog.csdn.net/weixin_42511396/article/details/117683326)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值