Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get *change* file time in Windows?

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: On Windows

File times on CIFS share backed by FreeNAS (ZFS): 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).

like image 987
morfizm Avatar asked Dec 17 '14 20:12

morfizm


Video Answer


1 Answers

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.

like image 65
morfizm Avatar answered Oct 17 '22 07:10

morfizm