首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DeviceIoControl错误1错误函数

DeviceIoControl错误1错误函数
EN

Stack Overflow用户
提问于 2016-04-22 16:17:40
回答 1查看 3K关注 0票数 1

我已经在内核空间中创建了一个设备,并使用CreateFile在用户空间中访问它,我能够向驱动程序发送ioctl,并且它们被正确地执行。不知道如何跟踪WdfRequestComplete之后发生的事情,返回时我以错误1(无效函数)结束。在将其标记为dup之前,请注意,在编写驱动程序ioctl和使用同步io而不是异步时,有一个不同之处。

在用户空间:

代码语言:javascript
复制
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

在核空间中

代码语言:javascript
复制
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:我试着做

代码语言:javascript
复制
temp = ExAllocatePoolWithTag(
    NonPagedPool,
    PAGE_SIZE,
    MEMORY_TAG
    );

// other code to
RtlCopyMemory((VirtioQCArg*)outputBuffer, temp, OutputBufferLength);

仍然得到错误1

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-26 17:10:35

我在linux驱动程序中将ioctl cmds定义为枚举(运行良好),在windows中实现驱动程序时,我使用了相同的枚举定义。

代码语言:javascript
复制
enum
{
    // Module & Execution control (driver API)
    VIRTIQC_SET = 200,
    VIRTIQC_UNSET,
    // more cmds.....
}

在windows中,定义控制代码需要更多。正如这里解释的那样,CTL_CODE宏应该用于定义新的IOCTL控制代码。

#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)

在我的例子中,我最终定义了以下内容:

代码语言:javascript
复制
#define VIRTQC_MAP CTL_CODE(FILE_DEVICE_NETWORK, 0xC8, METHOD_IN_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
#define VIRTQC_UNMAP CTL_CODE(FILE_DEVICE_NETWORK, 0xC9, METHOD_OUT_DIRECT, FILE_READ_DATA)

我知道小于0x800的函数代码是为MS保留的,但是我的主机上的设备需要这些代码,所以我只是提供所要求的内容。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36798773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档