DeleteFile and RemoveDirectory, “delete” the file/directory by setting FILE_DISPOSITION_INFORMATION.DeleteFile to 1. This is done by calling NtSetInformationFile with FILE_INFORMATION_CLASS parameter set to FileDispositionInformation. This marks the file/directory for deletion and the file gets deleted after last handle is closed. This is very important and easy to overlook. DeleteFile success does not mean that file is deleted from the file system5 6.

A file deletion typically means (a) operating on the parent directory and removing the entry for the file in the directory (b) releasing the clusters used by the file into free space available. The latter can only happen after the hard link count goes to zero.

DeleteFile/RemoveDirectory do not delete reparse point/symbolic link targets7. You have to use option 3 for achieving that.

So then what is NtDeleteFile for if it is not used by DeleteFile ? Hmm… Perhaps another post is in order here ?

1 empty directory or a junction to an empty/non-empty directory
2 DeleteFile calls NtOpenFile in Vista like thus –

ntStat = NtOpenFile (&FileHandle, //FileHandle
                     DELETE|FILE_READ_ATTRIBUTES //DesiredAccess
                     &oa, //ObjectAttributes
                     &iosb,//IoStatusBlock
                     FILE_SHARE_READ|
                     FILE_SHARE_WRITE|
                     FILE_SHARE_DELETE,//ShareAccess
                     FILE_OPEN_REPARSE_POINT|
                     FILE_OPEN_FOR_BACKUP_INTENT|
                     FILE_NON_DIRECTORY_FILE);//OpenOptions

3 RemoveDirectory opens the directory in Vista like thus –

ntStat = NtOpenFile (&FileHandle, //FileHandle
                     SYNCHRONIZE|DELETE|FILE_READ_ATTRIBUTES //DesiredAccess
                     &oa, //ObjectAttributes
                     &iosb,//IoStatusBlock
                     FILE_SHARE_READ|
                     FILE_SHARE_WRITE|
                     FILE_SHARE_DELETE,//ShareAccess
                     FILE_OPEN_REPARSE_POINT|
                     FILE_OPEN_FOR_BACKUP_INTENT|
                     FILE_SYNCHRONOUS_IO_NONALERT|
                     FILE_DIRECTORY_FILE);//OpenOptions

4which makes a little bit more sense than ERROR_ACCESS_DENIED from DeleteFile.

5Directories that have files cannot be deleted. Therefore if software is removing a directory and its sub-directories recursively, based on the assumption that DeleteFile takes immediate effect,  there may be directory removal errors because they are not empty yet. This makes it tricky to delete a directory recursively.

6In fact documentation suggests (which I have not verified) that fresh creates on a file marked for delete – may succeed as long as FILE_SHARE_DELETE flag  is passed.

7That is because FILE_OPEN_REPARSE_POINT flag suppresses reparse point processing when opening the file via NtOpenFile.

Tagged with →  
Share →

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop us a note so we can take care of it!

Visit our friends!

A few highly recommended friends...

Set your Twitter account name in your settings to use the TwitterBar Section.