凭空创建 WDF 读取请求?

发布于 2024-12-09 05:04:11 字数 2343 浏览 3 评论 0原文

背景: 我正在编写一个虚拟 USB 转 RS232 驱动程序。但由于我的硬件是 USB 芯片 (PDIUSBD12),而不是纯 UART 芯片,因此驱动程序需要进行一些特殊调整。使用超级终端之类的 PC 应该相信它正在与常规 RS232 芯片通信。不管怎样,问题不在于这件事,更多的是一个理解WDF的问题,呵呵:)

问题: 我想要完成的是创建一个“读取请求”(无中生有)并将其传递给硬件。遗憾的是,WdfRequestRetrieveOutputMemory 导致“访问破坏”/崩溃。我创建新请求的方式是否存在任何根本问题? WdfRequestRetrieveOutputMemory 的输入变量都不为 NULL,但我猜 maskRequest 变量在某种程度上有问题?!

    case IOCTL_SERIAL_WAIT_ON_MASK: // *** Wait on Mask ***
    if (m_WaitMask == 0) { // Can only set if mask is not zero
        status = STATUS_UNSUCCESSFUL;
        DbgPrint("IOCTL_SERIAL_WAIT_ON_MASK failed, no wait mask\n");
        bytesTransferred = 0;
        break;
    }
    else {
        // Registers completion routine for the mask-request
        WdfRequestSetCompletionRoutine(Request, WaitOnMaskCompletionRoutine, pDevContext->BulkReadPipe); // pDevContext->BulkReadPipe??

        // Forward the mask-request to the mask wait queue
        status = WdfRequestForwardToIoQueue(Request, mask_queue);
        if (!NT_SUCCESS(status)) {
            DbgPrint("IOCTL_SERIAL_WAIT_ON_MASK, WdfRequestForwardToIoQueue failed\n");
            bytesTransferred = 0;
            break;
        }
        status = STATUS_PENDING;

        // Create a brand new read request and pass it down to the hardware
        mask_status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, NULL, &maskRequest);
        if(!NT_SUCCESS(mask_status)) {
            goto MaskExit;
        }

        mask_status = WdfRequestRetrieveOutputMemory(maskRequest, &maskMemory);
        if(!NT_SUCCESS(mask_status)) {
            goto MaskExit;
        }

        mask_status = WdfUsbTargetPipeFormatRequestForRead(pDevContext->BulkReadPipe, maskRequest, maskMemory, NULL); 
        if (!NT_SUCCESS(mask_status)) {
            goto MaskExit;
        }

        WdfRequestSetCompletionRoutine(maskRequest, EvtRequestMaskReadCompletionRoutine, pDevContext->BulkReadPipe);
        ret = WdfRequestSend(maskRequest, WdfUsbTargetPipeGetIoTarget(pDevContext->BulkReadPipe), WDF_NO_SEND_OPTIONS);
        if (ret == FALSE) {
            mask_status = WdfRequestGetStatus(maskRequest);
            goto MaskExit;
        }
        else {
            break;
        }

MaskExit:
        WdfRequestCompleteWithInformation(maskRequest, mask_status, 0);
    }

Background:
I'm writing a virtual USB to RS232 driver. But since my hardware is a USB-chip (PDIUSBD12) and not a pure UART chip the driver needs some special tweaks. A PC using something like the Hyperterminal should beleive that it is talking to a regular RS232 chip. Anyway, the problem is not in this matter, it is more of a understanding-the-WDF-issue, hehe :)

Problem:
What I want to accomplish is to create a "read request" (out of nothing) and pass it down to the hardware. Sadly the WdfRequestRetrieveOutputMemory causes a "Access voilation"/crash. Is there any fundamental problem with how I create the new request? None of the input variables to WdfRequestRetrieveOutputMemory is NULL but I guess that the maskRequest variable is faulty in some way?!

    case IOCTL_SERIAL_WAIT_ON_MASK: // *** Wait on Mask ***
    if (m_WaitMask == 0) { // Can only set if mask is not zero
        status = STATUS_UNSUCCESSFUL;
        DbgPrint("IOCTL_SERIAL_WAIT_ON_MASK failed, no wait mask\n");
        bytesTransferred = 0;
        break;
    }
    else {
        // Registers completion routine for the mask-request
        WdfRequestSetCompletionRoutine(Request, WaitOnMaskCompletionRoutine, pDevContext->BulkReadPipe); // pDevContext->BulkReadPipe??

        // Forward the mask-request to the mask wait queue
        status = WdfRequestForwardToIoQueue(Request, mask_queue);
        if (!NT_SUCCESS(status)) {
            DbgPrint("IOCTL_SERIAL_WAIT_ON_MASK, WdfRequestForwardToIoQueue failed\n");
            bytesTransferred = 0;
            break;
        }
        status = STATUS_PENDING;

        // Create a brand new read request and pass it down to the hardware
        mask_status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, NULL, &maskRequest);
        if(!NT_SUCCESS(mask_status)) {
            goto MaskExit;
        }

        mask_status = WdfRequestRetrieveOutputMemory(maskRequest, &maskMemory);
        if(!NT_SUCCESS(mask_status)) {
            goto MaskExit;
        }

        mask_status = WdfUsbTargetPipeFormatRequestForRead(pDevContext->BulkReadPipe, maskRequest, maskMemory, NULL); 
        if (!NT_SUCCESS(mask_status)) {
            goto MaskExit;
        }

        WdfRequestSetCompletionRoutine(maskRequest, EvtRequestMaskReadCompletionRoutine, pDevContext->BulkReadPipe);
        ret = WdfRequestSend(maskRequest, WdfUsbTargetPipeGetIoTarget(pDevContext->BulkReadPipe), WDF_NO_SEND_OPTIONS);
        if (ret == FALSE) {
            mask_status = WdfRequestGetStatus(maskRequest);
            goto MaskExit;
        }
        else {
            break;
        }

MaskExit:
        WdfRequestCompleteWithInformation(maskRequest, mask_status, 0);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆沫 2024-12-16 05:04:11

您无法通过这种方式访问​​请求的输出缓冲区。使用 WdfRequestCreate 您只需创建请求对象。因此,当您调用 WdfRequestRetrieveOutputMemory 时,此请求不会附加任何缓冲区。之后,您需要使用 WdfUsbTargetPipeFormatRequestForRead 进行初始化。在此调用的第三个参数中,您可以指定此请求的读取缓冲区。

You cannot access request's output buffer this way. With WdfRequestCreate you are only creating the request object. So this request doenst have any buffer attached to it when you call WdfRequestRetrieveOutputMemory. After that you need to do initialization with WdfUsbTargetPipeFormatRequestForRead. In the third parameter of this call, you can specify the read buffer for this request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文