#include "stdafx.h" #include #include #include #include #include #include int main(int argc, char *argv[]) { time_t modtime = time(NULL) - 24 * 60 * 60; FILE *f; if (argc < 3) { printf("please provide 2 different test files paths on a network driver, i.e. ' Y:\\afile.txt Y:\\bfile.txt'\n"); return 1; } char *boostfile = argv[1]; char *utimefile = argv[2]; // // demonstrate the problem first // printf("\ntest boost::last_write_time(f,t) to modifty last write time on %s\n", boostfile); f = fopen(boostfile,"wb"); fwrite("X",1,1,f); fclose(f); printf("%lld - original last write time\n", boost::filesystem::last_write_time(boostfile)); f = fopen(boostfile,"r+b"); fwrite("X",1,1,f); fclose(f); boost::filesystem::last_write_time(boostfile, modtime); printf("%lld - last write time after calling boost::last_write_time to modify it\n", boost::filesystem::last_write_time(boostfile)); f = fopen(boostfile,"r"); fclose(f); printf("%lld [TEST:%s] last write opening for read - Expected %lld\n", boost::filesystem::last_write_time(boostfile), boost::filesystem::last_write_time(boostfile) == modtime ? "PASS" : "FAIL", modtime); // // demonstrate the problem expected behavior // printf("\ntest utime() on %s\n", utimefile); f = fopen(utimefile,"wb"); fwrite("X",1,1,f); fclose(f); printf("%lld - original last write time\n", boost::filesystem::last_write_time(utimefile)); f = fopen(utimefile,"r+b"); fwrite("X",1,1,f); fclose(f); struct utimbuf u; u.actime = 0; u.modtime = modtime; utime(utimefile, &u); printf("%lld - last write time after calling utime() to modify it\n", boost::filesystem::last_write_time(utimefile)); f = fopen(utimefile,"r"); fclose(f); printf("%lld [TEST:%s] last write opening for read - Expected %lld\n", boost::filesystem::last_write_time(utimefile), boost::filesystem::last_write_time(utimefile) == modtime ? "PASS" : "FAIL", modtime); // // demonstrate perhaps how to fix it using FILE_GENERIC_WRITE rather than just FILE_WRITE_ATTRIBUTES // printf("\nshow 'better' windows API usage to modifty last write time on %s\n", boostfile); f = fopen(boostfile,"wb"); fwrite("X",1,1,f); fclose(f); printf("%lld original last write time\n", boost::filesystem::last_write_time(boostfile)); f = fopen(boostfile,"r+b"); fwrite("X",1,1,f); fclose(f); // using boost's technique as see in http://svn.boost.org/svn/boost/trunk/libs/filesystem/v3/src/operations.cpp (in last_write_time -- variant that modifies time) // or http://svn.boost.org/svn/boost/trunk/libs/filesystem/v2/src/v2_operations.cpp (in set_file_write_time ) { HANDLE h = CreateFileA(boostfile, FILE_GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); FILETIME lwt; __int64 temp = modtime; temp *= 10000000; temp += 116444736000000000LL; lwt.dwLowDateTime = static_cast(temp); lwt.dwHighDateTime = static_cast(temp >> 32); SetFileTime(h, 0, 0, &lwt); } printf("%lld - last write time after calling native SetFileTime() with a handle with FILE_GENERIC_ACCESS\n", boost::filesystem::last_write_time(boostfile)); f = fopen(boostfile,"r"); fclose(f); printf("%lld [TEST:%s] last write opening for read - Expected %lld\n", boost::filesystem::last_write_time(boostfile), boost::filesystem::last_write_time(boostfile) == modtime ? "PASS" : "FAIL", modtime); return 0; }