From: uba on

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

From: Don Burn on
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" <kid07.uba(a)gmail.com> wrote in message
news:ff6295d7-a968-4da4-ae6d-5bb9e59f1fbe(a)a16g2000pre.googlegroups.com...
>
> 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




From: uba on
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;
}
From: Egidio [MSFT] on
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" <kid07.uba(a)gmail.com> wrote in message
news:c1ad7296-3697-4996-9138-01d3588b3c22(a)u15g2000prd.googlegroups.com...
> 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;
> }

From: Egidio [MSFT] on
For the test below mark the queue as parallel (from serial) else you will
not see your callback invoked.

"Egidio [MSFT]" <egidio(a)online.microsoft.com> wrote in message
news:O$IV7RqpKHA.3776(a)TK2MSFTNGP04.phx.gbl...
> 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" <kid07.uba(a)gmail.com> wrote in message
> news:c1ad7296-3697-4996-9138-01d3588b3c22(a)u15g2000prd.googlegroups.com...
>> 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;
>> }
>