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:c1ad7296-3697-4996-9138-...
> 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(&deviceAtt ributes,
> 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(&ioQueueCon fig,
> WdfIoQueueDispatchSequential);
>
> ioQueueConfig.EvtIoRead = FilterEvtIoRead;
> ioQueueConfig.EvtIoWrite = FilterEvtIoWrite;
>
> status =
> WdfIoQueueCreate(device,&ioQueueConfig,WDF_NO_OBJE CT_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,WdfIoQueue DispatchManual);
>
> status = WdfIoQueueCreate
> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&f ilterExt-
>>ReadQueue);
>
> if (!NT_SUCCESS(status)) {
> KdPrint(("Disk UFilter: WdfIoQueueCreate for Read failed %!
> STATUS!\n", status));
> return status;
> }
>
> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueue DispatchManual);
>
> status = WdfIoQueueCreate
> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&f ilterExt-
>>WriteQueue);
>
> if (!NT_SUCCESS(status)) {
> KdPrint(("Disk UFilter: WdfIoQueueCreate for Write failed %!
> STATUS!\n", status));
> return status;
> }
>
> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueue DispatchManual);
>
> status = WdfIoQueueCreate
> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&f ilterExt-
>>ReadMergeQueue);
>
> if (!NT_SUCCESS(status)) {
> KdPrint(("Disk UFilter: WdfIoQueueCreate for Read failed %!
> STATUS!\n", status));
> return status;
> }
>
> WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueue DispatchManual);
>
> status = WdfIoQueueCreate
> (device,&ioQueueConfig,WDF_NO_OBJECT_ATTRIBUTES,&f ilterExt-
>>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,FilterRe questCompletionRoutine,filterExt);
>
> ret = WdfRequestSend(NewRequest,Target,WDF_NO_SEND_OPTIO NS);
>
> 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;
> }