summaryrefslogtreecommitdiff
path: root/shared/file_traverser.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:11:56 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:11:56 +0200
commit98ecf620f7de377dc8ae9ad7fbd1e3b24477e138 (patch)
treefaadc6d8822c20cd3bc6f50b2a98e6c580585949 /shared/file_traverser.cpp
parent3.16 (diff)
downloadFreeFileSync-98ecf620f7de377dc8ae9ad7fbd1e3b24477e138.tar.gz
FreeFileSync-98ecf620f7de377dc8ae9ad7fbd1e3b24477e138.tar.bz2
FreeFileSync-98ecf620f7de377dc8ae9ad7fbd1e3b24477e138.zip
3.17
Diffstat (limited to 'shared/file_traverser.cpp')
-rw-r--r--shared/file_traverser.cpp91
1 files changed, 38 insertions, 53 deletions
diff --git a/shared/file_traverser.cpp b/shared/file_traverser.cpp
index 2af0f4af..90a5bd79 100644
--- a/shared/file_traverser.cpp
+++ b/shared/file_traverser.cpp
@@ -7,7 +7,7 @@
#include "file_traverser.h"
#include <limits>
#include "system_constants.h"
-#include "system_func.h"
+#include "last_error.h"
#include "string_conv.h"
#include "assert_static.h"
#include "symlink_target.h"
@@ -26,36 +26,20 @@
#ifdef FFS_WIN
inline
-wxLongLong getWin32TimeInformation(const FILETIME& lastWriteTime)
+zen::Int64 filetimeToTimeT(const FILETIME& lastWriteTime)
{
//convert UTC FILETIME to ANSI C format (number of seconds since Jan. 1st 1970 UTC)
- wxLongLong writeTimeLong(lastWriteTime.dwHighDateTime, lastWriteTime.dwLowDateTime);
- writeTimeLong /= 10000000; //reduce precision to 1 second (FILETIME has unit 10^-7 s)
- writeTimeLong -= wxLongLong(2, 3054539008UL); //timeshift between ansi C time and FILETIME in seconds == 11644473600s
-
- assert(lastWriteTime.dwHighDateTime <= static_cast<unsigned long>(std::numeric_limits<long>::max()));
- assert_static(sizeof(DWORD) == sizeof(long));
- assert_static(sizeof(long) == 4);
+ zen::Int64 writeTimeLong = zen::to<zen::Int64>(zen::UInt64(lastWriteTime.dwLowDateTime, lastWriteTime.dwHighDateTime) / 10000000U); //reduce precision to 1 second (FILETIME has unit 10^-7 s)
+ writeTimeLong -= zen::Int64(3054539008UL, 2); //timeshift between ansi C time and FILETIME in seconds == 11644473600s
return writeTimeLong;
}
inline
-void setWin32FileInformation(const FILETIME& lastWriteTime,
- const DWORD fileSizeHigh,
- const DWORD fileSizeLow,
- ffs3::TraverseCallback::FileInfo& output)
-{
- output.lastWriteTimeRaw = getWin32TimeInformation(lastWriteTime);
- output.fileSize = wxULongLong(fileSizeHigh, fileSizeLow);
-}
-
-
-inline
-bool setWin32FileInformationFromSymlink(const Zstring& linkName, ffs3::TraverseCallback::FileInfo& output)
+bool setWin32FileInformationFromSymlink(const Zstring& linkName, zen::TraverseCallback::FileInfo& output)
{
//open handle to target of symbolic link
- HANDLE hFile = ::CreateFile(ffs3::applyLongPathPrefix(linkName).c_str(),
+ HANDLE hFile = ::CreateFile(zen::applyLongPathPrefix(linkName).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -68,12 +52,13 @@ bool setWin32FileInformationFromSymlink(const Zstring& linkName, ffs3::TraverseC
Loki::ScopeGuard dummy = Loki::MakeGuard(::CloseHandle, hFile);
(void)dummy; //silence warning "unused variable"
- BY_HANDLE_FILE_INFORMATION fileInfoByHandle;
+ BY_HANDLE_FILE_INFORMATION fileInfoByHandle = {};
if (!::GetFileInformationByHandle(hFile, &fileInfoByHandle))
return false;
//write output
- setWin32FileInformation(fileInfoByHandle.ftLastWriteTime, fileInfoByHandle.nFileSizeHigh, fileInfoByHandle.nFileSizeLow, output);
+ output.lastWriteTimeRaw = filetimeToTimeT(fileInfoByHandle.ftLastWriteTime);
+ output.fileSize = zen::UInt64(fileInfoByHandle.nFileSizeLow, fileInfoByHandle.nFileSizeHigh);
return true;
}
#endif
@@ -82,7 +67,7 @@ bool setWin32FileInformationFromSymlink(const Zstring& linkName, ffs3::TraverseC
class DirTraverser
{
public:
- DirTraverser(const Zstring& baseDirectory, bool followSymlinks, ffs3::TraverseCallback& sink, ffs3::DstHackCallback* dstCallback)
+ DirTraverser(const Zstring& baseDirectory, bool followSymlinks, zen::TraverseCallback& sink, zen::DstHackCallback* dstCallback)
#ifdef FFS_WIN
: isFatFileSystem(dst::isFatDrive(baseDirectory))
#endif
@@ -113,9 +98,9 @@ public:
private:
template <bool followSymlinks>
- void traverse(const Zstring& directory, ffs3::TraverseCallback& sink, int level)
+ void traverse(const Zstring& directory, zen::TraverseCallback& sink, int level)
{
- using namespace ffs3;
+ using namespace zen;
if (level == 100) //catch endless recursion
{
@@ -129,9 +114,9 @@ private:
directory :
directory + common::FILE_NAME_SEPARATOR;
- WIN32_FIND_DATA fileMetaData = {};
+ WIN32_FIND_DATA fileInfo = {};
HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(directoryFormatted + Zchar('*')).c_str(), //__in LPCTSTR lpFileName
- &fileMetaData); //__out LPWIN32_FIND_DATA lpFindFileData
+ &fileInfo); //__out LPWIN32_FIND_DATA lpFindFileData
//no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH
if (searchHandle == INVALID_HANDLE_VALUE)
@@ -141,10 +126,9 @@ private:
return;
//else: we have a problem... report it:
- const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") + wxT("\n\n") +
- ffs3::getLastErrorFormatted(lastError);
+ const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
- sink.onError(errorMessage);
+ sink.onError(errorMessage + wxT("\n\n") +zen::getLastErrorFormatted(lastError));
return;
}
@@ -154,7 +138,7 @@ private:
do
{
//don't return "." and ".."
- const Zchar* const shortName = fileMetaData.cFileName;
+ const Zchar* const shortName = fileInfo.cFileName;
if ( shortName[0] == Zstr('.') &&
((shortName[1] == Zstr('.') && shortName[2] == Zstr('\0')) ||
shortName[1] == Zstr('\0')))
@@ -162,7 +146,7 @@ private:
const Zstring& fullName = directoryFormatted + shortName;
- const bool isSymbolicLink = (fileMetaData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
+ const bool isSymbolicLink = (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
if (isSymbolicLink && !followSymlinks) //evaluate symlink directly
{
@@ -179,11 +163,11 @@ private:
#endif
}
- details.lastWriteTimeRaw = getWin32TimeInformation(fileMetaData.ftLastWriteTime);
- details.dirLink = (fileMetaData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; //directory symlinks have this flag on Windows
+ details.lastWriteTimeRaw = filetimeToTimeT(fileInfo.ftLastWriteTime);
+ details.dirLink = (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; //directory symlinks have this flag on Windows
sink.onSymlink(shortName, fullName, details);
}
- else if (fileMetaData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //a directory... or symlink that needs to be followed (for directory symlinks this flag is set too!)
+ else if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //a directory... or symlink that needs to be followed (for directory symlinks this flag is set too!)
{
const TraverseCallback::ReturnValDir rv = sink.onDir(shortName, fullName);
switch (rv.returnCode)
@@ -206,7 +190,7 @@ private:
{
//broken symlink...
details.lastWriteTimeRaw = 0; //we are not interested in the modification time of the link
- details.fileSize = 0;
+ details.fileSize = 0U;
}
}
else
@@ -214,29 +198,30 @@ private:
//####################################### DST hack ###########################################
if (isFatFileSystem)
{
- const dst::RawTime rawTime(fileMetaData.ftCreationTime, fileMetaData.ftLastWriteTime);
+ const dst::RawTime rawTime(fileInfo.ftCreationTime, fileInfo.ftLastWriteTime);
if (dst::fatHasUtcEncoded(rawTime)) //throw (std::runtime_error)
- fileMetaData.ftLastWriteTime = dst::fatDecodeUtcTime(rawTime); //return real UTC time; throw (std::runtime_error)
+ fileInfo.ftLastWriteTime = dst::fatDecodeUtcTime(rawTime); //return real UTC time; throw (std::runtime_error)
else
- markForDstHack.push_back(std::make_pair(fullName, fileMetaData.ftLastWriteTime));
+ markForDstHack.push_back(std::make_pair(fullName, fileInfo.ftLastWriteTime));
}
//####################################### DST hack ###########################################
- setWin32FileInformation(fileMetaData.ftLastWriteTime, fileMetaData.nFileSizeHigh, fileMetaData.nFileSizeLow, details);
+ details.lastWriteTimeRaw = filetimeToTimeT(fileInfo.ftLastWriteTime);
+ details.fileSize = zen::UInt64(fileInfo.nFileSizeLow, fileInfo.nFileSizeHigh);
}
sink.onFile(shortName, fullName, details);
}
}
while (::FindNextFile(searchHandle, // handle to search
- &fileMetaData)); // pointer to structure for data on found file
+ &fileInfo)); // pointer to structure for data on found file
const DWORD lastError = ::GetLastError();
if (lastError != ERROR_NO_MORE_FILES) //this is fine
{
//else we have a problem... report it:
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- sink.onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted(lastError));
+ sink.onError(errorMessage + wxT("\n\n") + zen::getLastErrorFormatted(lastError));
}
#elif defined FFS_LINUX
@@ -244,7 +229,7 @@ private:
if (dirObj == NULL)
{
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- sink.onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ sink.onError(errorMessage + wxT("\n\n") + zen::getLastErrorFormatted());
return;
}
@@ -262,7 +247,7 @@ private:
//else: we have a problem... report it:
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- sink.onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ sink.onError(errorMessage + wxT("\n\n") + zen::getLastErrorFormatted());
return;
}
@@ -281,7 +266,7 @@ private:
if (::lstat(fullName.c_str(), &fileInfo) != 0) //lstat() does not resolve symlinks
{
const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(fullName) + wxT("\"");
- sink.onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ sink.onError(errorMessage + wxT("\n\n") + zen::getLastErrorFormatted());
continue;
}
@@ -296,7 +281,7 @@ private:
//a broken symbolic link
TraverseCallback::FileInfo details;
details.lastWriteTimeRaw = 0; //we are not interested in the modifiation time of the link
- details.fileSize = 0;
+ details.fileSize = 0U;
sink.onFile(shortName, fullName, details); //report broken symlink as file!
continue;
}
@@ -341,7 +326,7 @@ private:
{
TraverseCallback::FileInfo details;
details.lastWriteTimeRaw = fileInfo.st_mtime; //UTC time(ANSI C format); unit: 1 second
- details.fileSize = fileInfo.st_size;
+ details.fileSize = zen::UInt64(fileInfo.st_size);
sink.onFile(shortName, fullName, details);
}
@@ -352,7 +337,7 @@ private:
#ifdef FFS_WIN
//####################################### DST hack ###########################################
- void applyDstHack(ffs3::DstHackCallback& dstCallback)
+ void applyDstHack(zen::DstHackCallback& dstCallback)
{
int failedAttempts = 0;
int filesToValidate = 50; //don't let data verification become a performance issue
@@ -366,7 +351,7 @@ private:
const dst::RawTime encodedTime = dst::fatEncodeUtcTime(i->second); //throw (std::runtime_error)
{
- HANDLE hTarget = ::CreateFile(ffs3::applyLongPathPrefix(i->first).c_str(),
+ HANDLE hTarget = ::CreateFile(zen::applyLongPathPrefix(i->first).c_str(),
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -400,7 +385,7 @@ private:
//dst hack: verify data written; attention: this check may fail for "sync.ffs_lock"
WIN32_FILE_ATTRIBUTE_DATA debugeAttr = {};
- ::GetFileAttributesEx(ffs3::applyLongPathPrefix(i->first).c_str(), //__in LPCTSTR lpFileName,
+ ::GetFileAttributesEx(zen::applyLongPathPrefix(i->first).c_str(), //__in LPCTSTR lpFileName,
GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId,
&debugeAttr); //__out LPVOID lpFileInformation
@@ -423,7 +408,7 @@ private:
};
-void ffs3::traverseFolder(const Zstring& directory, bool followSymlinks, TraverseCallback& sink, DstHackCallback* dstCallback)
+void zen::traverseFolder(const Zstring& directory, bool followSymlinks, TraverseCallback& sink, DstHackCallback* dstCallback)
{
DirTraverser(directory, followSymlinks, sink, dstCallback);
}
bgstack15