Wrong timestamp on files written over cifs
We have a ZFS volume shared over CIFS, accessed by clients on windows computers.
When a user unrar a .rar file with winrar, all files will have the current
time as timestamp, not the timestamp from within the archive.
When unzipping the timestamps are correct.
Attached pcap files:
Bge0.rar.pcap is activity when unraring.
Bge0.zip.pcap is activity when unziping.
File from rar archive gets current date as timestamp. File from zip keeps original timestamp.
I used winrar to extract from both rar and zip.
I have contacted winrar about this, and they use the same "logic" for both zip and rar.
The difference is the API-calls for writing files.
Here is the info from winrar support:
If you mean WinRAR, not Unix RAR version, then it uses the standard
CreateFile call to create a file, writes data to file with WriteFile,
sets the file time with SetFileTime, closes the file with
CloseHandle, sets file attributes with SetFileAttributes.
All this API calls are typical.
Now I looked at WinRAR unzip code more carefully. Unlike unrar
code, it opens a file with fopen, writes data, closes the file with
fclose, then re-opens the file with CreateFile, sets the file time
with SetFileTime and closes it with CloseHandle. So unlike unrar
code, it does not write any data to file after CreateFile and before SetFileTime.
But it has its price, time wasted to re-open a file.
On windows servers the timestamps are correct in both cases...
Updated by Vidar Nilsen about 9 years ago
Thanks to WinRAR support, I might have more accurate information on how to reproduce this bug.
From Eugene at winrar support:
I think, they might fail to reproduce the problem based only on this
information. You provided them the quote from my first email on this
issue, where I only started to investigate it and did not really understood what causes it.
It would be more helpful for them to know that SetFileTime does not
work properly if CreateFile is called with GENERIC_READ|GENERIC_WRITE
and then some data was written to file before SetFileTime call.
And SetFileTime works properly if CreateFile was called with
GENERIC_WRITE only or no data was written to file before SetFileTime
call or FlushFileBuffers call or some delay is added before SetFileTime.
It looks like a delayed write operation modifies the file time, but
only in GENERIC_READ|GENERIC_WRITE mode.
In unzip code close/reopen works similarly to FlushFileBuffers.