I tried implementing a filtering driver for a HID device using WDF, in which a parallel queue was created, and I registered the EvtIoRead routine. In this routine, I can receive a request of type "WdfRequestTypeRead" and register the completion routine for the request and forward the request. Now what I want to do is, when the program processes this type of request for the first time, add the identity, and save the data to the driver's buffer in the completion routine, and then when subsequent requests come in, I will use another processing method according to the state, which is to copy the data saved to the local last output buffer to the current request and complete the current request, and then I will create a new Read request, create memory for it, and format the request, when the above steps are successful. I'm going to forward that request, however, I'm having an issue right now, This is part of the code that handles the logic,The problem is in the comments of the code.
VOID EvtIoRead(_In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t Length) {
NTSTATUS status;
WDF_REQUEST_SEND_OPTIONS options;
PAGED_CODE();
WDFMEMORY memory = NULL;
WDFREQUEST newRequest = NULL;
WDF_OBJECT_ATTRIBUTES attributes;
WDFIOTARGET ioTarget = WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue));
//
// ******************* Create a Read Request*************************************************
//
LARGE_INTEGER byteOffset;
WDF_REQUEST_PARAMETERS oldParams;
WDF_REQUEST_PARAMETERS_INIT(&oldParams);
WdfRequestGetParameters(Request, &oldParams);
byteOffset.QuadPart = oldParams.Parameters.Read.DeviceOffset;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, REQUEST_CONTEXT);
attributes.ParentObject = WdfIoQueueGetDevice(Queue);
status = WdfRequestCreate(&attributes, ioTarget, &newRequest);
if (NT_SUCCESS(status)) {
PREQUEST_CONTEXT pReaquestContext = GetRequestContext(newRequest);
pReaquestContext->IsCreateManual = TRUE;
pReaquestContext->Queue = Queue;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ParentObject = newRequest;
status = WdfMemoryCreate(&attributes, NonPagedPool, 'test', oldParams.Size, &memory, NULL);
if (NT_SUCCESS(status)) {
status = WdfIoTargetFormatRequestForRead(ioTarget, newRequest, memory, NULL, &byteOffset.QuadPart);
if (NT_SUCCESS(status)) {
// Complete the request
WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length);
/******** test ******/
WDF_REQUEST_PARAMETERS newParams;
WDF_REQUEST_PARAMETERS_INIT(&newParams);
WdfRequestGetParameters(newRequest, &newParams);
// The question is here, I have clearly formatted it here,
// but why is the type of getting the newly created request still WdfRequestTypeCreate????
/******** test end ******/
WdfRequestSetCompletionRoutine(newRequest, EvtReadRequestIoctlCompletionRoutine, NULL);
// send
if (WdfRequestSend(newRequest, ioTarget, NULL) == FALSE) {
WdfObjectDelete(memory);
WdfObjectDelete(newRequest);
}
}
else {
WdfObjectDelete(memory);
WdfObjectDelete(newRequest);
}
}
else {
WdfObjectDelete(newRequest);
}
}else
WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length);
// ****************** END *****************************************************************
}