Creating WDF read request out of nothing?
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->开发者_JS百科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);
}
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.
精彩评论