CachedIo directly wrote to the disk

I wrote my minifilter driver to test file write irp. In pre-write I called dbgprint to print flags, but found the output information is not consistent with my expectations.

My expectation is that the first time is cache write and the second time is noncache and paging io write.

But the logs shows that cache io direct write the data to the disk.(in 2)

i use filetest.exe created a file named "a.txt",and then wrote 0x1(1) bytes data, it will show me 2 lines logs, i know that one is cache io(write to the cache), and the other is lazy writer non cache and paging io(real write to the disk):

IsFastIo=0, NonCachedIo=0, PagingIo=0, SyncPagingIo=0, FileSize=0, AllocationSize=0, ValidDataLength=0, StartingVbo=0, ByteCount=1, FileFlags=0x40042, IrpFlags=0x60A00

IsFastIo=0, NonCachedIo=1, PagingIo=1, SyncPagingIo=1, FileSize=1, AllocationSize=8, ValidDataLength=1, StartingVbo=0, ByteCount=4096, FileFlags=0x44042, IrpFlags=0x20043

Then i use filetest.exe created a file named "b.txt",and then wrote 0x1001(!!!!important diffrence 4097) bytes data,but only one cached log show me. it is NOT noncache, and NOT paging io, and after wating for a while, still NO the lazy writer's write log.

IsFastIo=0, NonCachedIo=0, PagingIo=0, SyncPagingIo=0, FileSize=0, AllocationSize=0, ValidDataLength=0, StartingVbo=0, ByteCount=4097, FileFlags=0x40042, IrpFlags=0x60A00

I have done this experiment many times,only the diffrence is the size to write(1 byte and 4097 bytes) ,and I can reproduce the above situation every time.

I want to ask:
1.In 2 ,why only cache write log, no disk write log?
2.When was the data written to disk?

What file system? The bits in the request are for guidance only and RDR in particular is (was maybe) renowned for doing what it wants despite what you say

Thank you for your attention, Windows 10 Professional in VMware Workstation, NTFS, if you need more information, you can leave a message again.

I seem to have found the cause of the problem.

For debugging purposes, I used the FltObjects->FileObject->FileName field at the beginning of prewrite to filter the file names a.txt and b.txt. However, the second log file name was "$ConvertToNonresident", so I filtered it out. Therefore, the next step of printing the log was not executed. After removing the judgment conditions, it was normal:

IsFastIo=0, NonCachedIo=0, PagingIo=0, SyncPagingIo=0, FileSize=0, AllocationSize=0, ValidDataLength=0, StartingVbo=0, ByteCount=1, FileFlags=0x40042, IrpFlags=0x60A00

IsFastIo=0, NonCachedIo=1, PagingIo=1, SyncPagingIo=1, FileSize=4097, AllocationSize=8192, ValidDataLength=4097, StartingVbo=0, ByteCount=8192, FileFlags=0x40100, IrpFlags=0x20043

FltObjects->FileObject->FileName Why is it $ConvertToNonresident?

Right, The use of fields within the FileObject are reserved to the FSD. Many drivers get this wrong (including, distressingly, some Microsoft ones).

I guess I assume you were using Procmon to monitor and that gets this sort of thing right.

1 Like

I corrected my incorrect description above to facilitate later reference.

I seem to have found the cause of the problem.

For debugging purposes, I used the FltObjects->FileObject->FileName field at the beginning of prewrite to filter the file names a.txt and b.txt. However, the second log file name was "$ConvertToNonresident", so I filtered it out. Therefore, the next step of printing the log was not executed. After removing the judgment conditions, test 2 show right log:

\Users\test\Desktop\test\b.txt IsFastIo=0, NonCachedIo=0, PagingIo=0, SyncPagingIo=0, FS=0, AS=0, VDL=0, StartingVbo=0, ByteCount=4097, FileFlags=0x40042, IrpFlags=0x60A00

(null) IsFastIo=0, NonCachedIo=1, PagingIo=1, SyncPagingIo=1, FS=4097, AS=8192, VDL=4097, StartingVbo=0, ByteCount=8192, FileFlags=0x40100, IrpFlags=0x20043

FltObjects->FileObject->FileName Why is it null or $ConvertToNonresident?

As Rod said, the fields in the FILE_OBJECT are for the file system driver's use. In particular, the FileObject field is valid only during processing of IRP_MJ_CREATE. The rest of the time you cannot rely on it. That is one reason why the Filter Manager provides the name query API (FltGetFileNameInformation). If you need a file's name, use the API, don't use the FILE_OBJECT.FileName field.

1 Like