Allowing renaming but not deleting for files on Windows
I’ve had a client ask if it’s possible to rename his server log file whilst the server is running but not allow deletion. This is harder than you’d expect to achieve. The established view of “the internet” is that NTFS doesn’t support permissions to allow file renaming and still prevent file deletion. This is true. If you want to allow renaming you need to create or open the file with
FILE_SHARE_DELETE access and this allows rename AND delete. The reason for this is that a rename is actually a process of creating a copy of the file with a new name and then deleting the old file. I pointed this out to my client and he immediately responded with “I can rename a running exe but am prevented from deleting it.”. This, of course, is true. Executable files can be renamed and not deleted if they are currently running.
The fact that executables can work this way gave me the hint I needed. I figured it’s likely the fact that the file is mapped into memory that prevents the deletion…
Adding some code that uses
CreateFileMapping() to create a file mapping object from the log file’s file handle, and then holding the file mapping open whilst we’re using the log, gives the results that my client wants. A log file that can be renamed but not deleted. Note that you don’t actually have to map the file mapping into memory, just hold the handle open.
Note that the file in question needs to contain at least one byte to be able to create the file mapping but that’s easy to work around for us.