summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
Diffstat (limited to 'zen')
-rw-r--r--zen/dst_hack.cpp2
-rw-r--r--zen/file_handling.cpp23
-rw-r--r--zen/notify_removal.cpp39
-rw-r--r--zen/perf.h18
-rw-r--r--zen/process_priority.cpp55
-rw-r--r--zen/process_priority.h8
-rw-r--r--zen/recycler.cpp13
-rw-r--r--zen/tick_count.h6
-rw-r--r--zen/type_traits.h6
-rw-r--r--zen/zstring.cpp7
10 files changed, 59 insertions, 118 deletions
diff --git a/zen/dst_hack.cpp b/zen/dst_hack.cpp
index 52d45679..b38f73b4 100644
--- a/zen/dst_hack.cpp
+++ b/zen/dst_hack.cpp
@@ -57,7 +57,7 @@ bool dst::isFatDrive(const Zstring& filepath) //throw()
return false;
const DWORD bufferSize = MAX_PATH + 1;
- wchar_t fsName[bufferSize];
+ wchar_t fsName[bufferSize] = {};
//suprisingly fast: ca. 0.03 ms per call!
if (!::GetVolumeInformation(appendSeparator(volumePath).c_str(), //__in_opt LPCTSTR lpRootPathName,
diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp
index b4622a9c..75062462 100644
--- a/zen/file_handling.cpp
+++ b/zen/file_handling.cpp
@@ -20,7 +20,6 @@
#include <Aclapi.h>
#include "privilege.h"
#include "dll.h"
-#include "win.h" //includes "windows.h"
#include "long_path_prefix.h"
#include "dst_hack.h"
#include "win_ver.h"
@@ -828,8 +827,8 @@ void setFileTimeRaw(const Zstring& filepath, const FILETIME& creationTime, const
nullptr,
&lastWriteTimeDbg));
- assert(std::abs(filetimeToTimeT(creationTimeDbg ) - filetimeToTimeT(creationTime )) <= 2); //respect 2 second FAT/FAT32 precision
- assert(std::abs(filetimeToTimeT(lastWriteTimeDbg) - filetimeToTimeT(lastWriteTime)) <= 2); //
+ assert(std::abs(filetimeToTimeT(lastWriteTimeDbg) - filetimeToTimeT(lastWriteTime)) <= 2); //respect 2 second FAT/FAT32 precision
+ //assert(std::abs(filetimeToTimeT(creationTimeDbg ) - filetimeToTimeT(creationTime )) <= 2); -> creation time not available for Linux-hosted Samba shares!
#endif
}
#endif
@@ -1632,7 +1631,7 @@ void copyFileWindowsSparse(const Zstring& sourceFile,
throw FileError(errorMsg, errorDescr);
}
- ScopeGuard guardTarget = makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: guard just after opening target and before managing hFileOut
+ ScopeGuard guardTarget = makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: guard just after opening target and before managing hFileTarget
ZEN_ON_SCOPE_EXIT(::CloseHandle(hFileTarget));
//----------------------------------------------------------------------
@@ -1772,26 +1771,26 @@ void copyFileWindowsSparse(const Zstring& sourceFile,
FILE_FLAG_SEQUENTIAL_SCAN,
nullptr);
if (hFileTarget == INVALID_HANDLE_VALUE)
- throw 1;
+ throw FileError(L"fail");
ZEN_ON_SCOPE_EXIT(::CloseHandle(hSparse));
DWORD br = 0;
if (!::DeviceIoControl(hSparse, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &br,nullptr))
- throw 1;
+ throw FileError(L"fail");
LARGE_INTEGER liDistanceToMove = {};
liDistanceToMove.QuadPart = 1024 * 1024 * 1024; //create 5 TB sparse file
liDistanceToMove.QuadPart *= 5 * 1024; //maximum file size on NTFS: 16 TB - 64 kB
if (!::SetFilePointerEx(hSparse, liDistanceToMove, nullptr, FILE_BEGIN))
- throw 1;
+ throw FileError(L"fail");
if (!SetEndOfFile(hSparse))
- throw 1;
+ throw FileError(L"fail");
FILE_ZERO_DATA_INFORMATION zeroInfo = {};
zeroInfo.BeyondFinalZero.QuadPart = liDistanceToMove.QuadPart;
if (!::DeviceIoControl(hSparse, FSCTL_SET_ZERO_DATA, &zeroInfo, sizeof(zeroInfo), nullptr, 0, &br, nullptr))
- throw 1;
+ throw FileError(L"fail");
*/
}
@@ -2044,6 +2043,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile,
dst::isFatDrive(targetFile) &&
getFilesize(sourceFile) >= 4U * std::uint64_t(1024U * 1024 * 1024)) //throw FileError
errorDescr += L"\nFAT volumes cannot store files larger than 4 gigabyte.";
+ //see "Limitations of the FAT32 File System": http://support.microsoft.com/kb/314463/en-us
//note: ERROR_INVALID_PARAMETER can also occur when copying to a SharePoint server or MS SkyDrive and the target filepath is of a restricted type.
}
@@ -2255,14 +2255,15 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath
Zstring tmpTarget = targetFile + TEMP_FILE_ENDING; //use temporary file until a correct date has been set
//raw file copy
- for (int i = 1;; ++i)
+ for (int i = 0;; ++i)
try
{
copyFileSelectOs(sourceFile, tmpTarget, onUpdateCopyStatus, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked
break;
}
- catch (const ErrorTargetExisting&) //using optimistic strategy: assume everything goes well, but recover on error -> minimize file accesses
+ catch (const ErrorTargetExisting&) //optimistic strategy: assume everything goes well, but recover on error -> minimize file accesses
{
+ if (i == 10) throw; //avoid endless recursion in pathological cases, e.g. https://sourceforge.net/p/freefilesync/discussion/open-discussion/thread/36adac33
tmpTarget = targetFile + Zchar('_') + numberTo<Zstring>(i) + TEMP_FILE_ENDING;
}
diff --git a/zen/notify_removal.cpp b/zen/notify_removal.cpp
index 3de375f2..45a39c48 100644
--- a/zen/notify_removal.cpp
+++ b/zen/notify_removal.cpp
@@ -38,7 +38,7 @@ private:
MessageProvider (const MessageProvider&) = delete;
MessageProvider& operator=(const MessageProvider&) = delete;
- static const wchar_t dummyWindowName[];
+ static const wchar_t dummyClassName[];
static LRESULT CALLBACK topWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -51,7 +51,7 @@ private:
};
-const wchar_t MessageProvider::dummyWindowName[] = L"E6AD5EB1-527B-4EEF-AC75-27883B233380"; //random name
+const wchar_t MessageProvider::dummyClassName[] = L"E6AD5EB1-527B-4EEF-AC75-27883B233380"; //random name
LRESULT CALLBACK MessageProvider::topWndProc(HWND hwnd, //handle to window
@@ -81,37 +81,30 @@ MessageProvider::MessageProvider() :
WNDCLASS wc = {};
wc.lpfnWndProc = topWndProc;
wc.hInstance = hMainModule;
- wc.lpszClassName = dummyWindowName;
+ wc.lpszClassName = dummyClassName;
if (::RegisterClass(&wc) == 0)
throwFileError(_("Unable to register to receive system messages."), L"RegisterClass", getLastError());
- ScopeGuard guardClass = makeGuard([&] { ::UnregisterClass(dummyWindowName, hMainModule); });
+ ScopeGuard guardClass = makeGuard([&] { ::UnregisterClass(dummyClassName, hMainModule); });
//create dummy-window
- windowHandle = ::CreateWindow(dummyWindowName, //LPCTSTR lpClassName OR ATOM in low-order word!
- nullptr, //LPCTSTR lpWindowName,
- 0, //DWORD dwStyle,
- 0, //int x,
- 0, //int y,
- 0, //int nWidth,
- 0, //int nHeight,
- 0, //note: we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)!
- nullptr, //HMENU hMenu,
- hMainModule, //HINSTANCE hInstance,
- nullptr); //LPVOID lpParam
+ windowHandle = ::CreateWindow(dummyClassName, //_In_opt_ LPCTSTR lpClassName,
+ nullptr, //_In_opt_ LPCTSTR lpWindowName,
+ 0, //_In_ DWORD dwStyle,
+ 0, 0, 0, 0, //_In_ int x, y, nWidth, nHeight,
+ nullptr, //_In_opt_ HWND hWndParent; we need a toplevel window to receive device arrival events, not a message-window (HWND_MESSAGE)!
+ nullptr, //_In_opt_ HMENU hMenu,
+ hMainModule, //_In_opt_ HINSTANCE hInstance,
+ nullptr); //_In_opt_ LPVOID lpParam
if (!windowHandle)
throwFileError(_("Unable to register to receive system messages."), L"CreateWindow", getLastError());
//store this-pointer for topWndProc() to use: do this AFTER CreateWindow() to avoid processing messages while this constructor is running!!!
//unlike: http://blogs.msdn.com/b/oldnewthing/archive/2014/02/03/10496248.aspx
::SetLastError(ERROR_SUCCESS); //[!] required for proper error handling, see MSDN, SetWindowLongPtr
- if (::SetWindowLongPtr(windowHandle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)) == 0)
- {
- const DWORD lastError = ::GetLastError(); //copy before directly or indirectly making other system calls!
- if (lastError != ERROR_SUCCESS)
- throwFileError(_("Unable to register to receive system messages."), L"SetWindowLongPtr", lastError);
- }
+ if (::SetWindowLongPtr(windowHandle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)) == 0 && ::GetLastError() != ERROR_SUCCESS)
+ throwFileError(_("Unable to register to receive system messages."), L"SetWindowLongPtr", ::GetLastError());
guardClass.dismiss();
}
@@ -121,8 +114,8 @@ MessageProvider::~MessageProvider()
{
//clean-up in reverse order
::DestroyWindow(windowHandle);
- ::UnregisterClass(dummyWindowName, //LPCTSTR lpClassName OR ATOM in low-order word!
- hMainModule); //HINSTANCE hInstance
+ ::UnregisterClass(dummyClassName, //LPCTSTR lpClassName OR ATOM in low-order word!
+ hMainModule); //HINSTANCE hInstance
}
diff --git a/zen/perf.h b/zen/perf.h
index ccaa3f07..4405537c 100644
--- a/zen/perf.h
+++ b/zen/perf.h
@@ -4,8 +4,8 @@
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
-#ifndef DEBUG_PERF_HEADER
-#define DEBUG_PERF_HEADER
+#ifndef DEBUG_PERF_HEADER_83947184145342652456
+#define DEBUG_PERF_HEADER_83947184145342652456
#include "deprecate.h"
#include "tick_count.h"
@@ -30,14 +30,10 @@ public:
ZEN_DEPRECATE
PerfTimer() : //throw TimerError
- ticksPerSec_(ticksPerSec()), startTime(), resultShown(false)
+ ticksPerSec_(ticksPerSec()), startTime(getTicks()), resultShown(false)
{
- //std::clock() - "counts CPU time in C and wall time in VC++" - WTF!???
-#ifdef ZEN_WIN
- if (::SetThreadAffinityMask(::GetCurrentThread(), 1) == 0) //"should not be required unless there are bugs in BIOS or HAL" - msdn, QueryPerformanceCounter
- throw TimerError();
-#endif
- startTime = getTicks();
+ //std::clock() - "counts CPU time in Linux GCC and wall time in VC++" - WTF!???
+
if (ticksPerSec_ == 0 || !startTime.isValid())
throw TimerError();
}
@@ -50,7 +46,7 @@ public:
if (!now.isValid())
throw TimerError();
- const auto delta = static_cast<long>(1000.0 * dist(startTime, now) / ticksPerSec_);
+ const std::int64_t delta = 1000 * dist(startTime, now) / ticksPerSec_;
#ifdef ZEN_WIN
std::ostringstream ss;
ss << delta << " ms";
@@ -72,4 +68,4 @@ private:
};
}
-#endif //DEBUG_PERF_HEADER
+#endif //DEBUG_PERF_HEADER_83947184145342652456
diff --git a/zen/process_priority.cpp b/zen/process_priority.cpp
index d2f6dc26..ee8e7d8b 100644
--- a/zen/process_priority.cpp
+++ b/zen/process_priority.cpp
@@ -5,17 +5,11 @@
// **************************************************************************
#include "process_priority.h"
-#include "sys_error.h"
+//#include "sys_error.h"
#include "i18n.h"
#ifdef ZEN_WIN
#include "win.h" //includes "windows.h"
-
-#elif defined ZEN_LINUX
-
-#elif defined ZEN_MAC
-#include <sys/resource.h> //getiopolicy_np
-#include <IOKit/pwr_mgt/IOPMLib.h> //keep in .cpp file to not pollute global namespace!
#endif
using namespace zen;
@@ -99,51 +93,4 @@ private:
const int oldIoPrio;
};
*/
-
-#elif defined ZEN_MAC
-//https://developer.apple.com/library/mac/#qa/qa1340
-struct PreventStandby::Pimpl
-{
- Pimpl() : assertionID() {}
- IOPMAssertionID assertionID;
-};
-
-PreventStandby::PreventStandby() : pimpl(make_unique<Pimpl>())
-{
- IOReturn rv = ::IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
- kIOPMAssertionLevelOn,
- CFSTR("FreeFileSync"),
- &pimpl->assertionID);
- if (rv != kIOReturnSuccess)
- throw FileError(_("Unable to suspend system sleep mode."), replaceCpy<std::wstring>(L"IOReturn Code %x", L"%x", numberTo<std::wstring>(rv))); //could not find a better way to convert IOReturn to string
-}
-
-PreventStandby::~PreventStandby()
-{
- ::IOPMAssertionRelease(pimpl->assertionID);
-}
-
-
-struct ScheduleForBackgroundProcessing::Pimpl
-{
- Pimpl() : oldIoPrio() {}
- int oldIoPrio;
-};
-
-
-ScheduleForBackgroundProcessing::ScheduleForBackgroundProcessing() : pimpl(make_unique<Pimpl>())
-{
- pimpl->oldIoPrio = ::getiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS);
- if (pimpl->oldIoPrio == -1)
- throwFileError(_("Cannot change process I/O priorities."), L"getiopolicy_np", getLastError());
-
- if (::setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE) != 0)
- throwFileError(_("Cannot change process I/O priorities."), L"setiopolicy_np", getLastError());
-}
-
-
-ScheduleForBackgroundProcessing::~ScheduleForBackgroundProcessing()
-{
- ::setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, pimpl->oldIoPrio);
-}
#endif
diff --git a/zen/process_priority.h b/zen/process_priority.h
index 78e49cd0..a133985f 100644
--- a/zen/process_priority.h
+++ b/zen/process_priority.h
@@ -3,11 +3,11 @@
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
-#ifndef PREVENTSTANDBY_H_INCLUDED
-#define PREVENTSTANDBY_H_INCLUDED
+#ifndef PREVENTSTANDBY_H_83421759082143245
+#define PREVENTSTANDBY_H_83421759082143245
#include <memory>
-#include <zen/file_error.h>
+#include "file_error.h"
namespace zen
{
@@ -34,4 +34,4 @@ private:
};
}
-#endif // PREVENTSTANDBY_H_INCLUDED
+#endif //PREVENTSTANDBY_H_83421759082143245
diff --git a/zen/recycler.cpp b/zen/recycler.cpp
index 41ea6002..930b05ac 100644
--- a/zen/recycler.cpp
+++ b/zen/recycler.cpp
@@ -84,20 +84,21 @@ void zen::recycleOrDelete(const std::vector<Zstring>& itempaths, const std::func
if (vistaOrLater()) //new recycle bin usage: available since Vista
{
- using namespace fileop;
- const DllFun<FunType_moveToRecycleBin > moveToRecycler (getDllName(), funName_moveToRecycleBin);
- const DllFun<FunType_getLastErrorMessage> getLastErrorMessage(getDllName(), funName_getLastErrorMessage);
+#define DEF_DLL_FUN(name) const DllFun<fileop::FunType_##name> name(fileop::getDllName(), fileop::funName_##name);
+DEF_DLL_FUN(moveToRecycleBin);
+DEF_DLL_FUN(getLastErrorMessage);
+#undef DEF_DLL_FUN
- if (!moveToRecycler || !getLastErrorMessage)
+ if (!moveToRecycleBin || !getLastErrorMessage)
throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempaths[0])),
- replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName())));
+ replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(fileop::getDllName())));
std::vector<const wchar_t*> cNames;
for (auto it = itempaths.begin(); it != itempaths.end(); ++it) //CAUTION: do not create temporary strings here!!
cNames.push_back(it->c_str());
CallbackData cbd(notifyDeletionStatus);
- if (!moveToRecycler(&cNames[0], cNames.size(), onRecyclerCallback, &cbd))
+ if (!moveToRecycleBin(&cNames[0], cNames.size(), onRecyclerCallback, &cbd))
{
if (cbd.exceptionInUserCallback)
{
diff --git a/zen/tick_count.h b/zen/tick_count.h
index cb15fe20..482689d7 100644
--- a/zen/tick_count.h
+++ b/zen/tick_count.h
@@ -102,7 +102,7 @@ int64_t ticksPerSec() //return 0 on error
#ifdef ZEN_WIN
LARGE_INTEGER frequency = {};
if (!::QueryPerformanceFrequency(&frequency)) //MSDN promises: "The frequency cannot change while the system is running."
- return 0;
+ return 0; //MSDN: "This won't occur on any system that runs Windows XP or later."
static_assert(sizeof(int64_t) >= sizeof(frequency.QuadPart), "");
return frequency.QuadPart;
@@ -126,8 +126,10 @@ TickVal getTicks() //return !isValid() on error
{
#ifdef ZEN_WIN
LARGE_INTEGER now = {};
- if (!::QueryPerformanceCounter(&now)) //msdn: SetThreadAffinityMask() may be required if there are bugs in BIOS or HAL"
+ if (!::QueryPerformanceCounter(&now))
return TickVal();
+ //detailed info about QPC: http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx
+ //- MSDN: "No need to set the thread affinity"
#elif defined ZEN_LINUX
//gettimeofday() seems fine but is deprecated
diff --git a/zen/type_traits.h b/zen/type_traits.h
index 1c2da5eb..8e85a7b2 100644
--- a/zen/type_traits.h
+++ b/zen/type_traits.h
@@ -7,7 +7,7 @@
#ifndef TYPE_TRAITS_HEADER_3425628658765467
#define TYPE_TRAITS_HEADER_3425628658765467
-#include <type_traits> //all we need is std::is_class!!
+#include <type_traits> //all we need is std::is_class!!
namespace zen
{
@@ -38,10 +38,10 @@ struct ResultType
//Herb Sutter's signedness conversion helpers: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/
template<class T> inline
-typename std::make_signed<T>::type makeSigned(T t) { return std::make_signed<T>::type(t); }
+typename std::make_signed<T>::type makeSigned(T t) { return typename std::make_signed<T>::type(t); }
template<class T> inline
-typename std::make_unsigned<T>::type makeUnsigned(T t) { return std::make_unsigned<T>::type(t); }
+typename std::make_unsigned<T>::type makeUnsigned(T t) { return typename std::make_unsigned<T>::type(t); }
//################# Built-in Types ########################
//Example: "IsSignedInt<int>::value" evaluates to "true"
diff --git a/zen/zstring.cpp b/zen/zstring.cpp
index f1858efc..f16af6a0 100644
--- a/zen/zstring.cpp
+++ b/zen/zstring.cpp
@@ -18,6 +18,7 @@
#ifndef NDEBUG
#include <mutex>
#include <iostream>
+#include "thread.h"
#endif
using namespace zen;
@@ -38,14 +39,14 @@ public:
void insert(const void* ptr, size_t size)
{
- std::lock_guard<std::mutex> dummy(lockActStrings);
+ boost::lock_guard<boost::mutex> dummy(lockActStrings);
if (!activeStrings.insert(std::make_pair(ptr, size)).second)
reportProblem("Serious Error: New memory points into occupied space: " + rawMemToString(ptr, size));
}
void remove(const void* ptr)
{
- std::lock_guard<std::mutex> dummy(lockActStrings);
+ boost::lock_guard<boost::mutex> dummy(lockActStrings);
if (activeStrings.erase(ptr) != 1)
reportProblem("Serious Error: No memory available for deallocation at this location!");
}
@@ -94,7 +95,7 @@ private:
throw std::logic_error("Memory leak! " + message);
}
- std::mutex lockActStrings;
+ boost::mutex lockActStrings;
zen::hash_map<const void*, size_t> activeStrings;
};
bgstack15