March 6th, 2026
heartlike2 reactions

When Read­Directory­ChangesW reports that a deletion occurred, how can I learn more about the deleted thing?

A customer was using Read­Directory­ChangesW to monitor changes to a directory. However, they ran into a problem when they received a FILE_ACTION_REMOVED notification: Since the notification is raised when the item is deleted, they can’t do a Get­File­AttributesEx to find out whether the deleted item was a file or a subdirectory, and if it was a file, the size of the deleted file. Their program needs that information as part of its directory monitoring, so what mechanism is there to recover that information?

The Read­Directory­ChangesW function provides no way to recover information about the item that was deleted. All you get is the name of the item.

Recall that Read­Directory­ChangesW is for detecting changes to information that would appear in a directory listing. The idea is that your program performs a Find­First­File/Find­Next­File to build an in-memory cache for a directory, and then you can use Read­Directory­ChangesW to perform incremental updates to your cache. For example, if you see a FILE_ACTION_ADDED, then you can call Get­File­Attributes or Get­File­Attributes­Ex to get information about the thing that was added and update your cache. That way, when you see the FILE_ACTION_REMOVED, you can read the entry from your cache to get the information about the item that was removed (as well as removing it from your cache).

There is a race condition here, however. If the item is added and then immediately deleted, then when you get around to calling Get­File­Attributes, it won’t be there, so you don’t actually know what it was.

Fortunately, there’s Read­Directory­Changes­ExW. If you ask for Read­Directory­Notify­Extended­Information, then you get back a series of FILE_NOTIFY_EXTENDED_INFORMATION structures, and in addition to the action and the file name, those also contain directory information about the item, including its file attributes. This information is provided both on the add and on the remove, so you can just look at the FileAttributes on the FILE_ACTION_REMOVED to see whether it was a file or a folder, and if it was a file, you can use the FileSize to see the logical size of the file at the time it was deleted.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

11 comments

Discussion is closed. Login to edit/delete existing comments.

Sort by :
  • alan robinson

    I didn’t know directories had genders. It is very forward looking that you can change them tho, and even register to be notified of the change (which is good since the effect seem to be minimal). Seems like somebody messed up the capitalization of the function name tho.

    • Me Gusta · Edited

      The capitilisation is fine. The function is called Read Directory Changes, there is the suffix for whether it is ANSI (A) or Unicode/Wide(W) which is a well known Windows NT thing.

      Unlike functions like CreateFile which has a generic name, but is implemented as either CreateFileA for the ANSI version or CreateFileW for the Unicode/Wide version, there was never a generic ReadDirectoryChanges. Since this was a Unicode only funtion, it only ever had the W version of the function, hence ReadDirectoryChangesW. You can see this in other functions, Like FindFirstFileNameW and FindFirstStreamW.

      • LB

        If only we had -A versions now that Windows 10 and 11 have UTF-8 support…

  • Igor Levicki

    On a side note Raymond, someone is stealing your clicks:

    hxxps://theoldnewthing.livejournal.com/

    (link neutered on purpose)

  • Igor Levicki

    @Raymond Chen

    And here we are, 4 decades later and Windows still doesn't have the single most useful notification -- file close notification.

    If you can't tell when the added file was actually fully written and closed by the creator owner after being created then having that file added notification is useless because you have to resort to polling in 2026 to be able to monitor newly written files.

    Sure, you can write a filesystem filter driver, but then you have to "pay to play" (an extortion racket for EV certificates, Azure Portal access and all other stuff that goes with that) meaning...

    Read more
      • Harry Johnston

        Analogously, you can install a system service to read the change journal on your application’s behalf.

        And sure, this won’t fit every single use case ever. I never said it did!

      • Igor Levicki

        @Harry Johnston

        1. With minifilter driver you need admin rights just to install it and then you can run the app without elevation. For example, an image viewer which parses file formats which can have malicious payloads shouldn't be run elevated but it might need to monitor a folder for new files. Not to mention that in secured environments (such as an ATM where software runs with limited user account and hardened security) reading USN journal is impossible.

        2. And so is on ExFAT which has has no journal, and for ReFS you'd have to recognize it and explicitly handle different size...

        Read more
      • Harry Johnston

        Yes, of course. You also need admin rights to install a filesystem filter driver. At least using the change journal doesn’t require an EV certificate.

      • Igor Levicki

        I hope you were joking? Are you aware you need admin rights for FSCTL_QUERY_USN_JOURNAL?

      • LB

        Yeah but UWP apps rightly don’t have permissions at that level so they have to do the wait and poll dance.