I am seeing issues with async IOCTL call WdfIoTargetFormatRequestForInternalIoctl.
After request completes if I try to get the Out Buffer associated with the Out Memory Handle like this, it does not reflect the Out Data expected:
OutMemHandle = CompletionParams->Parameters.Ioctl.Output.Buffer;
OutBuffer = (VOID))WdfMemoryGetBuffer(OutMemHandle, NULL);
I have used Buffer I/O and direct I/O methods, retrieved the OutBuffer through WdfRequestRetrieveOutputBuffer and also tried updating Irp->MdlAddress with the Out data in case of direct I/0, but in my completion routine. I do not see the OUT data in the original OutBuffer I sent through the IOCTL.
I seem to be missing something either in the way of sending the async ioctl or in the way of handling the received IOCTL.
All this I am doing in kernel mode only. I am just trying to send some custom IOCTLs, not URBs.
I had similar experience with sending a control transfer asynchronously.
Any help?
Thx!
Vidya
NTSTATUS
SendIOCTLToTargetAsync(
IN PFDO_EXTENSION fdoData,
IN ULONG IoctlControlCode,
IN OUT PVOID InputBuffer,
IN ULONG InputBufferLength,
IN OUT PVOID OutputBuffer,
IN ULONG OutputBufferLength,
PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,
PVOID completionContext
)
{
NTSTATUS status;
WDF_REQUEST_REUSE_PARAMS params;
WDFMEMORY inputMem, outputMem;
PVOID InBuffer, OutBuffer;
WDF_OBJECT_ATTRIBUTES attribs;
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
“–> SendIOCTLToTargetAsync\n”);
inputMem = outputMem = NULL;
if (InputBuffer != NULL) {
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
attribs.ParentObject = fdoData->WdfRequest;
status = WdfMemoryCreate(
&attribs,
NonPagedPool,
0,
InputBufferLength,
&inputMem,
&InBuffer
);
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“WdfMemoryCreate for Device Descriptor failed %!STATUS!\n”,
status);
return status;
}
RtlCopyMemory(InBuffer, InputBuffer, InputBufferLength);
}
if (OutputBuffer != NULL) {
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
attribs.ParentObject = fdoData->WdfRequest;
status = WdfMemoryCreate(
&attribs,
NonPagedPool,
0,
OutputBufferLength,
&outputMem,
&OutBuffer
);
if(!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
“WdfMemoryCreate for Device Descriptor failed %!STATUS!\n”,
status);
return status;
}
}
status = WdfIoTargetFormatRequestForInternalIoctl(
WdfUsbTargetDeviceGetIoTarget(fdoData->WdfUsbTargetDevice),
fdoData->WdfRequest,
IoctlControlCode,
inputMem,
NULL,
outputMem,
NULL
);
if (!NT_SUCCESS(status)) {
return status;
}
WdfRequestSetCompletionRoutine(
fdoData->WdfRequest,
CompletionRoutine,
completionContext
);
if (WdfRequestSend(
fdoData->WdfRequest,
WdfUsbTargetDeviceGetIoTarget(fdoData->WdfUsbTargetDevice),
WDF_NO_SEND_OPTIONS
) == FALSE) {
status = WdfRequestGetStatus(fdoData->WdfRequest);
}
Drv_WdfReuseRequest(fdoData->WdfRequest);
TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,
“<– SendIOCTLToTargetAsync\n”);
return status;
}