I am trying to use FreeNAS CIFS share with Windows (synchronizing files from Windows to FreeNAS) and hit a problem that robocopy.exe thinks that some files need to be copied again every time I run robocopy.exe (/COPY:DAT).
My favorite file management tool, Far Manager, tells me that "Change time" is different:
File times on Windows:
File times on CIFS share backed by FreeNAS (ZFS):
I am perfectly fine with the fact that "change time" is lost, and I'd be happy to reset change time on the Windows drive, but I can't find how I can do that programmatically.
Python's os.stat(filename) returns st_atime, st_mtime and st_ctime, and, I've tested, this tuple has equal values between Windows and FreeNAS. Presumably "change time" isn't there.
Windows API also gives only 3 numbers (creation, last access and last write) but not "change time": http://msdn.microsoft.com/en-us/library/windows/desktop/ms724320(v=vs.85).aspx
Apparently both robocopy.exe and Far Manager somehow get 4 values from the system. I'd really like to avoid disassembling them, hoping to get an answer here. How do I get and set "change time"?
Any solution will do (Python, C++, WinAPI, external command line tools that can manipulate that, etc).
OK, I seem to have figured it out, thanks to cocarin for pointing to Far sources. Far uses NtQueryInformationFile to get times and NtSetInformationFile to set them, and FILE_BASIC_INFORMATION structure contains all 4 times, including change time.
QueryInformationFile docs: http://msdn.microsoft.com/en-us/library/windows/hardware/ff567052(v=vs.85).aspx (ZwQueryInformationFile)
SetInformationFile docs: http://msdn.microsoft.com/en-us/library/windows/hardware/ff567096(v=vs.85).aspx (ZwSetInformationFile)
FILE_BASIC_INFORMATION docs: http://msdn.microsoft.com/en-us/library/windows/hardware/ff545762(v=vs.85).aspx
typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime; // <--- win!
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
Not sure if there are any nice wrappers for Python but this is good enough, I can write my own wrapper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With