JustKernel

Ray Of Hope

ZwReadFile and FltReadFile

Today I was working on mini filter driver which required me to copy some data from one file to other. Looked quite a simple operation with ZwReadFile doing the reading and ZwWritefile to write the data. But then I noticed that after doing few reads and write ZwReadFile hanged. Interesting…. Added few traces before and after the call, debugged it further to check the IRQ level and APCs status while issuining successful ZwReads and the failed one.

I noticed that while issuing ZwReadFile IO was of type PAGING_IO and also APCs were disabled and logically if you are going to call ZwReadFile with APCs disabled (for synchrnous IO) its bound to fail. Did some reasearch on internet and my theory was confirmed.https://www.osronline.com/showthread.cfm?link=224259

Further I replaced ZwCreateFile with FltCreateFileEx and then replaced ZwReadFilw with FltReadFile using the pointer to file object returned during FltCreateFileEx. This API returned an error INVALID_DEVIE_OBJECT. I was confused as to why ZwReadFile was successfull but FltReadFile was failing. Again went through different websites and ddk documentation and was able to identify the root cause.

The root cause was that the instance parameter that I was passing to the FltReadFile was wrong. My minifilter driver is supposed to filter some files that are in C drive/voluem, but the file I was reading was in my F drive (different volume). So when I was trying to pass fltobjects->instance in fltRead it was looking for a file in my C drive. Now to do fltreadFile on another volume, I have to find minifilter instances attached to that volume and then issue fltreadFile.

Some of the helper calls that I used:
status = FltEnumerateVolumes(fltObjects->Filter, pVolumeList, 255, &numVolList);
if (NT_SUCCESS (status))
{
for ( i = 0; i < numVolList; i++) { FltGetVolumeName(pVolumeList[i], NULL, &BufferSizeNeeded); FltEnumerateInstances(pVolumeList[i], fltObjects->Filter, &InstanceList, 1, &NumInstances);
DbgPrintEx( DPFLTR_IHVDRIVER_ID, FAKEVHDX_ERROR_LEVEL,
“number of instances for volume %d \n”, NumInstances);
VolumeName.Buffer = (PWCH)ExAllocatePool( NonPagedPoolNx, BufferSizeNeeded );
if ( NULL != VolumeName.Buffer )
{
VolumeName.MaximumLength = (USHORT)BufferSizeNeeded;
FltGetVolumeName(pVolumeList[i], &VolumeName, NULL);
DbgPrintEx( DPFLTR_IHVDRIVER_ID, FAKEVHDX_ERROR_LEVEL,
“VMDKOpenImageFile Volume Name :%wZ Idx:%d \n”, &VolumeName);
ExFreePool(VolumeName.Buffer);
}
}

mail_you_queries: anshul_makkar@justkernel.com

Tags: , ,


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.