How do you delete a file or directory1 in Win32/64 ? You have primarily three options –
- DeleteFile, RemoveDirectory
- MoveFileEx (…, MOVEFILE_DELAY_UNTIL_REBOOT…)
- CreateFile (…, FILE_FLAG_DELETE_ON_CLOSE…) followed by CloseHandle
First of all DeleteFile cannot be used to delete a directory, you are supposed to use RemoveDirectory instead. If you pass a directory path to DeleteFile, the call fails and GetLastError returns error 5 (ERROR_ACCESS_DENIED) which is rather befuddling when you hit it for the first time. This happens even if the logged on user has DELETE access permissions for the directory. So what gives ?
DeleteFile is roughly three system calls combined together into one win32 API – NtOpenFile, NtSetInformationFile and NtClose. NtOpenFile is declared in ntifs.h like thus –
When a directory path is passed to DeleteFile – the call to NtOpenFile2 (which can open a file or directory) fails with STATUS_FILE_IS_A_DIRECTORY (0xC00000BA – The file that was specified as a target is a directory and the caller specified that it could be anything but a directory). This status code gets mapped subsequently to Win32 ERROR_ACCESS_DENIED. The error happens because DeleteFile invokes NtOpenFile2 with FILE_NON_DIRECTORY_FILE bit set in OpenOptions parameter thus ensuring that directories cannot be deleted via DeleteFile.
RemoveDirectory is not very different3 from DeleteFile and uses the same system calls. When RemoveDirectory invokes NtOpenFile however, it calls with FILE_DIRECTORY_FILE bit in OpenOptions parameter and therefore can operate on directories and not files. If a file path is passed to RemoveDirectory, NtOpenFile fails with STATUS_NOT_A_DIRECTORY (0xC0000103 – A requested opened file is not a directory) which gets mapped into Win32 error 267 (ERROR_DIRECTORY)4.
- 1 2