Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


WdfIoQueueFindRequest returns STATUS_NO_MORE_ENTRIES

vikrantwaje96vikrantwaje96 Member Posts: 7

I have two IOCTL which are handled by same kernel mode driver.
In 1st IOCTL, I forward the request to manual queue using WdfRequestForwardToIoQueue(). The return status of this function is a success.
in 2nd IOCTL, I am trying to find the request in the manual queue using WdfIoQueueFindRequest(). However, its returning the status as STATUS_NO_MORE_ENTRIES.
I am not quite sure what causes the STATUS_NO_MORE_ENTRIES error since the request looks to be forwarded successfully to manual queue by 1st IOCTL

Comments

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,445

    Perhaps you should show us some code. This s a very common pattern.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • vikrantwaje96vikrantwaje96 Member Posts: 7

    Basically, in my first try I tried to forward the request to a manual queue and find the request in the manual queue as part of same IOCTL(This was just for testing):

    // Queue creation in EvtDeviceAdd:
    
     WDF_OBJECT_ATTRIBUTES_INIT(&attr);
        attr.ExecutionLevel = WdfExecutionLevelPassive;
        WDF_IO_QUEUE_CONFIG_INIT(&config, WdfIoQueueDispatchManual);
        config.PowerManaged = WdfFalse;
        status = WdfIoQueueCreate(device,
                                  &config,
                                  &attr,
                                  &context->manualQueue);
    
    // IOCTL handler in which forwarding and searching is happening(1st try):
    
    VOID
    ProcessIoctl(
        _In_ WDFQUEUE   Queue,
        _In_ WDFREQUEST Request,
        _In_ size_t     outputlengthBuffer,
        _In_ size_t     inputlengthBuffer,
        _In_ ULONG      IoControlCode
        )
    {
      switch(IoControlCode){
     NTSTATUS status = 0;
       case IOCTL1:
       {
           PCONTEXT context = GetContext(WdfIoQueueGetDevice(Queue));
           status = WdfRequestForwardToIoQueue(Request, context->manualQueue);
         if (NT_SUCCESS(status))
         {
            // Mark request pending
            status = STATUS_PENDING;
         }
    
      //Now start finding the request in manual queue appended above
       do {
            WDF_REQUEST_PARAMETERS_INIT(&params);
            status = WdfIoQueueFindRequest(
                                           context->manualQueue,
                                           prevTagRequest,
                                           NULL,
                                           &params,
                                           &tagRequest
                                           );
            if (prevTagRequest) {
                WdfObjectDereference(prevTagRequest);
            }
            if (status == STATUS_NO_MORE_ENTRIES) {  // This condition is getting triggered somehow
                break;
            }
            if (status == STATUS_NOT_FOUND) {
                //
                // The prevTagRequest request has disappeared from the
                // queue. There might be other requests that match
                // the criteria, so restart the search. 
                //
                prevTagRequest = tagRequest = NULL;
                continue;
            }
            if (!NT_SUCCESS(status)) { 
                status = STATUS_UNSUCCESSFUL;
                break;
            }
            if (IOCTL1 == params.Parameters.DeviceIoControl.IoControlCode){
                //
                // Found a match. Retrieve the request from the queue.
                //
                status = WdfIoQueueRetrieveFoundRequest(
                                                        context->manualQueue,
                                                        tagRequest,
                                                        Request1
                                                        );
                WdfObjectDereference(tagRequest);
                if (status == STATUS_NOT_FOUND) {
                    //
                    // The tagRequest request has disappeared from the
                    // queue. There might be other requests that match 
                    // the criteria, so restart the search. 
                    //
                    prevTagRequest = tagRequest = NULL;
                    continue;
                }
                if (!NT_SUCCESS(status)) {
                    status = STATUS_UNSUCCESSFUL;
                    break;
                }
                //
                //  Found a request.
                //
                ASSERT(*Request1 == tagRequest);
                status =  STATUS_SUCCESS;
                break;
            } else {
                //
                // This request is not the correct one. Drop the reference 
                // on the tagRequest after the driver obtains the next request.
                //
                prevTagRequest = tagRequest;
                continue;
            }
        } while (TRUE);
    
    
       }
    
    
    }
    
    
    }
    
  • vikrantwaje96vikrantwaje96 Member Posts: 7
    edited November 2022

    I am trying to forward request to queue and find the request in queue as part of same IOCTL:

    //EvtDeviceAdd
        WDF_OBJECT_ATTRIBUTES_INIT(&attr);
        attr.ExecutionLevel = WdfExecutionLevelPassive;
        WDF_IO_QUEUE_CONFIG_INIT(&config, WdfIoQueueDispatchManual);
        config.PowerManaged = WdfFalse;
        status = WdfIoQueueCreate(device,
                                  &config,
                                  &attr,
                                  &context->manualQueue);
    
    
    VOID
    ProcessIoctl(
        _In_ WDFQUEUE   Queue,
        _In_ WDFREQUEST Request,
        _In_ size_t     lengthOutputBuffer,
        _In_ size_t     lengthInputBuffer,
        _In_ ULONG      IoControlCode
        )
    {
    switch(IoControlCode)
    {
      case IOCTL1:
    {
    
          PCONTEXT context = GetContext(WdfIoQueueGetDevice(Queue));;
    
          status = WdfRequestForwardToIoQueue(Request, context->manualQueue);
         if (NT_SUCCESS(status))
        {
            status = STATUS_PENDING;
        }
    
    
      //Now find the request in the queue previously forwarded
    WDF_REQUEST_PARAMETERS  params;
        WDFREQUEST  tagRequest;
        WDFREQUEST  prevTagRequest;
    
        WDF_REQUEST_PARAMETERS_INIT(&params);
    
        *Request = NULL;
        prevTagRequest = tagRequest = NULL;
    
        do {
            WDF_REQUEST_PARAMETERS_INIT(&params);
            status = WdfIoQueueFindRequest(
                                           context->manualQueue,
                                           prevTagRequest,
                                           NULL,
                                           &params,
                                           &tagRequest
                                           );
            if (prevTagRequest) {
                WdfObjectDereference(prevTagRequest);
            }
            if (status == STATUS_NO_MORE_ENTRIES) {
                status = STATUS_UNSUCCESSFUL;
                break;
            }
            if (status == STATUS_NOT_FOUND) {
                //
                // The prevTagRequest request has disappeared from the
                // queue. There might be other requests that match
                // the criteria, so restart the search. 
                //
                prevTagRequest = tagRequest = NULL;
                continue;
            }
            if (!NT_SUCCESS(status)) { 
                status = STATUS_UNSUCCESSFUL;
                break;
            }
            if (FunctionCode == params.Parameters.DeviceIoControl.IoControlCode){
                //
                // Found a match. Retrieve the request from the queue.
                //
                status = WdfIoQueueRetrieveFoundRequest(
                                                        context->manualQueue,
                                                        tagRequest,
                                                        Request1,
                                                        );
                WdfObjectDereference(tagRequest);
                if (status == STATUS_NOT_FOUND) {
                    //
                    // The tagRequest request has disappeared from the
                    // queue. There might be other requests that match 
                    // the criteria, so restart the search. 
                    //
                    prevTagRequest = tagRequest = NULL;
                    continue;
                }
                if (!NT_SUCCESS(status)) {
                    status = STATUS_UNSUCCESSFUL;
                    break;
                }
                //
                //  Found a request.
                //
                ASSERT(*Request1 == tagRequest);
                status =  STATUS_SUCCESS;
                break;
            } else {
                //
                // This request is not the correct one. Drop the reference 
                // on the tagRequest after the driver obtains the next request.
                //
                prevTagRequest = tagRequest;
                continue;
            }
        } while (TRUE);
    
    }
    
    }
    }
    
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,445
    edited November 2022

    Your "ASSERT" is incorrect. The request that you get from WdfIoQueueFindRequest is a "fake" shadow request that refers to the real request. You will not get the same request handle when you do WdfdIoQueueRetrieveFoundRequest. If you call WdfIoQueueGetState, does it show there are requests in the queue?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • vikrantwaje96vikrantwaje96 Member Posts: 7

    I used the following piece of code to achieve what you are trying to say(right after forwarding request to the Queue):

    ULONG num_request = 0;
    
        WDF_IO_QUEUE_STATE state = WdfIoQueueGetState(context->manualQueue,&num_request,NULL);
    
    

    It does say that the num_request = 1 after function execution, state variable is set to 0x0B.

    Also, looks like when I use WdfIoQueueRetrieveNextRequest() instead of WdfIoQueueFindRequest(), I see that the code returns success code.
    Is there any limitation for use of WdfIoQueueFindRequest() that causes it to return error status?

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,445

    Theoretically, your code should work. After all, you copied it word-for-word from the WdfIoQueueFindRequest documentation page, after all. However, I have had better luck with WdfIoQueueRetrieveNextRequest.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 January 2023 Live, Online
Developing Minifilters 20 March 2023 Live, Online
Internals & Software Drivers 17 April 2023 Live, Online
Writing WDF Drivers 22 May 2023 Live, Online