Wow. Very nice. Your tests make painfully clear that ReplaceFile() is not at all doing what we thought it would..
2) The results are unlikely to be applicable to a BSOD or power failure situation, where OS-level caching and drive-level caching are involved, eg. some drives tell the OS that the data has been committed to disk when it is actually still in the drive cache.
My guess is still that atomic overwriting renames (ie MoveFileEx()) will already help a lot, even if this still won't be safe in 100% of the BSOD cases.
At least on *NIX, the rule is to call fsync() on the new file before rename()'ing it, in order to prevent that the file ends up being renamed before its data have made it to disk (thus resulting in an empty/corrupted file after an untimely system crash). The Windows equivalent of fsync() appears to be FlushFileBuffers(). I don't know enough about how NTFS journaling works to say whether it helps to call FlushFileBuffers() before the CloseHandle() + MoveFileEx(). In any case, FlushFileBuffers() is probably the last and only thing you can add to improve the BSOD situation further from the application side. If it doesn't have too much of a performance penalty, it might be worth adding just in case.Edit:
just to make sure, FlushFileBuffers() would always be more of an improvement than MOVEFILE_WRITE_THROUGH, as the concern here is about the consistency of the update, not its durability. That is: it is important that mirc.ini is always in a good shape on disk; it is not so important when
the whole mirc.ini update actually makes it to disk.
3) Mode2 showed almost no file loss.
I'm surprised and slightly concerned that with MoveFileEx() there was still one loss case at all though. With only the application crashing, there should be no way that the file gets lost. Do you have any more details about what happened there? Was the file actually lost, empty, corrupted..?