c++ DeviceIoControl完全不工作,返回时SystemBuffer为空

zdwk9cvp  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(191)

我有一个IOCTL被发送到我的驱动程序与一个结构,该结构被成功传递,然后我的驱动程序发挥其魔力,但当它完成时,它应该返回一个简单的unsigned_int64,这是8字节长,我将IRP的IoStatus.Information设置为unsigned_int64的大小(8字节),并将该值复制到AssociatedIrp.SystemBuffer,最后将IoStatus.Status设置为STATUS_SUCCESS,然后调用IoCompleteRequest。
现在,我使用WinDbg检查了SystemBuffer是否包含正确的输出,以及调用IoCompleteRequest时状态和信息字段是否正确,然而,当我的用户模式应用程序调用DeviceIoControl返回输出缓冲区时,它不会更改我在lpOutBuffer字段中指向的整数值。我在创建时将其初始化为普通的0x9,在调用完成时保持相同的值,而在调用应该是完全不同的值时,我有多个IOCTL,它们都以完全相同的方式工作,我不知道这里发生了什么,任何提示都将非常感谢,我被引导相信这是一个windows bug现在或类似的东西,因为我已经通读了我的代码100次,没有弄清楚这个简单而复杂的bug。
我很抱歉,我不能张贴任何代码,因为我不拥有它和其他原因。

ni65a41a

ni65a41a1#

希望你在3年前提出这个问题后找到了解决方案。我们在调查类似的问题时遇到了这个帖子,解决方案非常简单,但没有文档记录。如果驱动程序将一些数据复制到输出缓冲区,并使用状态为OK的WdfRequestComplete,则不会向调用方返回任何内容!您需要调用WdfRequestCompleteWithInformation并传递在Information参数中写入的字节数。这将告诉框架返回给调用者的字节数。
例如:

WDFMEMORY   reqMemory;
NTSTATUS    status = WdfRequestRetrieveOutputMemory(Request, &reqMemory);
if (!NT_SUCCESS(status))
{
    break;
}
WdfMemoryCopyFromBuffer(reqMemory, 0, data, dataLen);

/* this will complete the request but nothing is returned to the caller
WdfRequestComplete(Request, S_OK);
*/
/* this is the correct way of returning the data */
WdfRequestCompleteWithInformation(Request, S_OK, dataLen);
hof1towb

hof1towb2#

在使用case语句时,不要忘记使用break,在以下情况下,如果忘记使用break,数据将不会复制到用户层

switch (stack->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_SEND: {
      SENDMessage(p_buffer);
      break;
    }
    case IOCTL_RECV: {
      RECVMessage(p_buffer) 
      break; // dont forget it
    }
    default: {
      nStatus = STATUS_INVALID_PARAMETER;
    }

相关问题