Re: Dispatch Requests

Discussion in 'Windows Vista Drivers' started by Egidio [MSFT], Feb 4, 2010.

  1. [I don't see my post, resending]

    This behavior can be also explained if you have a single client sending down
    I/O synchronously, i.e., until the stack doesn't complete the current
    IRP/Request, it will not be able to send down anything else.
    For example you can add a 'pre-process' callback or 'in-process' callback,
    these callbacks are called for each IRP/request your driver receives. If you
    see them called only once, it means this is a problem with drivers/app above
    you.

    Egi.


    "uba" <> wrote in message
    news:...
    > Hello,
    >
    > In my USB filter driver (KMDF) I do not want to send write or read
    > requests to lower stack as they arrive. I want to
    > bundle them in a list and send them once the list is full.
    >
    > I tried it but my filter driver does not get the second request. If I
    > send the request down the stack then i get the
    > next request.
    >
    > Is there any way I can send a pending status to upper stack so that i
    > get the next request even though i do not send the first one down the
    > stack?
    >
    > Thanks nd Regards,
    > kid
    >
    >
    >
    >
    >
    >
     
    Egidio [MSFT], Feb 4, 2010
    #1
    1. Advertising

  2. Egidio [MSFT]

    Don Burn Guest

    There is no maximum except limits to memory. The model should work, but
    you have to keep track of how many items are in the queue if you put in more
    than one.


    --
    Don Burn (MVP, Windows DKD)
    Windows Filesystem and Driver Consulting
    Website: http://www.windrvr.com
    Blog: http://msmvps.com/blogs/WinDrvr


    "uba" <> wrote in message
    news:...
    >
    > I would like to know what is maximum number of requests that
    > sequential or manual queue can hold. Is this unlimited. I know it is
    > unlimited for parallel queue. I'm not sure of sequential and manual.
    >
    > Don,
    >
    > Does the steps you described to merge requests work for more than 2
    > requests. I'm facing few problem while trying to merge more than 2
    > requests.
    >
    > Thanks nd Regards,
    > kid
    >
    >
    > __________ Information from ESET NOD32 Antivirus, version of virus
    > signature database 4834 (20100204) __________
    >
    > The message was checked by ESET NOD32 Antivirus.
    >
    > http://www.eset.com
    >
    >
    >




    __________ Information from ESET NOD32 Antivirus, version of virus signature database 4834 (20100204) __________

    The message was checked by ESET NOD32 Antivirus.

    http://www.eset.com
     
    Don Burn, Feb 4, 2010
    #2
    1. Advertising

  3. This behavior can be also explained if you have a single client sending down
    I/O synchronously, i.e., until the stack doesn't complete the current
    IRP/Request, it will not be able to send down anything else.
    For example you can add a 'pre-process' callback or 'in-process' callback,
    these callbacks are called for each IRP/request your driver receives. If you
    see them called only once, it means this is a problem with drivers/app above
    you.

    Egi.

    "uba" <> wrote in message
    news:...
    >
    > I would like to know what is maximum number of requests that
    > sequential or manual queue can hold. Is this unlimited. I know it is
    > unlimited for parallel queue. I'm not sure of sequential and manual.
    >
    > Don,
    >
    > Does the steps you described to merge requests work for more than 2
    > requests. I'm facing few problem while trying to merge more than 2
    > requests.
    >
    > Thanks nd Regards,
    > kid
    >
     
    Egidio [MSFT], Feb 4, 2010
    #3
  4. Is the first thread stuck someplace? After the 1st request got dispatched,
    did this thread finally returned to upper driver? Use !stacks 2
    <your_driver_name>.
    Try doing one small step at a time: do not forward the request, do not
    complete it, just return. Do you see your callback called for the 2nd
    request? If this works, it means that something is not right with the 1st
    thread, which seems to be blocked someplace or in a loop.

    Egi.


    "uba" <> wrote in message
    news:...
    > My mistake, the filter driver is a disk upper filter. It was not
    > USBSTOR lower filter.
    >
    > I had register a pre-processor call back and see next write arriving
    > before completion of first one. But if I forward the first request to
    > different queue and do not submit to lower stack, it just gets blocked
    > over there and EvtIOWrite is not invoked for second time.
    >
    > Here is the complete code.
    >
    > Can someone look into it and let me know if I'm doing anything wrong
    > here.
    >
    > NTSTATUS
    > FilterEvtDeviceAdd(
    > IN WDFDRIVER Driver,
    > IN PWDFDEVICE_INIT DeviceInit
    > )
    > {
    > WDF_OBJECT_ATTRIBUTES deviceAttributes;
    > PFILTER_EXTENSION filterExt;
    > NTSTATUS status;
    > WDFDEVICE device;
    > WDF_IO_QUEUE_CONFIG ioQueueConfig;
    >
    > PAGED_CODE ();
    > WdfFdoInitSetFilter(DeviceInit);
    > WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes,
    > FILTER_EXTENSION);
    > status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    > if (!NT_SUCCESS(status)) {
    > KdPrint( ("Disk UFilter: WdfDeviceCreate failed with status
    > code 0x%x\n", status));
    > return status;
    > }
    >
    > filterExt = FilterGetData(device);
    >
    > filterExt->WdfDevice = device;
    > filterExt->bCompleteWrite = FALSE;
    > WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
    > WdfIoQueueDispatchSequential);
    >
    > ioQueueConfig.EvtIoRead = FilterEvtIoRead;
    > ioQueueConfig.EvtIoWrite = FilterEvtIoWrite;
    >
    > status =
    > WdfIoQueueCreate(device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,WDF_NO_HANDLE
    > );
    >
    > if (!NT_SUCCESS(status)) {
    > KdPrint( ("Disk UFilter: WdfIoQueueCreate failed 0x%x\n",
    > status));
    > return status;
    > }
    >
    > WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >
    > status = WdfIoQueueCreate
    > (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>ReadQueue);

    >
    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfIoQueueCreate for Read failed %!
    > STATUS!\n", status));
    > return status;
    > }
    >
    > WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >
    > status = WdfIoQueueCreate
    > (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>WriteQueue);

    >
    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfIoQueueCreate for Write failed %!
    > STATUS!\n", status));
    > return status;
    > }
    >
    > WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >
    > status = WdfIoQueueCreate
    > (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>ReadMergeQueue);

    >
    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfIoQueueCreate for Read failed %!
    > STATUS!\n", status));
    > return status;
    > }
    >
    > WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >
    > status = WdfIoQueueCreate
    > (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>WriteMergeQueue);

    >
    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfIoQueueCreate for Write failed %!
    > STATUS!\n", status));
    > return status;
    > }
    >
    >
    > return status;
    > }
    >
    > VOID
    > FilterEvtIoWrite(
    > IN WDFQUEUE Queue,
    > IN WDFREQUEST Request,
    > IN size_t Length
    > )
    > {
    > NTSTATUS status;
    > PFILTER_EXTENSION filterExt;
    > WDFDEVICE device;
    >
    > KdPrint(("Disk UFilter: FilterEvtIoWrite Enter Request 0x%x Length: %d
    > \n", Request, Length));
    > device = WdfIoQueueGetDevice(Queue);
    > filterExt = FilterGetData(device);
    > if(IsQueueEmpty(filterExt->WriteMergeQueue))
    > {
    > status = FilterForwardReqToWriteMergeQueue(filterExt, filterExt-
    >>WriteMergeQueue, Request, Length);

    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: FilterForwardReqToWriteMergeQueue for
    > Write failed %!STATUS!\n", status));
    > return;
    > }
    > }
    > else
    > {
    > status = FilterMergeRequests(filterExt, Request);
    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: FilterMergeRequests for Write failed %!
    > STATUS!\n", status));
    > return;
    > }
    > }
    > KdPrint(("Disk UFilter: FilterEvtIoWrite Exit\n"));
    > return;
    > }
    >
    > NTSTATUS
    > FilterForwardReqToWriteMergeQueue(
    > IN PFILTER_EXTENSION filterExt,
    > IN WDFQUEUE Queue,
    > IN WDFREQUEST Request,
    > IN size_t Length
    > )
    > {
    > NTSTATUS status = STATUS_SUCCESS;
    >
    > KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Enter\n"));
    >
    > status = WdfRequestForwardToIoQueue(Request, Queue);
    > if(!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfRequestForwardToIoQueue failed%X
    > \n", status));
    > FilterCompleteRequest(Request, status, 0);
    > }
    > KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Exit\n"));
    > return status;
    > }
    >
    > NTSTATUS
    > FilterMergeRequests(
    > IN PFILTER_EXTENSION filterExt,
    > IN WDFREQUEST Request
    > )
    > {
    > NTSTATUS status = STATUS_SUCCESS;
    > WDFIOTARGET ioTarget;
    > WDF_OBJECT_ATTRIBUTES attributes;
    > WDFREQUEST NewRequest;
    > WDFREQUEST MergeRequest;
    > PVOID buffer0, buffer1;
    > PCHAR newbuffer;
    > size_t bufSize0, bufSize1, newbufSize;
    > WDFMEMORY Memory;
    >
    > KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Enter\n"));
    >
    > ioTarget = WdfDeviceGetIoTarget(filterExt->WdfDevice);
    >
    > WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    > attributes.ParentObject = ioTarget;
    >
    > status = WdfRequestCreate(&attributes,ioTarget,&NewRequest);
    >
    > if (!NT_SUCCESS(status))
    > {
    > KdPrint(("Disk UFilter: WdfRequestCreate Failed, Error = 0x%X\n",
    > status));
    > return status;
    > }
    >
    > status = WdfIoQueueRetrieveNextRequest(filterExt-
    >>WriteMergeQueue,&MergeRequest);

    >
    > if(!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfIoQueueRetrieveNextRequest failed",
    > status == STATUS_NO_MORE_ENTRIES));
    > }
    >
    > status = WdfRequestRetrieveInputBuffer(Request, 0, &buffer0,
    > &bufSize0);
    > if( !NT_SUCCESS(status) )
    > {
    > KdPrint (("Disk UFilter:Could not get request memory buffer %X\n",
    > status));
    > return status;
    > }
    >
    > status = WdfRequestRetrieveInputBuffer(MergeRequest, 0, &buffer1,
    > &bufSize1);
    > if( !NT_SUCCESS(status) )
    > {
    > KdPrint (("Disk UFilter:Could not get request memory buffer %X\n",
    > status));
    > return status;
    > }
    >
    > WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    > attributes.ParentObject = NewRequest;
    >
    > status = WdfMemoryCreate(
    > &attributes,
    > NonPagedPool,
    > 'UQER',
    > bufSize0 + bufSize1,
    > &Memory,
    > (PVOID*) &newbuffer
    > );
    >
    > if (!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: Failed to alloc mem for urb Error = 0x
    > %X\n", status));
    > status = STATUS_INSUFFICIENT_RESOURCES;
    > return status;
    > }
    >
    > status = WdfRequestRetrieveInputBuffer(NewRequest, 0, &newbuffer,
    > &newbufSize);
    > if( !NT_SUCCESS(status) )
    > {
    > KdPrint (("Disk UFilter:Could not get request memory buffer %X\n",
    > status));
    > return status;
    > }
    >
    > RtlCopyMemory((PVOID)newbuffer, buffer0, bufSize0);
    > RtlCopyMemory(newbuffer + bufSize0, buffer1, bufSize1);
    >
    > newbufSize = bufSize0 + bufSize1;
    >
    > status = WdfRequestForwardToIoQueue(Request, filterExt->WriteQueue);
    > if(!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfRequestForwardToIoQueue failed%X
    > \n", status));
    > FilterCompleteRequest(Request, status, 0);
    > }
    >
    > status = WdfRequestForwardToIoQueue(MergeRequest, filterExt-
    >>WriteQueue);

    > if(!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfRequestForwardToIoQueue failed%X
    > \n", status));
    > FilterCompleteRequest(MergeRequest, status, 0);
    > }
    >
    > WdfRequestFormatRequestUsingCurrentType(NewRequest);
    >
    > filterExt->bCompleteWrite = TRUE;
    >
    >
    > WdfRequestSetCompletionRoutine(NewRequest,FilterRequestCompletionRoutine,filterExt);
    >
    > ret = WdfRequestSend(NewRequest,Target,WDF_NO_SEND_OPTIONS);
    >
    > if (ret == FALSE) {
    > status = WdfRequestGetStatus (NewRequest);
    > KdPrint( ("WdfRequestSend failed: 0x%x\n", status));
    > WdfRequestComplete(NewRequest, status);
    > }
    > KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Exit\n"));
    > return status;
    > }
    >
    > VOID
    > FilterRequestCompletionRoutine(
    > IN WDFREQUEST Request,
    > IN WDFIOTARGET Target,
    > PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
    > IN WDFCONTEXT Context
    > )
    > {
    > WDFREQUEST NewRequest;
    > PFILTER_EXTENSION filterExt;
    > NTSTATUS status;
    > DWORD dwCnt;
    >
    > KdPrint(("Disk UFilter: FilterRequestCompletionRoutine Entry Request
    > 0x%x\n", Request));
    >
    > filterExt = (PFILTER_EXTENSION)Context;
    >
    > if(filterExt->bCompleteWrite)
    > {
    > for(dwCnt=0 ;dwCnt<2; dwCnt++)
    > {
    > status = WdfIoQueueRetrieveNextRequest(filterExt-
    >>WriteQueue,&NewRequest);

    >
    > if(!NT_SUCCESS(status)) {
    > KdPrint(("Disk UFilter: WdfIoQueueRetrieveNextRequest failed",
    > status == STATUS_NO_MORE_ENTRIES));
    > continue;
    > }
    >
    > WdfRequestComplete(NewRequest, CompletionParams->IoStatus.Status);
    > }
    > filterExt->bCompleteWrite = FALSE;
    >
    > }
    > else
    > {
    > WdfRequestComplete(Request, CompletionParams->IoStatus.Status);
    > }
    > KdPrint(("Disk UFilter: FilterRequestCompletionRoutine Exit\n"));
    > return;
    > }
     
    Egidio [MSFT], Feb 5, 2010
    #4
  5. For the test below mark the queue as parallel (from serial) else you will
    not see your callback invoked.

    "Egidio [MSFT]" <> wrote in message
    news:O$...
    > Is the first thread stuck someplace? After the 1st request got
    > dispatched, did this thread finally returned to upper driver? Use !stacks
    > 2 <your_driver_name>.
    > Try doing one small step at a time: do not forward the request, do not
    > complete it, just return. Do you see your callback called for the 2nd
    > request? If this works, it means that something is not right with the 1st
    > thread, which seems to be blocked someplace or in a loop.
    >
    > Egi.
    >
    >
    > "uba" <> wrote in message
    > news:...
    >> My mistake, the filter driver is a disk upper filter. It was not
    >> USBSTOR lower filter.
    >>
    >> I had register a pre-processor call back and see next write arriving
    >> before completion of first one. But if I forward the first request to
    >> different queue and do not submit to lower stack, it just gets blocked
    >> over there and EvtIOWrite is not invoked for second time.
    >>
    >> Here is the complete code.
    >>
    >> Can someone look into it and let me know if I'm doing anything wrong
    >> here.
    >>
    >> NTSTATUS
    >> FilterEvtDeviceAdd(
    >> IN WDFDRIVER Driver,
    >> IN PWDFDEVICE_INIT DeviceInit
    >> )
    >> {
    >> WDF_OBJECT_ATTRIBUTES deviceAttributes;
    >> PFILTER_EXTENSION filterExt;
    >> NTSTATUS status;
    >> WDFDEVICE device;
    >> WDF_IO_QUEUE_CONFIG ioQueueConfig;
    >>
    >> PAGED_CODE ();
    >> WdfFdoInitSetFilter(DeviceInit);
    >> WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes,
    >> FILTER_EXTENSION);
    >> status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint( ("Disk UFilter: WdfDeviceCreate failed with status
    >> code 0x%x\n", status));
    >> return status;
    >> }
    >>
    >> filterExt = FilterGetData(device);
    >>
    >> filterExt->WdfDevice = device;
    >> filterExt->bCompleteWrite = FALSE;
    >> WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
    >> WdfIoQueueDispatchSequential);
    >>
    >> ioQueueConfig.EvtIoRead = FilterEvtIoRead;
    >> ioQueueConfig.EvtIoWrite = FilterEvtIoWrite;
    >>
    >> status =
    >> WdfIoQueueCreate(device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,WDF_NO_HANDLE
    >> );
    >>
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint( ("Disk UFilter: WdfIoQueueCreate failed 0x%x\n",
    >> status));
    >> return status;
    >> }
    >>
    >> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >>
    >> status = WdfIoQueueCreate
    >> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>>ReadQueue);

    >>
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfIoQueueCreate for Read failed %!
    >> STATUS!\n", status));
    >> return status;
    >> }
    >>
    >> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >>
    >> status = WdfIoQueueCreate
    >> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>>WriteQueue);

    >>
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfIoQueueCreate for Write failed %!
    >> STATUS!\n", status));
    >> return status;
    >> }
    >>
    >> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >>
    >> status = WdfIoQueueCreate
    >> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>>ReadMergeQueue);

    >>
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfIoQueueCreate for Read failed %!
    >> STATUS!\n", status));
    >> return status;
    >> }
    >>
    >> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchManual);
    >>
    >> status = WdfIoQueueCreate
    >> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&filterExt-
    >>>WriteMergeQueue);

    >>
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfIoQueueCreate for Write failed %!
    >> STATUS!\n", status));
    >> return status;
    >> }
    >>
    >>
    >> return status;
    >> }
    >>
    >> VOID
    >> FilterEvtIoWrite(
    >> IN WDFQUEUE Queue,
    >> IN WDFREQUEST Request,
    >> IN size_t Length
    >> )
    >> {
    >> NTSTATUS status;
    >> PFILTER_EXTENSION filterExt;
    >> WDFDEVICE device;
    >>
    >> KdPrint(("Disk UFilter: FilterEvtIoWrite Enter Request 0x%x Length: %d
    >> \n", Request, Length));
    >> device = WdfIoQueueGetDevice(Queue);
    >> filterExt = FilterGetData(device);
    >> if(IsQueueEmpty(filterExt->WriteMergeQueue))
    >> {
    >> status = FilterForwardReqToWriteMergeQueue(filterExt, filterExt-
    >>>WriteMergeQueue, Request, Length);

    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: FilterForwardReqToWriteMergeQueue for
    >> Write failed %!STATUS!\n", status));
    >> return;
    >> }
    >> }
    >> else
    >> {
    >> status = FilterMergeRequests(filterExt, Request);
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: FilterMergeRequests for Write failed %!
    >> STATUS!\n", status));
    >> return;
    >> }
    >> }
    >> KdPrint(("Disk UFilter: FilterEvtIoWrite Exit\n"));
    >> return;
    >> }
    >>
    >> NTSTATUS
    >> FilterForwardReqToWriteMergeQueue(
    >> IN PFILTER_EXTENSION filterExt,
    >> IN WDFQUEUE Queue,
    >> IN WDFREQUEST Request,
    >> IN size_t Length
    >> )
    >> {
    >> NTSTATUS status = STATUS_SUCCESS;
    >>
    >> KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Enter\n"));
    >>
    >> status = WdfRequestForwardToIoQueue(Request, Queue);
    >> if(!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfRequestForwardToIoQueue failed%X
    >> \n", status));
    >> FilterCompleteRequest(Request, status, 0);
    >> }
    >> KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Exit\n"));
    >> return status;
    >> }
    >>
    >> NTSTATUS
    >> FilterMergeRequests(
    >> IN PFILTER_EXTENSION filterExt,
    >> IN WDFREQUEST Request
    >> )
    >> {
    >> NTSTATUS status = STATUS_SUCCESS;
    >> WDFIOTARGET ioTarget;
    >> WDF_OBJECT_ATTRIBUTES attributes;
    >> WDFREQUEST NewRequest;
    >> WDFREQUEST MergeRequest;
    >> PVOID buffer0, buffer1;
    >> PCHAR newbuffer;
    >> size_t bufSize0, bufSize1, newbufSize;
    >> WDFMEMORY Memory;
    >>
    >> KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Enter\n"));
    >>
    >> ioTarget = WdfDeviceGetIoTarget(filterExt->WdfDevice);
    >>
    >> WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    >> attributes.ParentObject = ioTarget;
    >>
    >> status = WdfRequestCreate(&attributes,ioTarget,&NewRequest);
    >>
    >> if (!NT_SUCCESS(status))
    >> {
    >> KdPrint(("Disk UFilter: WdfRequestCreate Failed, Error = 0x%X\n",
    >> status));
    >> return status;
    >> }
    >>
    >> status = WdfIoQueueRetrieveNextRequest(filterExt-
    >>>WriteMergeQueue,&MergeRequest);

    >>
    >> if(!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfIoQueueRetrieveNextRequest failed",
    >> status == STATUS_NO_MORE_ENTRIES));
    >> }
    >>
    >> status = WdfRequestRetrieveInputBuffer(Request, 0, &buffer0,
    >> &bufSize0);
    >> if( !NT_SUCCESS(status) )
    >> {
    >> KdPrint (("Disk UFilter:Could not get request memory buffer %X\n",
    >> status));
    >> return status;
    >> }
    >>
    >> status = WdfRequestRetrieveInputBuffer(MergeRequest, 0, &buffer1,
    >> &bufSize1);
    >> if( !NT_SUCCESS(status) )
    >> {
    >> KdPrint (("Disk UFilter:Could not get request memory buffer %X\n",
    >> status));
    >> return status;
    >> }
    >>
    >> WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    >> attributes.ParentObject = NewRequest;
    >>
    >> status = WdfMemoryCreate(
    >> &attributes,
    >> NonPagedPool,
    >> 'UQER',
    >> bufSize0 + bufSize1,
    >> &Memory,
    >> (PVOID*) &newbuffer
    >> );
    >>
    >> if (!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: Failed to alloc mem for urb Error = 0x
    >> %X\n", status));
    >> status = STATUS_INSUFFICIENT_RESOURCES;
    >> return status;
    >> }
    >>
    >> status = WdfRequestRetrieveInputBuffer(NewRequest, 0, &newbuffer,
    >> &newbufSize);
    >> if( !NT_SUCCESS(status) )
    >> {
    >> KdPrint (("Disk UFilter:Could not get request memory buffer %X\n",
    >> status));
    >> return status;
    >> }
    >>
    >> RtlCopyMemory((PVOID)newbuffer, buffer0, bufSize0);
    >> RtlCopyMemory(newbuffer + bufSize0, buffer1, bufSize1);
    >>
    >> newbufSize = bufSize0 + bufSize1;
    >>
    >> status = WdfRequestForwardToIoQueue(Request, filterExt->WriteQueue);
    >> if(!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfRequestForwardToIoQueue failed%X
    >> \n", status));
    >> FilterCompleteRequest(Request, status, 0);
    >> }
    >>
    >> status = WdfRequestForwardToIoQueue(MergeRequest, filterExt-
    >>>WriteQueue);

    >> if(!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfRequestForwardToIoQueue failed%X
    >> \n", status));
    >> FilterCompleteRequest(MergeRequest, status, 0);
    >> }
    >>
    >> WdfRequestFormatRequestUsingCurrentType(NewRequest);
    >>
    >> filterExt->bCompleteWrite = TRUE;
    >>
    >>
    >> WdfRequestSetCompletionRoutine(NewRequest,FilterRequestCompletionRoutine,filterExt);
    >>
    >> ret = WdfRequestSend(NewRequest,Target,WDF_NO_SEND_OPTIONS);
    >>
    >> if (ret == FALSE) {
    >> status = WdfRequestGetStatus (NewRequest);
    >> KdPrint( ("WdfRequestSend failed: 0x%x\n", status));
    >> WdfRequestComplete(NewRequest, status);
    >> }
    >> KdPrint(("Disk UFilter: FilterForwardReqToMergeQueue Exit\n"));
    >> return status;
    >> }
    >>
    >> VOID
    >> FilterRequestCompletionRoutine(
    >> IN WDFREQUEST Request,
    >> IN WDFIOTARGET Target,
    >> PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
    >> IN WDFCONTEXT Context
    >> )
    >> {
    >> WDFREQUEST NewRequest;
    >> PFILTER_EXTENSION filterExt;
    >> NTSTATUS status;
    >> DWORD dwCnt;
    >>
    >> KdPrint(("Disk UFilter: FilterRequestCompletionRoutine Entry Request
    >> 0x%x\n", Request));
    >>
    >> filterExt = (PFILTER_EXTENSION)Context;
    >>
    >> if(filterExt->bCompleteWrite)
    >> {
    >> for(dwCnt=0 ;dwCnt<2; dwCnt++)
    >> {
    >> status = WdfIoQueueRetrieveNextRequest(filterExt-
    >>>WriteQueue,&NewRequest);

    >>
    >> if(!NT_SUCCESS(status)) {
    >> KdPrint(("Disk UFilter: WdfIoQueueRetrieveNextRequest failed",
    >> status == STATUS_NO_MORE_ENTRIES));
    >> continue;
    >> }
    >>
    >> WdfRequestComplete(NewRequest, CompletionParams->IoStatus.Status);
    >> }
    >> filterExt->bCompleteWrite = FALSE;
    >>
    >> }
    >> else
    >> {
    >> WdfRequestComplete(Request, CompletionParams->IoStatus.Status);
    >> }
    >> KdPrint(("Disk UFilter: FilterRequestCompletionRoutine Exit\n"));
    >> return;
    >> }

    >
     
    Egidio [MSFT], Feb 5, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adobbing

    Upgrade Disc From Moduslink - Dispatch?

    Adobbing, Feb 1, 2007, in forum: Windows Vista Installation
    Replies:
    4
    Views:
    183
    Adobbing
    Feb 8, 2007
  2. Pavel A.

    IoGetRemainingStackSize at dispatch?

    Pavel A., Jul 25, 2003, in forum: Windows Vista Drivers
    Replies:
    1
    Views:
    405
    Pavel A.
    Jul 27, 2003
  3. Svyatoslav

    sequence of dispatch routines

    Svyatoslav, Sep 6, 2003, in forum: Windows Vista Drivers
    Replies:
    0
    Views:
    171
    Svyatoslav
    Sep 6, 2003
  4. Kingsley Jarrett
    Replies:
    1
    Views:
    229
    Kingsley Jarrett
    Jan 12, 2005
  5. Maxim S. Shatskih

    Re: Dispatch Requests

    Maxim S. Shatskih, Feb 2, 2010, in forum: Windows Vista Drivers
    Replies:
    6
    Views:
    300
    Egidio [MSFT]
    Feb 3, 2010
Loading...

Share This Page