summaryrefslogtreecommitdiff
path: root/zen/file_traverser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zen/file_traverser.cpp')
-rw-r--r--zen/file_traverser.cpp117
1 files changed, 18 insertions, 99 deletions
diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp
index d8f2d0cf..7b423faa 100644
--- a/zen/file_traverser.cpp
+++ b/zen/file_traverser.cpp
@@ -6,15 +6,13 @@
#include "file_traverser.h"
#include "sys_error.h"
-#include "assert_static.h"
#include "symlink_target.h"
#include "int64.h"
#ifdef ZEN_WIN
#include "win_ver.h"
#include "long_path_prefix.h"
-#include "dst_hack.h"
-#include "file_handling.h" //remove this huge dependency when getting rid of DST hack!! until then we need "setFileTime"
+#include "file_access.h"
#include "dll.h"
#include "FindFilePlus/find_file_plus.h"
@@ -30,7 +28,7 @@
using namespace zen;
-
+
namespace
{
//implement "retry" in a generic way:
@@ -179,8 +177,8 @@ struct Win32Traverser
{
struct DirHandle
{
- DirHandle(HANDLE hnd, const WIN32_FIND_DATA& d) : searchHandle(hnd), haveData(true), data(d) {}
- explicit DirHandle(HANDLE hnd) : searchHandle(hnd), haveData(false) {}
+ DirHandle(HANDLE hnd, const WIN32_FIND_DATA& d) : searchHandle(hnd), haveData(true), data(d) {}
+ explicit DirHandle(HANDLE hnd) : searchHandle(hnd), haveData(false) {}
HANDLE searchHandle;
bool haveData;
@@ -193,7 +191,7 @@ struct Win32Traverser
{
const Zstring& dirpathPf = appendSeparator(dirpath);
- WIN32_FIND_DATA fileData = {};
+ WIN32_FIND_DATA fileData = {};
HANDLE hnd = ::FindFirstFile(applyLongPathPrefix(dirpathPf + L'*').c_str(), &fileData);
//no noticable performance difference compared to FindFirstFileEx with FindExInfoBasic, FIND_FIRST_EX_CASE_SENSITIVE and/or FIND_FIRST_EX_LARGE_FETCH
if (hnd == INVALID_HANDLE_VALUE)
@@ -208,7 +206,7 @@ struct Win32Traverser
}
throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirpath)), L"FindFirstFile", lastError);
}
- return DirHandle(hnd, fileData);
+ return DirHandle(hnd, fileData);
}
static void destroy(const DirHandle& hnd) { ::FindClose(hnd.searchHandle); } //throw()
@@ -271,11 +269,11 @@ struct FilePlusTraverser
static DirHandle create(const Zstring& dirpath) //throw FileError
{
- const findplus::FindHandle hnd = ::openDir(applyLongPathPrefix(dirpath).c_str());
+ const findplus::FindHandle hnd = ::openDir(applyLongPathPrefix(dirpath).c_str());
if (!hnd)
- throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirpath)), L"openDir", getLastError());
+ throwFileError(replaceCpy(_("Cannot open directory %x."), L"%x", fmtFileName(dirpath)), L"openDir", getLastError());
- return DirHandle(hnd);
+ return DirHandle(hnd);
}
static void destroy(DirHandle hnd) { ::closeDir(hnd.searchHandle); } //throw()
@@ -325,13 +323,13 @@ struct FilePlusTraverser
class DirTraverser
{
public:
- static void execute(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback)
+ static void execute(const Zstring& baseDirectory, TraverseCallback& sink)
{
- DirTraverser(baseDirectory, sink, dstCallback);
+ DirTraverser(baseDirectory, sink);
}
private:
- DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback);
+ DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink);
DirTraverser (const DirTraverser&) = delete;
DirTraverser& operator=(const DirTraverser&) = delete;
@@ -340,58 +338,6 @@ private:
template <class Trav>
void traverseWithException(const Zstring& dirpath, TraverseCallback& sink, DWORD volumeSerial /*may be 0!*/); //throw FileError, NeedFallbackToWin32Traverser
-
- //####################################### DST hack ###########################################
- void applyDstHack(zen::DstHackCallback& dstCallback)
- {
- int failedAttempts = 0;
- int filesToValidate = 50; //don't let data verification become a performance issue
-
- for (auto it = markForDstHack.begin(); it != markForDstHack.end(); ++it)
- {
- if (failedAttempts >= 10) //some cloud storages don't support changing creation/modification times => don't waste (a lot of) time trying to
- return;
-
- dstCallback.requestUiRefresh(it->first);
-
- try
- {
- //set modification time including DST hack: this function is too clever to not introduce this dependency
- setFileTime(it->first, it->second, ProcSymlink::FOLLOW); //throw FileError
- }
- catch (FileError&)
- {
- ++failedAttempts;
- assert(false); //don't throw exceptions due to dst hack here
- continue;
- }
-
- //even at this point it's not sure whether data was written correctly, again cloud storages tend to lie about success status
- if (filesToValidate-- > 0)
- {
- const dst::RawTime encodedTime = dst::fatEncodeUtcTime(timetToFileTime(it->second)); //throw std::runtime_error
-
- //dst hack: verify data written; attention: this check may fail for "sync.ffs_lock"
- WIN32_FILE_ATTRIBUTE_DATA debugeAttr = {};
- ::GetFileAttributesEx(zen::applyLongPathPrefix(it->first).c_str(), //__in LPCTSTR lpFileName,
- GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId,
- &debugeAttr); //__out LPVOID lpFileInformation
-
- if (::CompareFileTime(&debugeAttr.ftCreationTime, &encodedTime.createTimeRaw) != 0 ||
- ::CompareFileTime(&debugeAttr.ftLastWriteTime, &encodedTime.writeTimeRaw) != 0)
- {
- ++failedAttempts;
- assert(false); //don't throw exceptions due to dst hack here
- continue;
- }
- }
- }
- }
-
- const bool needDstHack;
- typedef std::vector<std::pair<Zstring, std::int64_t>> FilenameTimeList;
- FilenameTimeList markForDstHack;
- //####################################### DST hack ###########################################
};
@@ -420,8 +366,7 @@ void DirTraverser::traverse<FilePlusTraverser>(const Zstring& dirpath, TraverseC
inline
-DirTraverser::DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback) :
- needDstHack(dstCallback ? dst::isFatDrive(baseDirectory) : false)
+DirTraverser::DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink)
{
try //traversing certain folders with restricted permissions requires this privilege! (but copying these files may still fail)
{
@@ -433,11 +378,6 @@ DirTraverser::DirTraverser(const Zstring& baseDirectory, TraverseCallback& sink,
traverse<FilePlusTraverser>(baseDirectory, sink, retrieveVolumeSerial(baseDirectory)); //retrieveVolumeSerial returns 0 on error
else //fallback
traverse<Win32Traverser>(baseDirectory, sink, 0);
-
- //apply daylight saving time hack AFTER file traversing, to give separate feedback to user
- if (needDstHack)
- if (dstCallback) //bound if "needDstHack == true"
- applyDstHack(*dstCallback);
}
@@ -507,20 +447,7 @@ void DirTraverser::traverseWithException(const Zstring& dirpath, TraverseCallbac
}
else //a file
{
- TraverseCallback::FileInfo fileInfo = Trav::extractFileInfo(findData, volumeSerial);
-
- //####################################### DST hack ###########################################
- if (needDstHack)
- {
- const dst::RawTime rawTime(Trav::getCreateTimeRaw(findData), Trav::getModTimeRaw(findData));
-
- if (dst::fatHasUtcEncoded(rawTime)) //throw std::runtime_error
- fileInfo.lastWriteTime = filetimeToTimeT(dst::fatDecodeUtcTime(rawTime)); //return real UTC time; throw std::runtime_error
- else
- markForDstHack.push_back(std::make_pair(itempath, filetimeToTimeT(rawTime.writeTimeRaw)));
- }
- //####################################### DST hack ###########################################
-
+ const TraverseCallback::FileInfo fileInfo = Trav::extractFileInfo(findData, volumeSerial);
sink.onFile(shortName, itempath, fileInfo);
}
}
@@ -531,13 +458,13 @@ void DirTraverser::traverseWithException(const Zstring& dirpath, TraverseCallbac
class DirTraverser
{
public:
- static void execute(const Zstring& baseDirectory, TraverseCallback& sink, DstHackCallback* dstCallback)
+ static void execute(const Zstring& baseDirectory, TraverseCallback& sink)
{
- DirTraverser(baseDirectory, sink, dstCallback);
+ DirTraverser(baseDirectory, sink);
}
private:
- DirTraverser(const Zstring& baseDirectory, zen::TraverseCallback& sink, zen::DstHackCallback* dstCallback)
+ DirTraverser(const Zstring& baseDirectory, zen::TraverseCallback& sink)
{
const Zstring directoryFormatted = //remove trailing slash
baseDirectory.size() > 1 && endsWith(baseDirectory, FILE_NAME_SEPARATOR) ? //exception: allow '/'
@@ -701,12 +628,4 @@ private:
}
-void zen::traverseFolder(const Zstring& dirpath, TraverseCallback& sink, DstHackCallback* dstCallback)
-{
- warn_static("let's tentatively disable the DST hack:")
- DirTraverser::execute(dirpath, sink, nullptr);
- return;
-#if 0
- DirTraverser::execute(dirpath, sink, dstCallback);
-#endif
-}
+void zen::traverseFolder(const Zstring& dirpath, TraverseCallback& sink) { DirTraverser::execute(dirpath, sink); }
bgstack15