From: Vadim Zeitlin Date: Wed, 27 Mar 2002 23:17:41 +0000 (+0000) Subject: wxFileName::Get/SetTimes() finally seem to work under Windows X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/6dbb903bb9410e2a2a977ad349ba7b4b3b12ac78?ds=sidebyside wxFileName::Get/SetTimes() finally seem to work under Windows git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14827 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/latex/wx/filename.tex b/docs/latex/wx/filename.tex index 343fb7f1b3..2e2b4ce538 100644 --- a/docs/latex/wx/filename.tex +++ b/docs/latex/wx/filename.tex @@ -140,7 +140,10 @@ following functions: \membersection{Operations} These methods allow to work with the file creation, access and modification -times: +times. Note that not all filesystems under all platforms implement these times +in the same way. For example, the access time under Windows has a resolution of +one day (so it is really the access date and not time). The access time may be +updated when the file is executed or not depending on the platform. \helpref{GetModificationTime}{wxfilenamegetmodificationtime}\\ \helpref{GetTimes}{wxfilenamegettimes}\\ @@ -400,9 +403,9 @@ Return the short form of the path (returns identity on non-Windows platforms) \membersection{wxFileName::GetTimes}\label{wxfilenamegettimes} -\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtChange}} +\constfunc{bool}{GetTimes}{\param{wxDateTime* }{dtAccess}, \param{wxDateTime* }{dtMod}, \param{wxDateTime* }{dtCreate}} -return the last access, last modification and last change times +return the last access, last modification and creation times (any of the pointers may be NULL) @@ -584,7 +587,7 @@ full name is the file name + extension (but without the path) \membersection{wxFileName::SetTimes}\label{wxfilenamesettimes} -\func{bool}{SetTimes}{\param{const wxDateTime* }{dtCreate}, \param{const wxDateTime* }{dtAccess}, \param{const wxDateTime* }{dtMod}} +\func{bool}{SetTimes}{\param{const wxDateTime* }{dtAccess}, \param{const wxDateTime* }{dtMod}, \param{const wxDateTime* }{dtCreate}} set the file creation and last access/mod times (any of the pointers may be NULL) diff --git a/include/wx/filename.h b/include/wx/filename.h index ceb0fc820e..928868fd3a 100644 --- a/include/wx/filename.h +++ b/include/wx/filename.h @@ -173,20 +173,20 @@ public: // time functions - // set the file creation and last access/mod times + // set the file last access/mod and creation times // (any of the pointers may be NULL) - bool SetTimes(const wxDateTime *dtCreate, - const wxDateTime *dtAccess, - const wxDateTime *dtMod); + bool SetTimes(const wxDateTime *dtAccess, + const wxDateTime *dtMod, + const wxDateTime *dtCreate); // set the access and modification times to the current moment bool Touch(); - // return the last access, last modification and last change times + // return the last access, last modification and create times // (any of the pointers may be NULL) bool GetTimes(wxDateTime *dtAccess, wxDateTime *dtMod, - wxDateTime *dtChange) const; + wxDateTime *dtCreate) const; // convenience wrapper: get just the last mod time of the file wxDateTime GetModificationTime() const diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 47c1c3f8ab..fba92070c9 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -90,7 +90,7 @@ #undef TEST_ALL static const bool TEST_ALL = TRUE; #else - #define TEST_WCHAR + #define TEST_FILETIME static const bool TEST_ALL = FALSE; #endif @@ -982,8 +982,8 @@ static void TestFileGetTimes() { wxFileName fn(_T("testdata.fc")); - wxDateTime dtAccess, dtMod, dtChange; - if ( !fn.GetTimes(&dtAccess, &dtMod, &dtChange) ) + wxDateTime dtAccess, dtMod, dtCreate; + if ( !fn.GetTimes(&dtAccess, &dtMod, &dtCreate) ) { wxPrintf(_T("ERROR: GetTimes() failed.\n")); } @@ -992,9 +992,9 @@ static void TestFileGetTimes() static const wxChar *fmt = _T("%Y-%b-%d %H:%M:%S"); wxPrintf(_T("File times for '%s':\n"), fn.GetFullPath().c_str()); - wxPrintf(_T("Access: \t%s\n"), dtAccess.Format(fmt).c_str()); - wxPrintf(_T("Mod/creation:\t%s\n"), dtMod.Format(fmt).c_str()); - wxPrintf(_T("Change: \t%s\n"), dtChange.Format(fmt).c_str()); + wxPrintf(_T("Creation: \t%s\n"), dtCreate.Format(fmt).c_str()); + wxPrintf(_T("Last read: \t%s\n"), dtAccess.Format(fmt).c_str()); + wxPrintf(_T("Last write: \t%s\n"), dtMod.Format(fmt).c_str()); } } diff --git a/src/common/filename.cpp b/src/common/filename.cpp index 4f126db178..439490514f 100644 --- a/src/common/filename.cpp +++ b/src/common/filename.cpp @@ -135,23 +135,31 @@ class wxFileHandle { public: - wxFileHandle(const wxString& filename) + enum OpenMode + { + Read, + Write + }; + + wxFileHandle(const wxString& filename, OpenMode mode) { m_hFile = ::CreateFile ( - filename, // name - GENERIC_READ, // access mask - 0, // no sharing - NULL, // no secutity attr - OPEN_EXISTING, // creation disposition - 0, // no flags - NULL // no template file + filename, // name + mode == Read ? GENERIC_READ // access mask + : GENERIC_WRITE, + 0, // no sharing + NULL, // no secutity attr + OPEN_EXISTING, // creation disposition + 0, // no flags + NULL // no template file ); if ( m_hFile == INVALID_HANDLE_VALUE ) { - wxLogSysError(_("Failed to open '%s' for reading"), - filename.c_str()); + wxLogSysError(_("Failed to open '%s' for %s"), + filename.c_str(), + mode == Read ? _("reading") : _("writing")); } } @@ -187,32 +195,45 @@ private: // convert between wxDateTime and FILETIME which is a 64-bit value representing // the number of 100-nanosecond intervals since January 1, 1601. -// the number of milliseconds between the Unix Epoch (January 1, 1970) and the -// FILETIME reference point (January 1, 1601) -static const wxLongLong FILETIME_EPOCH_OFFSET = wxLongLong(0xa97, 0x30b66800); - static void ConvertFileTimeToWx(wxDateTime *dt, const FILETIME &ft) { - wxLongLong ll(ft.dwHighDateTime, ft.dwLowDateTime); - - // convert 100ns to ms - ll /= 10000; + FILETIME ftLocal; + if ( !::FileTimeToLocalFileTime(&ft, &ftLocal) ) + { + wxLogLastError(_T("FileTimeToLocalFileTime")); + } - // move it to our Epoch - ll -= FILETIME_EPOCH_OFFSET; + SYSTEMTIME st; + if ( !::FileTimeToSystemTime(&ftLocal, &st) ) + { + wxLogLastError(_T("FileTimeToSystemTime")); + } - *dt = wxDateTime(ll); + dt->Set(st.wDay, wxDateTime::Month(st.wMonth - 1), st.wYear, + st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); } static void ConvertWxToFileTime(FILETIME *ft, const wxDateTime& dt) { - // do the reverse of ConvertFileTimeToWx() - wxLongLong ll = dt.GetValue(); - ll += FILETIME_EPOCH_OFFSET; - ll *= 10000; + SYSTEMTIME st; + st.wDay = dt.GetDay(); + st.wMonth = dt.GetMonth() + 1; + st.wYear = dt.GetYear(); + st.wHour = dt.GetHour(); + st.wMinute = dt.GetMinute(); + st.wSecond = dt.GetSecond(); + st.wMilliseconds = dt.GetMillisecond(); + + FILETIME ftLocal; + if ( !::SystemTimeToFileTime(&st, &ftLocal) ) + { + wxLogLastError(_T("SystemTimeToFileTime")); + } - ft->dwHighDateTime = ll.GetHi(); - ft->dwLowDateTime = ll.GetLo(); + if ( !::LocalFileTimeToFileTime(&ftLocal, ft) ) + { + wxLogLastError(_T("LocalFileTimeToFileTime")); + } } #endif // __WIN32__ @@ -1561,9 +1582,9 @@ void wxFileName::SplitPath(const wxString& fullpath, // time functions // ---------------------------------------------------------------------------- -bool wxFileName::SetTimes(const wxDateTime *dtCreate, - const wxDateTime *dtAccess, - const wxDateTime *dtMod) +bool wxFileName::SetTimes(const wxDateTime *dtAccess, + const wxDateTime *dtMod, + const wxDateTime *dtCreate) { #if defined(__UNIX_LIKE__) || (defined(__DOS__) && defined(__WATCOMC__)) if ( !dtAccess && !dtMod ) @@ -1582,7 +1603,7 @@ bool wxFileName::SetTimes(const wxDateTime *dtCreate, return TRUE; } #elif defined(__WIN32__) - wxFileHandle fh(GetFullPath()); + wxFileHandle fh(GetFullPath(), wxFileHandle::Write); if ( fh.IsOk() ) { FILETIME ftAccess, ftCreate, ftWrite; @@ -1626,13 +1647,13 @@ bool wxFileName::Touch() #else // other platform wxDateTime dtNow = wxDateTime::Now(); - return SetTimes(NULL /* don't change create time */, &dtNow, &dtNow); + return SetTimes(&dtNow, &dtNow, NULL /* don't change create time */); #endif // platforms } bool wxFileName::GetTimes(wxDateTime *dtAccess, wxDateTime *dtMod, - wxDateTime *dtChange) const + wxDateTime *dtCreate) const { #if defined(__UNIX_LIKE__) || defined(__WXMAC__) || (defined(__DOS__) && defined(__WATCOMC__)) wxStructStat stBuf; @@ -1642,13 +1663,13 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess, dtAccess->Set(stBuf.st_atime); if ( dtMod ) dtMod->Set(stBuf.st_mtime); - if ( dtChange ) - dtChange->Set(stBuf.st_ctime); + if ( dtCreate ) + dtCreate->Set(stBuf.st_ctime); return TRUE; } #elif defined(__WIN32__) - wxFileHandle fh(GetFullPath()); + wxFileHandle fh(GetFullPath(), wxFileHandle::Read); if ( fh.IsOk() ) { FILETIME ftAccess, ftCreate, ftWrite; @@ -1656,14 +1677,14 @@ bool wxFileName::GetTimes(wxDateTime *dtAccess, if ( ::GetFileTime(fh, dtMod ? &ftCreate : NULL, dtAccess ? &ftAccess : NULL, - dtChange ? &ftWrite : NULL) ) + dtCreate ? &ftWrite : NULL) ) { if ( dtMod ) ConvertFileTimeToWx(dtMod, ftCreate); if ( dtAccess ) ConvertFileTimeToWx(dtAccess, ftAccess); - if ( dtChange ) - ConvertFileTimeToWx(dtChange, ftWrite); + if ( dtCreate ) + ConvertFileTimeToWx(dtCreate, ftWrite); return TRUE; }