Creating WDF read request out of nothing?

922 views Asked by At

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);
    }
1

There are 1 answers

0
Flynch On

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.