How can I use WDF to properly create a read request in the driver?

Jump Zhang 40 Reputation points
2023-06-06T08:20:29.5133333+00:00

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 *****************************************************************
	
}
Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
11,953 questions
Windows Hardware Performance
Windows Hardware Performance
Windows: A family of Microsoft operating systems that run across personal computers, tablets, laptops, phones, internet of things devices, self-contained mixed reality headsets, large collaboration screens, and other devices.Hardware Performance: Delivering / providing hardware or hardware systems or adjusting / adapting hardware or hardware systems.
1,657 questions
0 comments No comments
{count} votes

Accepted answer
  1. Doron Holan 1,801 Reputation points
    2023-06-15T05:56:33.9966667+00:00

    WDFREQUEST follows IRP semantics. FormatForRead sets the next stack locations format, GetParameters queries the current stack location's format. GetParameters on a new request doesn't make sense as there is no current stack location in the request (the creator doesn't get a stack location).

    The next problem you are going to face is that the HID stack requires your read request have a file object set. The applications read request has a file object set by the io manager. you need to either copy the application's file object pointer to your new request or open your own file handle (new WDFIOTARGET). If you copy the applications file object pointer, you need to keep track of cleanup and close on the file object to clear the copy.

    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 ******/
    

2 additional answers

Sort by: Most helpful
  1. Limitless Technology 44,551 Reputation points
    2023-06-07T12:48:11.0566667+00:00

    Hello there,

    A driver must complete a request when it determines that one of the following cases is true:

    The requested I/O operation has finished successfully.

    The requested I/O operation was started but failed before it finished.

    The requested I/O operation is not supported, or was not valid at the time it was received, and could not be started.

    The requested I/O operation was canceled.

    This topic provides a high-level overview of the framework objects you'll use to develop a Kernel-Mode Driver Framework (KMDF) driver

    https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/using-the-framework-to-develop-a-driver

    Hope this resolves your Query !!

    --If the reply is helpful, please Upvote and Accept it as an answer--

    0 comments No comments

  2. Jump Zhang 40 Reputation points
    2023-06-15T10:50:43.69+00:00

    Why isn't the additional question I attached displaying?


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.