IRP_MJ_READ stays in a loop

Hello.

I’ve been developing an encryption minifilter as posted before in other threads, but I encountered a problem that I’m not able to fix. I can’t find why is this happening. I’ll describe my scenario and when the loop occurs.

Scenario: I want to decrypt files that has a header and show only the decrypted text without the header. For example, if I has [XYZ] as the file, the application opening the file should see only [YES]. To do this:

1-In postcreate, if the file is of my interest (it has a header), I create a stream context. This streamcontext has also a header buffer, where I write the header of the file.

2-In preread, I get the stream context and, if successful, modify the read offset to the size of the header and register a post-callback.

3-In postread, I decrypt the buffer and show the new content to the application.

This behaviour won’t fail if I don’t modify the offset. I.e. I can decrypt without problems the full file+header.

But if I modify the offset, then the driver enter a loops and it keeps doing the irp_mj_read, catching preread/postread forever and writing it to the buffer. When I stop the driver, the file has 99999(or whatever number) times the decypted text: yesyesyesyesyesyes…

Why could this happen? I can include some code if necessary.

Thanks in advance.

It sounds like the byte offset isn’t being updated properly. Presumably the
application has a synchronous handle and is just reading until it gets back
end of file. If the offset never changes the application will just keep
reading the same data over and over.

Do you call FltSetCallbackDataDirty after changing the offset?

If you can reproduce this on FAT, build your own copy of the source from the
WDK and put it on your test system. Then set breakpoints in the read path
and check the difference between the working and non-working cases. Fiddling
with altitudes to put ProcMon between your filter and the file system might
also be interesting. (As an aside, both of these things will serve you well
in the future so good to get practice doing this anyway)

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Hello.

I’ve been developing an encryption minifilter as posted before in other
threads, but I encountered a problem that I’m not able to fix. I can’t find
why is this happening. I’ll describe my scenario and when the loop occurs.

Scenario: I want to decrypt files that has a header and show only the
decrypted text without the header. For example, if I has [XYZ] as
the file, the application opening the file should see only [YES]. To do
this:

1-In postcreate, if the file is of my interest (it has a header), I create a
stream context. This streamcontext has also a header buffer, where I write
the header of the file.

2-In preread, I get the stream context and, if successful, modify the read
offset to the size of the header and register a post-callback.

3-In postread, I decrypt the buffer and show the new content to the
application.

This behaviour won’t fail if I don’t modify the offset. I.e. I can decrypt
without problems the full file+header.

But if I modify the offset, then the driver enter a loops and it keeps doing
the irp_mj_read, catching preread/postread forever and writing it to the
buffer. When I stop the driver, the file has 99999(or whatever number) times
the decypted text: yesyesyesyesyesyes…

Why could this happen? I can include some code if necessary.

Thanks in advance.

Thanks for your reply, Scott.

To answer your question, yes, I call FltSetCallbackDataDirty after changing the offset. I even commented that line to check what happens and the behaviour is the same.

I’ll play with the altitudes to check what is happening with procmon, but I guess I’ll only see a lot of READs, but not the cause.

Do you have another guessing of what could be the cause of it? What should I modify aswell if I modify the offset of the read operation? Maybe the set information, query… I don’t know where should I look.

My description is my best guess based on the information provided. There are too many possibilities and the reasons can vary depending on the calling application and it’s I/O pattern.

Compare a ProcMon trace without your filter to a trace with your filter. Clearly in your case the app is missing its terminating case. Compare the operations and data returned up to the infinite loop and see what’s different.

In the long run you are going to need to handle every operation that has anything to do with size. This includes the zillion (or so) query attributes, directory info types, and set size operations. Byte range locks are another fun one. You also want to make sure that you test with memory mapped files. (Note that this stuff is all very well tested by the HLKs and its included IFS Tests). The archives should have lots of good info on other random stuff that needs attention.

-scott
OSR
@OSRDrivers

Not sure, but you may need to play with the offset in the file object in
post read if this is a syncrhonous non paging IO. The FSD will have set
what it thinks it should be but your user’s view is different.