How to Open a Read/Write Handle with CreateFile on a Read-Only File

252 views Asked by At

Hi I have a simple question - what are my options for opening a read/write handle with CreateFile on a read-only file? Do I have to remove the read-only attribute temporarily, open the handle, do the work, then reapply the attribute? Is there another way to do it? For my situation the program in question has administrative privileges.

Here's some code as things are now and what goes wrong:

HANDLE hTargetFile;
hTargetFile = CreateFile(QDir::toNativeSeparators(targetFileString).toStdWString().c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,NULL);

and I get CreateFile failed with error 5: Access is denied. from GetLastError().

Thanks!

1

There are 1 answers

5
Remy Lebeau On

what are my options for opening a read/write handle with CreateFile on a read-only file?

None. You can't get a write handle to a read-only file. CreateFile() will fail with ERROR_ACCESS_DENIED.

Do I have to remove the read-only attribute temporarily, open the handle, do the work, then reapply the attribute?

Yes, exactly. And of course, that creates a race condition, because as soon as you remove the read-only attribute, any other process with adequate permissions to the file could open the file for writing and block you out before you are able to open the file yourself.

Is there another way to do it?

Although APIs like ReOpenFile() and SetFileInformationByHandle() do exist, I was not able to figure out a way to use them to create a write handle to a read-only file (with or without removing the read-only attribute from the file) in way that would allow the caller to gain write access to the file while still preventing other processes from also gaining write access to the file.

I think @MartinYork said it best in his comment:

I would make a copy of the file. Create a read/write handle update the file approprirtely when finished replace the original with the new file. This prevents race conditions when you remove the read-only attribute temporarily