【发布时间】:2016-04-22 16:17:40
【问题描述】:
我在内核空间创建了一个设备,并使用CreateFile 在用户空间访问它我能够将ioctl 发送到驱动程序并且它们被正确执行。不知道如何跟踪WdfRequestComplete 之后发生的事情,返回时我以错误 1(无效函数)结束。在将其标记为 dup 之前,请注意与 this 的不同之处在于我编写了驱动程序 ioctl,并且我使用的是同步 io 而不是异步。
在用户空间:
fd = CreateFile(dev_path,
(FILE_GENERIC_READ | FILE_GENERIC_WRITE),
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL, OPEN_EXISTING, 0, NULL);
// ... error checking code here
DeviceIoControl(fd, // device handler
VIRTQC_CMD_MMAP, // command to send
&inputBuffer,
inputBufferLength,
&outputBuffer,
outputBufferLength,
&returnLength,
(LPOVERLAPPED)NULL); // overlapped structure not needed using sync io
在内核空间中
status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &inputBuffer, NULL);
if (!NT_SUCCESS(status))
{
WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
return;
}
inputVirtArg = (VirtioQCArg*)inputBuffer;
status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &outputBuffer, NULL);
if (!NT_SUCCESS(status))
{
WdfRequestComplete(Request, STATUS_INVALID_PARAMETER);
return;
}
outputVirtArg = (VirtioQCArg*)outputBuffer;
switch (IoControlCode)
{
case VIRTQC_CMD_MMAP:
if (PsGetCurrentThread() == irp->Tail.Overlay.Thread)
{
status = CreateAndMapMemory(device, &(inputVirtArg), &(outputVirtArg));
outputVirtArg->flag = (!NT_SUCCESS(status)) ? 0 : 1;
}
else
status = STATUS_UNSUCCESSFUL;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
WdfRequestComplete(Request, status);
更新 1:
我尝试过WdfRequestCompleteWithInformation(Request, status, OutputBufferLength);,但结果相同。
另外,我注意到 inputBuffer 和 outputBuffer 的地址是一样的。
更新 2: 我试过做
temp = ExAllocatePoolWithTag(
NonPagedPool,
PAGE_SIZE,
MEMORY_TAG
);
// other code to
RtlCopyMemory((VirtioQCArg*)outputBuffer, temp, OutputBufferLength);
仍然出现错误 1
【问题讨论】:
-
您需要从一些基本的故障排除开始:大量使用 DbgPrint 来查看哪个功能失败以及错误代码是什么。没有这些信息,我们不可能为您提供帮助。
-
我可以在使用
outputBuffer = irp->AssociatedIrp.SystemBuffer而不是WdfRequestRetrieveOutputBuffer后访问用户空间中的结果,但我不知道为什么。我使用了 DbgPrint 并使用 windbg 进行了跟踪,以检查为什么我仍然不断收到错误 1,但在 EvtIoDeviceControl 中似乎一切正常。 -
IOCTL使用什么数据传输类型,见msdn.microsoft.com/en-us/library/windows/hardware/…?
-
@HarryJohnston 谢谢!就是这样,我使用与我的 linux 驱动程序相同的代码并且没有指定 CTL_CODE 宏,因此它默认为 METHOD_BUFFERED
-
您应该发布详细信息作为答案。