Deleted but not yet forgotten

Date:June 7, 2004 / year-entry #223
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
Comments:    18
Summary:Earlier, I discussed the interactions of the various FILE_SHARE_* flags, then Larry Osterman took this as inspiration to give a history of the file sharing flags. If a file is opened with delete-sharing enabled and you delete the file, the file doesn't actually go away until the open handles are closed. In the meantime, the...

Earlier, I discussed the interactions of the various FILE_SHARE_* flags, then Larry Osterman took this as inspiration to give a history of the file sharing flags.

If a file is opened with delete-sharing enabled and you delete the file, the file doesn't actually go away until the open handles are closed. In the meantime, the file hangs around as a zombie. (Under Unix, a deleted file with open handles is removed from the directory and merely floats around in the happy sea of inodes with no name.)

Why doesn't the file go away?

Well, one reason is that device drivers can ask for the name of the file that corresponds to an open handle. If the directory entry were removed, then there would be no name to return! (What would you expect to be returned from GetModuleFileName if the module no longer exists? Should it be possible for GetModuleFileName to return ERROR_FILE_NOT_FOUND?)

Another reason is that if power were to be lost while a "forgotten but not lost" handle was still open, you would now have lost clusters on the disk.

And a final reason is that a "pending delete" file isn't actually gone for good. A driver can "undelete" the file by clearing the delete-on-close flag!


Comments (18)
  1. Scott says:

    The Unix way has the advantage of allowing you to replace an in-use file.

    Relying on applications using a specific flag like delete-sharing doesn’t do much good since most applications don’t.

  2. Jack Mathews says:

    These are excuses to get around Win32’s coupling of the directory structure and files. The device driver and GetModuleFileName situations are not so much problems with architecture as they are design limitations in Win32. If a file handle could have no assiciated file, then people would get used to it pretty fast. Same with modules. There are plenty of other idiosyncracies with Win32 that people have to learn over the years.

    As for "forgotten but not lost," when a file gets deleted, put the file node number in a list on the filesystem of nodes that need to get deleted on next boot in the case of a power loss. Simple.

    This is unfortunately another blog entry where the answer to Win32’s aberrent behavior is justified, but the real answer is that it’s because Win32 is what it is.

  3. Raymond Chen says:

    Yes, that’s just the way it is. I’m not so much justifying the original design as justifying why it can’t be changed at this point. Too much relies on the old behavior.

  4. Centaur says:

    Actually, I have once had an experience of accidentally deleting a file while it was being used. “Oops! If I close that media player, the file will be gone; I do not have the skill of ‘clearing the delete-on-close flag’, so this is not an option; what if I reset the machine?” So I did, and after a bootup and a chkdsk the file was there intact. I’d be really impressed (and disappointed) if Windows remembered that this file had been condemned.

  5. asdf says:

    How come handle to filename mapping isn’t exposed in the win api?

  6. Raymond Chen says:

    I don’t know. Probably because there hasn’t been a good reason to, and because if you do it, then people will rely on it even more than they inadvertently do now, making it even harder to change the behavior in the future.

  7. Ben Hutchings says:

    Since a file shared with FILE_SHARE_DELETE can be renamed while it’s still open, the name can become invalid at any time even though the file can’t be deleted. So any program that relies on re-opening such a file by name is already broken. This kluge just reduces the problem to a race condition.

  8. Jack Mathews says:

    I’m mostly curious have programs like this work:

    http://www.sysinternals.com/ntw2k/freeware/handle.shtml

    … that actually get the filename from the handle. I’m sure if I dust off Advanced Windows I can find it in the kernel section, but that’s at home right now :)

  9. Raymond Chen says:

    Scott: Of course many said applications *rely* on the file not being deleted while it’s open. For example, they may try to open it a second time and not handle the error case.

  10. Raymond Chen says:

    Ben: But a program that opens *without* FILE_SHARE_DELETE can be certain that the file cannot even be renamed. It’s the programs that open without FILE_SHARE_DELETE (i.e.: nearly all of them) that I’m concerned about.

    Jack: That program installs a driver and therefore can use the driver function.

  11. Michael says:

    Re: handle to name mapping:

    The Win32 layer is actually just that – a layer on top of the underlying NT operating system APIs which are mostly in the kernel.

    The kernel does keep track of the name of the file that was opened, but it’s in the kernel NT namespace, not in the win32 namespace and sometimes it’s not possible to (easily) map back from the NT namespace to the Win32 namespace.

    So, to do this reliably would entail the Win32 layer somehow capturing the original path and keeping it associated with the handle. So then either Win32 handles aren’t kernel handles any more or the kernel handle table rundown needs to understand managing lifetime of the copy of the win32 path.

    (You can get a perspective on playing with the NT namespace by using \? paths with the Win32 APIs – they are tunnelled through to the NT namespace by replacing the 2nd slash with another question mark – e.g. "\?foo" turns into "??foo".)

    For the most part the NT layer is a much better API set than the Win32 layer although more complicated in many respects (disassemble kernel32!CreateFileW some time in a debugger).

    But this file handle/deletion semantic is actually very deep in the NT model also. It’s believed that if someone were able to call CreateFileW() on c:foo.txt and then later on call it again without having closed the handle and end up with a different handle on a different file that happens to be at the same point in the namespace there would be massive compatibility problems.

    I’m somewhat skeptical but I do beat on the FS guys about this somewhat regularly.

  12. Johan Thelin says:

    Would this be useable to create auto-self-deleting temporary files as one can in Unix? (If I look to the other comments, it does not seem so…)

  13. JP says:

    re: auto-self-deleting temporary files

    Isn’t that what the FILE_FLAG_DELETE_ON_CLOSE flag is for?

    As far as I’m concerned the only thing that’s broken here is that FILE_SHARE_DELETE isn’t the default. Applications shouldn’t restrict the user’s ability to delete and rename files unless there are very good reasons to do so.

  14. Raymond Chen says:

    FILE_SHARE_DELETE is off by default because programs designed for Windows 95/98/Me assume that files cannot be deleted while they are open. (Notice that Windows 95/98/Me didn’t support FILE_SHARE_DELETE.)

    In other words, we’re stuck with the default being "deny delete" for compatibility reasons.

  15. Paul Bartrum says:

    Raymond: Would it be possible to change the default for programs written for Longhorn?

    That way, you could have your cake and eat it too. At the cost of increased complexity in the API, of course.

  16. Mike says:

    This reminds me of a bug I discovered in Windows 2000 (well, probably, it could have been our bug but it seemed unlikely). I put it down to the delete on close flag not quite being used in the right way. The problem did not occur on Windows XP.

    We had a custom USB driver that had the usual GUID named device nodes in the NT namespace. Our application kept the device node open some of the time and it was possible for the following sequence of events to occur:

    1. Device is opened by application.

    2. Device is physically disconnected. Windows tries to delete the device node and fails because it is still open. Instead it just marks it for deletion on close.

    3. Device is reconnected. Windows tries to recreate the device nodes but they already exist. :(

    4. The application finally notices that the device has gone away and it closes the device. The device nodes are now deleted.

    So, you’re left with an attached device that no longer has its device nodes. The only solution I found was to disconnect the device and reconnect it again.

    Mike.

  17. asdf says:

    Who is the person that determines that handle to filename mapping isn’t important enough to be in the winapi but relatively useless functions like GetMessageExtraInfo/SetMessageExtraInfo and GetBitmapDimensionEx/SetBitmapDimensionEx (first question, why did they even bother to make an ex version? second question, if windows doesn’t use this information at all why does msdn say what the units of measurement are?) should be?

  18. Raymond Chen says:

    Those functions are historical; the Win32 team had no choice but to support them. (The Ex versions were necessary during the conversion from Win16 to Win32.)

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index