Why doesn't returning error in the DeleteFile event handler prevent file deletion?
This is the correct behavior. Windows can delete a file or directory in two ways:
The first way:
- The file is opened.
- The "delete on close" flag is set for the file (see MSDN's FileDispositionInformation article for details). During this system request, the CanFileBeDeleted event fires.
- The file is closed. This causes CBFS Connect to fire the DeleteFile event.
Unfortunately, the system doesn't check the status of the delete file request; it's expected to always finish successfully. That's why reporting errors from the DeleteFile event doesn't work. But the deletion can be prevented if the CanFileBeDeleted event handler denies it.
The second way:
- The file is opened with the "delete on close" flag (refer to the description of the FILE_FLAG_DELETE_ON_CLOSE flag in the Win32 CreateFile API documentation).
- The file is closed. CBFS Connect fires the CanFileBeDeleted event; if the event handler allows the deletion of the file, the DeleteFile event fires (otherwise, the CloseFile event fires).
To protect the file from being deleted in this scenario, you need to check for the FILE_FLAG_DELETE_ON_CLOSE flag in the OpenFile event handler. If it's present, then returning the ERROR_ACCESS_DENIED (5) error causes the file not to be opened (and therefore not to be deleted on close).
Unfortunately, such deletion protection can cause some applications or processes to work incorrectly. Consider a process that uses some temporary file(s). The process opens the file, reads/writes it, and closes the handle many times. Finally, the process decides to open the file with the FILE_FLAG_DELETE_ON_CLOSE flag and perform more read/write operations before deleting the file. Preventing the file from opening in this last situation can cause the process to behave incorrectly.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at firstname.lastname@example.org.