NTFS hard links (& ADS... and the Microsoft mess)
Posted: Mon Dec 05, 2011 5:33 am
Many programs destroy hard links and file comments when writing changes to a file.
The ExamDiff editor too.
Text editors written with microsoft's MFC most probably save documents using the little known CMirrorFile class which, instead of saving straight to the target filename, it creates a temporary file, writes in it, deletes the original and then renames the temporary to the actual filename.
As you can imagine, any stream or hard link information in the original file is lost.
WordPad and visual studio 6 are two known culprits.
Hard links are ok if you use straight CreateFile calls without mirror files, but that ruines ADS when overwriting existing files with comments.
The problem is with the dwCreationDisposition argument used with CreateFile API.
You can use for convenience CREATE_ALWAYS that doesn't care whether the file being written exists or not, but nukes the old file in case it does exist, including any parallel streams - thus destroying the summary information stream.
The message is: do not use CREATE_ALWAYS!
A little extra effort is required to examine if the file we are about to write exists or not. If it does, then use TRUNCATE_EXISTING which will preserve ADS. If it doesn't, then pass CREATE_NEW as the disposition parameter.
The ExamDiff editor too.
Text editors written with microsoft's MFC most probably save documents using the little known CMirrorFile class which, instead of saving straight to the target filename, it creates a temporary file, writes in it, deletes the original and then renames the temporary to the actual filename.
As you can imagine, any stream or hard link information in the original file is lost.
WordPad and visual studio 6 are two known culprits.
Hard links are ok if you use straight CreateFile calls without mirror files, but that ruines ADS when overwriting existing files with comments.
The problem is with the dwCreationDisposition argument used with CreateFile API.
You can use for convenience CREATE_ALWAYS that doesn't care whether the file being written exists or not, but nukes the old file in case it does exist, including any parallel streams - thus destroying the summary information stream.
The message is: do not use CREATE_ALWAYS!
A little extra effort is required to examine if the file we are about to write exists or not. If it does, then use TRUNCATE_EXISTING which will preserve ADS. If it doesn't, then pass CREATE_NEW as the disposition parameter.