From: uba on 4 Feb 2010 07:40 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 4 Feb 2010 08:30 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 5 Feb 2010 08:18 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 5 Feb 2010 15:47 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 5 Feb 2010 15:54 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; >> } >
First
|
Prev
|
Pages: 1 2 3 4 Prev: Multiple VIDs in the same INF file Next: How to trigger copy of usbser.sys from CAB |