C++/Win32: How to wait for a pending delete to complete

前端 未结 13 1106
不思量自难忘°
不思量自难忘° 2020-11-30 03:20

Solved:

  • Workable solution: sbi\'s answer
  • Explanation for what really happens: Hans\'s answer
  • Explanation for why OpenFile do
13条回答
  •  鱼传尺愫
    2020-11-30 03:44

    I just had this exact issue and took TWO steps to address it; I stopped using C/C++ stdlib apis and ::DeleteFile(..), and switched to:

    1. ::MoveFileEx(src,dest,MOVEFILE_WRITE_THROUGH);. See: MOVEFILE_WRITE_THROUGH

    2. h = ::CreateFile(DELETE | SYNCHRONIZE,OPEN_EXISTING,FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_OPEN_REPARSE_POINT); ::CloseHandle(h);

    The above are pseudo calls showing the relevant flags, specifically note that there is NO sharing on the CreateFile call used to achieve delete.

    Together they gave me better precision on the rename and delete semantics. They are working in my code now and have improved the precision and control from other threads/processes (watching the file-system for changes) interjecting actions on the file due to latencies [or sharing] in the other rename and/or delete APIs. Without that control, a file set to delete when its last kernel-handle was closed might actually languish open until the system was rebooted, and you might not know.

    Hopefully those feedback snippets might prove useful to others.

    Addendum: I happen to use hardlinks for a portion of the work I do. It turns out that although you can create hardlinks on a file that is OPEN, you cannot delete ANY of them until all handles to ANY of the underlying data-stream(s) to that NTFS file are closed. That is weird since:

    • the OS tracks by them using a single ID in what is effectively an INode (ntfs uid).
      • https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilebyid
      • https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
      • https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilenamew
      • https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_info
    • you can create hardlinks while it is open, just not delete them
      • hardlinks are actually alias-names in the attributes (XATTRs) in NTFS
    • you can rename them while it is open
      • so changing the name doesn't matter

    Which would lead you to think that only the last hardlink should be non-deletable while the kernel has one or more open-file handles referring to the hardlinked NTFS File's MFT-Entry/ATTRs. anyway, just another thing to know.

提交回复
热议问题