Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTFSD
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Forcing the Cache Manager to release its reference to a File Object

rstruempfrstruempf Member Posts: 103

I've run up against a brick wall, and am hoping someone here can give me some advice. You know that File Object that the Cache Manager (not sure if that is technically accurate) latches onto to use for internal file management, caching, etc.? I need that to go away for a specified file that has no other open handles to it. I believe what I am looking to do is to evict that file from cache so that Cc will release the file object.

I need to do this for two reasons:

One is that the information in the stream context is out of date. I don't want to have to make marks on the wall to try to catch stream context for file X and then add locking to perform the update. I'd like to just have it go away, and the next time the file is accessed, start anew, peacefully, in PostCreate.

The other is that I process the data as it is read into the cache, and I need to redo that processing for the file based on new configuration.

I thought I had found the answer in CcCoherencyFlushAndPurgeCache(). Based on the documentation, I thought that I could invoke one of the Acquire For IRPs to acquire the file, and then call this function. But I have read through many an old post here and the advice is always the same, "Thou Shalt Not Call Cc functions for objects that you don't own."

So that is my rock. What advice do you have Mr. Hard Place? :/

Comments

  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,131

    I cannot remember your use case. Is this the ZFS port? If so then you own the cache and it suffices to call CcCoherencyFlushAndPurgeCache
     

    Good luck working out what locks you need. You need to interlock against CcInitializeCacheMapand CcUninitializeCacheMap but not interlock against paging writes.
     

    If you are in cleanup you might be able toset the length to zero in CcUninitializeCacheMap But beware of waiting for the event because it occassionaly won't fire (which is I suspect why FAT didn't use it the last time I looked).
     

    If you are a filter then you do not own the cache and so this is the standard reply

    In general you cannot. What are you going to do if the user has sections mapped?
     
    But you may get some mileage with the IRP_MJ_FLUSH IRP_MN_FLUSH_AND_PURGE combo.
     

    What you MUST NOT DO (unless you own the cache) is what people often crop up and say "just call such and such a Cc Function" - those calls are reserved for people who are managing the cache.
     

  • rstruempfrstruempf Member Posts: 103

    I'm the latter, a filter. I will test the IRP_MJ_FLUSH IRP_MN_FLUSH_AND_PURGE combo you mentioned and see if that gets at least some of what I need.

    Thanks again, Rod!

  • rstruempfrstruempf Member Posts: 103

    Rod, I see that I can use FltFlushBuffers() to send IRP_MJ_FLUSH from a minifilter. Any idea how to generate this IRP using IRP_MN_FLUSH_AND_PURGE?

  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,131

    You’ll probably need to do it by hand, using FltAllocateCaabackData and FltPerformSynchrousIo. There should be examples in the archive

  • rstruempfrstruempf Member Posts: 103

    Perfect! Thanks.

  • rstruempfrstruempf Member Posts: 103

    @rod_widdowson This worked perfectly. Thanks for your advice.

    PFLT_CALLBACK_DATA data;
    FltAllocateCallbackData(_fltInstance, _fileObject, &data);
    data->Iopb->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
    data->Iopb->MinorFunction = IRP_MN_FLUSH_AND_PURGE;
    FltPerformSynchronousIo(data);
    NTSTATUS status = data->IoStatus.Status;
    FltFreeCallbackData(data);
    return status;

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA