folder can be deleted only in case it empty, otherwise we got error STATUS_DIRECTORY_NOT_EMPTY
- Indicates that the directory trying to be deleted is not empty.
from another side - if you have opening handle for file - it can not be deleted until you not close it handle (something here changed begin from win10 rs1)
so if you monitor some child sub-folder with ReadDirectoryChangesW
you have opened handle to it, and parent can not (before WIN10_RS1) be deleted until you not close this handle.
in general process look like - when somebody try delete folder - it must enumerate all files(sub-folders) inside it and delete it first. when delete operation will be apply on folder for which ReadDirectoryChangesW
called - the io request will be completed with status STATUS_DELETE_PENDING
- A non close operation has been requested of a file object with a delete pending. (it converted to win32 error code ERROR_ACCESS_DENIED
- Access is denied.). when you got this error from ReadDirectoryChangesW
you must close your directory handle used in this call. then is raise - who is first - you close directory handle or another code try delete parent folder...
begin from win10 rs1 possible delete parent, even if somebody hold open handle to it child file(folder) by calling NtSetInformationFile
with FileDispositionInformationEx
or SetFileInformationByHandle
with FileDispositionInfoEx
.
the magic here in new flag FILE_DISPOSITION_POSIX_SEMANTICS
(Specifies the system should perform a POSIX-style delete)
Normally a file marked for deletion is not actually deleted until all
open handles for the file have been closed and the link count for the
file is zero. When marking a file for deletion using
FILE_DISPOSITION_POSIX_SEMANTICS
, the link gets removed from the
visible namespace as soon as the POSIX delete handle has been closed,
but the file’s data streams remain accessible by other existing
handles until the last handle has been closed.
so when we use this - file itself of course will be not deleted, until caller of ReadDirectoryChangesW
not close self handle, but file will be removed from the parent folder. as result parent folder can became empty, after which we can delete it.
note that DeleteFileW
and RemoveDirectoryW
here will be not work here, because they used old information class FileDispositionInformation with FILE_DISPOSITION_INFORMATION
ULONG DeletePosix(PCWSTR lpFileName)
{
HANDLE hFile = CreateFileW(lpFileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
static FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE| FILE_DISPOSITION_POSIX_SEMANTICS };
ULONG dwError = SetFileInformationByHandle(hFile, FileDispositionInfoEx, &fdi, sizeof(fdi))
? NOERROR : GetLastError();
// win10 rs1: file removed from parent folder here
CloseHandle(hFile);
return dwError;
}
and of course child must be open with FILE_SHARE_DELETE
in other calls, otherwise we simply can not open it with DELETE
access later