bdwain
bdwain

Reputation: 1745

lockfileex doesn't stop create_always from erasing the file

in one process, i called createfile with GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, and FILE_ATTRIBUTE_NORMAL as the params. then i called LockFileEx on the whole file. i acquired an exclusive lock, and locked from range 0 to UINT_MAX.

after that, in another process, i called ::CreateFileW(path.c_str(), perms, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

and it erased the contents of the file. shouldn't it not be able to do that while my other prcoess has the file locked (exclusively)?

i want other processes to be able to get handles to the file (which is why i used the file_share flags), but i assumed they couldnt change the file at all while another process locked it, and so i was doing something like

createfile lockfileex

and having it block on lockfileex until the other file releases the lock. is it just me or is msft's behavior here wrong?

Upvotes: 2

Views: 597

Answers (1)

Brent M. Spell
Brent M. Spell

Reputation: 2257

It is debatable whether Windows should honor file locks when you attempt to open a file with CREATE_ALWAYS, but it appears from your notes that it does not. The best way to prevent other processes from writing to a file that you have open is not to specify FILE_SHARE_WRITE in your exclusive process.

However, this won't give you the waiting behavior that you would get from the file lock implementation without polling. There is no way to open a file with exclusive access and have any other files that are attempting to open it wait until the process with exclusive access relinquishes that access.

If you have access to the source of all of the processes involved, then you could just have the processes that are attempting to truncate the file first call LockFileEx on a region, and then call SetFileSize after acquiring the lock.

As a side note, only locking the region from 0 bytes to UINT_MAX won't provide mutual exclusion if, say, a process opens the file and attempts to write to the location at UINT_MAX + 1 (just past the 4GB point).

Upvotes: 3

Related Questions