summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:39 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:39 +0200
commitd2854834e18443876c8f75e0a7f3b88d1d549fc4 (patch)
treee967b628081e50abc7c34cd264e6586271c7e728 /lib
parent4.1 (diff)
downloadFreeFileSync-d2854834e18443876c8f75e0a7f3b88d1d549fc4.tar.gz
FreeFileSync-d2854834e18443876c8f75e0a7f3b88d1d549fc4.tar.bz2
FreeFileSync-d2854834e18443876c8f75e0a7f3b88d1d549fc4.zip
4.2
Diffstat (limited to 'lib')
-rw-r--r--lib/FindFilePlus/dll_main.cpp2
-rw-r--r--lib/FindFilePlus/load_dll.cpp2
-rw-r--r--lib/FindFilePlus/load_dll.h1
-rw-r--r--lib/IFileOperation/file_op.cpp240
-rw-r--r--lib/ShadowCopy/Shadow_Server2003.vcxproj (renamed from lib/ShadowCopy/Shadow_2003.vcxproj)0
-rw-r--r--lib/ShadowCopy/Shadow_Windows7.vcxproj241
-rw-r--r--lib/ShadowCopy/shadow.cpp196
-rw-r--r--lib/ShadowCopy/shadow.h68
-rw-r--r--lib/Thumbnail/thumbnail.cpp5
-rw-r--r--lib/cmp_filetime.h11
-rw-r--r--lib/custom_grid.cpp10
-rw-r--r--lib/db_file.cpp40
-rw-r--r--lib/dir_lock.cpp22
-rw-r--r--lib/dir_name.cpp2
-rw-r--r--lib/error_log.cpp20
-rw-r--r--lib/ffs_paths.h44
-rw-r--r--lib/help_provider.h2
-rw-r--r--lib/icon_buffer.cpp143
-rw-r--r--lib/icon_buffer.h8
-rw-r--r--lib/localization.cpp15
-rw-r--r--lib/lock_holder.h2
-rw-r--r--lib/parallel_scan.cpp30
-rw-r--r--lib/parse_plural.h2
-rw-r--r--lib/process_xml.cpp8
-rw-r--r--lib/process_xml.h5
-rw-r--r--lib/recycler.cpp22
-rw-r--r--lib/resolve_path.cpp32
-rw-r--r--lib/resources.cpp2
-rw-r--r--lib/shadow.cpp40
-rw-r--r--lib/statistics.h3
-rw-r--r--lib/xml_base.cpp14
-rw-r--r--lib/xml_base.h4
32 files changed, 716 insertions, 520 deletions
diff --git a/lib/FindFilePlus/dll_main.cpp b/lib/FindFilePlus/dll_main.cpp
index aca474bc..5d64181b 100644
--- a/lib/FindFilePlus/dll_main.cpp
+++ b/lib/FindFilePlus/dll_main.cpp
@@ -6,7 +6,7 @@
#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+#include <zen/win.h>
#include "init_dll_binding.h"
diff --git a/lib/FindFilePlus/load_dll.cpp b/lib/FindFilePlus/load_dll.cpp
index 7166223b..20d9a5fe 100644
--- a/lib/FindFilePlus/load_dll.cpp
+++ b/lib/FindFilePlus/load_dll.cpp
@@ -6,7 +6,7 @@
#include "load_dll.h"
#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+#include <zen/win.h>
void* /*FARPROC*/ dll::loadSymbol(const wchar_t* libraryName, const char* functionName)
{
diff --git a/lib/FindFilePlus/load_dll.h b/lib/FindFilePlus/load_dll.h
index 149b6efe..350de9f8 100644
--- a/lib/FindFilePlus/load_dll.h
+++ b/lib/FindFilePlus/load_dll.h
@@ -44,4 +44,3 @@ void* /*FARPROC*/ loadSymbol(const wchar_t* libraryName, const char* functionNam
}
#endif //LOAD_DLL_HEADER_0312463214872163832174
-
diff --git a/lib/IFileOperation/file_op.cpp b/lib/IFileOperation/file_op.cpp
index 10eac5de..fca802f0 100644
--- a/lib/IFileOperation/file_op.cpp
+++ b/lib/IFileOperation/file_op.cpp
@@ -5,69 +5,38 @@
// **************************************************************************
#include "file_op.h"
+#include <algorithm>
+#include <string>
#define WIN32_LEAN_AND_MEAN
-#include <zen/win.h>
#include <zen/com_ptr.h>
#include <zen/com_error.h>
-#include <Shellapi.h> // Included for shell constants such as FO_* values
-#include <shobjidl.h> // Required for necessary shell dependencies
-#include <algorithm>
-#include <string>
+#include <shellapi.h> //shell constants such as FO_* values
+#include <shobjidl.h>
using namespace zen;
-namespace fileop
+namespace
{
-inline
-void copyString(const std::wstring& input, wchar_t* buffer, size_t bufferSize)
+void moveToRecycleBin(const wchar_t* fileNames[], //throw ComError
+ size_t fileNo) //size of fileNames array
{
- if (bufferSize > 0)
- {
- //size_t endPos = input.copy(buffer, bufferSize - 1);
- //buffer[endPos] = 0;
- const size_t maxSize = std::min(input.length(), bufferSize - 1);
- std::copy(input.begin(), input.begin() + maxSize, buffer);
- buffer[maxSize] = 0;
- }
-}
-
-std::wstring lastErrorMessage; //this should really be thread-local!!!
-}
-
-
-bool fileop::moveToRecycleBin(const wchar_t* fileNames[],
- size_t fileNo) //size of fileNames array
-{
- HRESULT hr;
-
- // Create the IFileOperation interface
ComPtr<IFileOperation> fileOp;
- hr = ::CoCreateInstance(CLSID_FileOperation,
- NULL,
- CLSCTX_ALL,
- IID_PPV_ARGS(fileOp.init()));
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(::CoCreateInstance(CLSID_FileOperation, //throw ComError
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(fileOp.init())));
// Set the operation flags. Turn off all UI
// from being shown to the user during the
// operation. This includes error, confirmation
// and progress dialogs.
- hr = fileOp->SetOperationFlags(FOF_ALLOWUNDO |
- FOF_NOCONFIRMATION |
- FOF_SILENT |
- FOFX_EARLYFAILURE |
- FOF_NOERRORUI);
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"SetOperationFlags\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(fileOp->SetOperationFlags(FOF_ALLOWUNDO | //throw ComError
+ FOF_NOCONFIRMATION |
+ FOF_SILENT |
+ FOFX_EARLYFAILURE |
+ FOF_NOERRORUI));
int operationCount = 0;
@@ -75,161 +44,142 @@ bool fileop::moveToRecycleBin(const wchar_t* fileNames[],
{
//create file/folder item object
ComPtr<IShellItem> psiFile;
- hr = ::SHCreateItemFromParsingName(fileNames[i],
- NULL,
- IID_PPV_ARGS(psiFile.init()));
+ HRESULT hr = ::SHCreateItemFromParsingName(fileNames[i],
+ NULL,
+ IID_PPV_ARGS(psiFile.init()));
if (FAILED(hr))
{
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || //file not existing anymore
hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND))
continue;
-
- std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n");
- message += std::wstring(L"\"") + fileNames[i] + L"\".";
-
- lastErrorMessage = generateErrorMsg(message, hr);
- return false;
+ throw ComError(std::wstring(L"Error calling \"SHCreateItemFromParsingName\" for file:\n") + L"\"" + fileNames[i] + L"\".", hr);
}
- hr = fileOp->DeleteItem(psiFile.get(), NULL);
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"DeleteItem\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(fileOp->DeleteItem(psiFile.get(), NULL));
++operationCount;
}
- if (operationCount == 0) //calling PerformOperations() without anything to do results in E_UNEXPECTED
- return true;
+ if (operationCount == 0) //calling PerformOperations() without anything to do would result in E_UNEXPECTED
+ return;
//perform actual operations
- hr = fileOp->PerformOperations();
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"PerformOperations\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(fileOp->PerformOperations());
//check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors!
BOOL pfAnyOperationsAborted = FALSE;
- hr = fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted);
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted));
if (pfAnyOperationsAborted == TRUE)
- {
- lastErrorMessage = L"Operation did not complete successfully.";
- return false;
- }
-
- return true;
+ throw ComError(L"Operation did not complete successfully.");
}
-bool fileop::copyFile(const wchar_t* sourceFile,
- const wchar_t* targetFile)
+void copyFile(const wchar_t* sourceFile, //throw ComError
+ const wchar_t* targetFile)
{
- HRESULT hr;
-
- // Create the IFileOperation interface
ComPtr<IFileOperation> fileOp;
- hr = ::CoCreateInstance(CLSID_FileOperation,
- NULL,
- CLSCTX_ALL,
- IID_PPV_ARGS(fileOp.init()));
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(::CoCreateInstance(CLSID_FileOperation, //throw ComError
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(fileOp.init())));
// Set the operation flags. Turn off all UI
// from being shown to the user during the
// operation. This includes error, confirmation
// and progress dialogs.
- hr = fileOp->SetOperationFlags(FOF_NOCONFIRMATION |
- FOF_SILENT |
- FOFX_EARLYFAILURE |
- FOF_NOERRORUI);
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"SetOperationFlags\".", hr);
- return false;
- }
-
+ ZEN_CHECK_COM(fileOp->SetOperationFlags(FOF_NOCONFIRMATION | //throw ComError
+ FOF_SILENT |
+ FOFX_EARLYFAILURE |
+ FOF_NOERRORUI));
//create source object
ComPtr<IShellItem> psiSourceFile;
- hr = ::SHCreateItemFromParsingName(sourceFile,
- NULL,
- IID_PPV_ARGS(psiSourceFile.init()));
- if (FAILED(hr))
{
- std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n");
- message += std::wstring(L"\"") + sourceFile + L"\".";
- lastErrorMessage = generateErrorMsg(message, hr);
- return false;
+ HRESULT hr = ::SHCreateItemFromParsingName(sourceFile,
+ NULL,
+ IID_PPV_ARGS(psiSourceFile.init()));
+ if (FAILED(hr))
+ throw ComError(std::wstring(L"Error calling \"SHCreateItemFromParsingName\" for file:\n") + L"\"" + sourceFile + L"\".", hr);
}
const size_t pos = std::wstring(targetFile).find_last_of(L'\\');
if (pos == std::wstring::npos)
- {
- lastErrorMessage = L"Target filename does not contain a path separator.";
- return false;
- }
+ throw ComError(L"Target filename does not contain a path separator.");
const std::wstring targetFolder(targetFile, pos);
const std::wstring targetFileNameShort = targetFile + pos + 1;
//create target folder object
ComPtr<IShellItem> psiTargetFolder;
- hr = ::SHCreateItemFromParsingName(targetFolder.c_str(),
- NULL,
- IID_PPV_ARGS(psiTargetFolder.init()));
- if (FAILED(hr))
{
- std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for folder:\n");
- message += std::wstring(L"\"") + targetFolder + L"\".";
- lastErrorMessage = generateErrorMsg(message, hr);
- return false;
+ HRESULT hr = ::SHCreateItemFromParsingName(targetFolder.c_str(),
+ NULL,
+ IID_PPV_ARGS(psiTargetFolder.init()));
+ if (FAILED(hr))
+ throw ComError(std::wstring(L"Error calling \"SHCreateItemFromParsingName\" for folder:\n") + L"\"" + targetFolder + L"\".", hr);
}
//schedule file copy operation
- hr = fileOp->CopyItem(psiSourceFile.get(), psiTargetFolder.get(), targetFileNameShort.c_str(), NULL);
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"CopyItem\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(fileOp->CopyItem(psiSourceFile.get(), psiTargetFolder.get(), targetFileNameShort.c_str(), NULL));
//perform actual operations
- hr = fileOp->PerformOperations();
- if (FAILED(hr))
- {
- lastErrorMessage = generateErrorMsg(L"Error calling \"PerformOperations\".", hr);
- return false;
- }
+ ZEN_CHECK_COM(fileOp->PerformOperations());
//check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors!
BOOL pfAnyOperationsAborted = FALSE;
- hr = fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted);
- if (FAILED(hr))
+ ZEN_CHECK_COM(fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted));
+
+ if (pfAnyOperationsAborted == TRUE)
+ throw ComError(L"Operation did not complete successfully.");
+}
+
+
+inline
+void copyString(const std::wstring& input, wchar_t* buffer, size_t bufferSize)
+{
+ if (bufferSize > 0)
{
- lastErrorMessage = generateErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr);
- return false;
+ //size_t endPos = input.copy(buffer, bufferSize - 1);
+ //buffer[endPos] = 0;
+ const size_t maxSize = std::min(input.length(), bufferSize - 1);
+ std::copy(input.begin(), input.begin() + maxSize, buffer);
+ buffer[maxSize] = 0;
}
+}
- if (pfAnyOperationsAborted == TRUE)
+std::wstring lastErrorMessage; //this should really be thread-local!!!
+}
+
+
+bool fileop::moveToRecycleBin(const wchar_t* fileNames[],
+ size_t fileNo) //size of fileNames array
+{
+ try
+ {
+ ::moveToRecycleBin(fileNames, fileNo); //throw ComError
+ return true;
+ }
+ catch (const zen::ComError& e)
{
- lastErrorMessage = L"Operation did not complete successfully.";
+ lastErrorMessage = e.toString();
return false;
}
+}
+
- return true;
+bool fileop::copyFile(const wchar_t* sourceFile,
+ const wchar_t* targetFile)
+{
+ try
+ {
+ ::copyFile(sourceFile, targetFile); //throw ComError
+ return true;
+ }
+ catch (const zen::ComError& e)
+ {
+ lastErrorMessage = e.toString();
+ return false;
+ }
}
diff --git a/lib/ShadowCopy/Shadow_2003.vcxproj b/lib/ShadowCopy/Shadow_Server2003.vcxproj
index a893a389..a893a389 100644
--- a/lib/ShadowCopy/Shadow_2003.vcxproj
+++ b/lib/ShadowCopy/Shadow_Server2003.vcxproj
diff --git a/lib/ShadowCopy/Shadow_Windows7.vcxproj b/lib/ShadowCopy/Shadow_Windows7.vcxproj
new file mode 100644
index 00000000..2392fa99
--- /dev/null
+++ b/lib/ShadowCopy/Shadow_Windows7.vcxproj
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>Windows7</ProjectName>
+ <ProjectGuid>{7E217D76-90A5-4B03-A6F8-E7C3ADD22901}</ProjectGuid>
+ <RootNamespace>ShadowDll</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <UseOfAtl>false</UseOfAtl>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Shadow_$(ProjectName)_$(Platform)</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <BuildLog>
+ <Path>$(IntDir)Build.html</Path>
+ </BuildLog>
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
+ <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <ProfileGuidedDatabase>
+ </ProfileGuidedDatabase>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="dll_main.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
+ </ClCompile>
+ <ClCompile Include="shadow.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="shadow.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/lib/ShadowCopy/shadow.cpp b/lib/ShadowCopy/shadow.cpp
index 12e9fa60..5047a698 100644
--- a/lib/ShadowCopy/shadow.cpp
+++ b/lib/ShadowCopy/shadow.cpp
@@ -7,12 +7,9 @@
#include "shadow.h"
#include <algorithm>
#include <string>
-#include <comdef.h>
#include <zen/com_ptr.h>
#include <zen/com_error.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include "windows.h"
+#include <zen/scope_guard.h>
#ifdef USE_SHADOW_XP
#include "xp/inc/vss.h"
@@ -23,13 +20,30 @@
#include "Server 2003/inc/vss.h"
#include "Server 2003/inc/vswriter.h"
#include "Server 2003/inc/vsbackup.h"
+
+#elif defined USE_SHADOW_WINDOWS7
+#include <vss.h> //
+#include <vswriter.h> //part of Windows SDK for Windows 7
+#include <vsbackup.h> //
+#pragma comment(lib, "VssApi.lib")
+
#else
-adapt!
+#error adapt!
#endif
using namespace zen;
+struct shadow::ShadowData
+{
+ ShadowData(const ComPtr<IVssBackupComponents>& backupComp,
+ const std::wstring& shadowVolume) : backupComp_(backupComp), shadowVolume_(shadowVolume) {}
+
+ ComPtr<IVssBackupComponents> backupComp_;
+ std::wstring shadowVolume_;
+};
+
+
namespace
{
inline
@@ -45,143 +59,99 @@ void copyString(const std::wstring& input, wchar_t* buffer, size_t bufferSize)
}
}
-inline
-void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, unsigned int outputLen)
-{
- copyString(generateErrorMsg(input, hr), output, outputLen);
-}
-}
-
-bool shadow::createShadowCopy(const wchar_t* volumeName,
- wchar_t* shadowVolName,
- unsigned int shadowBufferLen,
- ShadowHandle* handle,
- wchar_t* errorMessage,
- unsigned int errorBufferLen)
+shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw ComError
{
- //MessageBox(0, L"backup err", L"", 0); */
- *handle = 0;
- HRESULT hr = NULL;
-
ComPtr<IVssBackupComponents> backupComp;
- if (FAILED(hr = CreateVssBackupComponents(backupComp.init())))
{
- if (hr == E_ACCESSDENIED)
- writeErrorMsg(L"The caller does not have sufficient backup privileges or is not an administrator.", hr, errorMessage, errorBufferLen);
- else
- writeErrorMsg(L"Error calling \"CreateVssBackupComponents\".", hr, errorMessage, errorBufferLen);
- return false;
+ HRESULT hr = ::CreateVssBackupComponents(backupComp.init());
+ if (FAILED(hr))
+ {
+ if (hr == E_ACCESSDENIED)
+ throw ComError(L"The caller does not have sufficient backup privileges or is not an administrator.", hr);
+ throw ComError(L"Error calling \"CreateVssBackupComponents\".", hr);
+ }
}
- if (FAILED(hr = backupComp->InitializeForBackup()))
- {
- writeErrorMsg(L"Error calling \"InitializeForBackup\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ZEN_CHECK_COM(backupComp->InitializeForBackup()); //throw ComError
+ ZEN_CHECK_COM(backupComp->SetBackupState(false, false, VSS_BT_FULL)); //throw ComError
- if (FAILED(hr = backupComp->SetBackupState(false, false, VSS_BT_FULL)))
+ auto waitForComFuture = [](IVssAsync& fut)
{
- writeErrorMsg(L"Error calling \"SetBackupState\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ZEN_CHECK_COM(fut.Wait());
- ComPtr<IVssAsync> vssWriters;
- if (FAILED(hr = backupComp->GatherWriterMetadata(vssWriters.init())))
- {
- //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build)
- writeErrorMsg(L"Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ HRESULT hr = S_OK;
+ ZEN_CHECK_COM(fut.QueryStatus(&hr, NULL)); //check if the async operation succeeded...
+ if (FAILED(hr))
+ throw ComError(L"Error calling \"fut->QueryStatus\".", hr);
+ };
- //wait for shadow copy writers to complete
- if (FAILED(hr = vssWriters->Wait()))
- {
- writeErrorMsg(L"Error calling \"vssWriters->Wait\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ComPtr<IVssAsync> gatherAsync;
+ ZEN_CHECK_COM(backupComp->GatherWriterMetadata(gatherAsync.init()));
+ waitForComFuture(*gatherAsync); //failure can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build)
- vssWriters->QueryStatus(&hr, NULL); //check if the async operation succeeded...
- if (FAILED(hr))
- {
- writeErrorMsg(L"Error calling \"vssWriters->QueryStatus\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ VSS_ID snapshotSetId = {};
+ ZEN_CHECK_COM(backupComp->StartSnapshotSet(&snapshotSetId));
+ ScopeGuard guardSnapShot = makeGuard([&]() { backupComp->AbortBackup(); });
+ //Quote: "This method must be called if a backup operation terminates after the creation of a
+ //shadow copy set with "StartSnapshotSet" and before "DoSnapshotSet" returns."
- VSS_ID snapshotSetId = {0};
- if (FAILED(hr = backupComp->StartSnapshotSet(&snapshotSetId)))
+ VSS_ID SnapShotId = {};
{
- writeErrorMsg(L"Error calling \"StartSnapshotSet\".", hr, errorMessage, errorBufferLen);
- return false;
+ HRESULT hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId);
+ if (FAILED(hr))
+ {
+ if (hr == VSS_E_VOLUME_NOT_SUPPORTED)
+ throw ComError(L"Volume Shadow Copy Service is not supported on this volume!");
+ throw ComError(L"Error calling \"backupComp->AddToSnapshotSet\".", hr);
+ }
}
- VSS_ID SnapShotId = {0};
- if (FAILED(hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId)))
- {
- writeErrorMsg(L"Error calling \"AddToSnapshotSet\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ComPtr<IVssAsync> prepareAsync;
+ ZEN_CHECK_COM(backupComp->PrepareForBackup(prepareAsync.init()));
+ waitForComFuture(*prepareAsync);
- ComPtr<IVssAsync> vssPrepare;
- if (FAILED(hr = backupComp->PrepareForBackup(vssPrepare.init())))
- {
- writeErrorMsg(L"Error calling \"PrepareForBackup\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ ComPtr<IVssAsync> snapshotAsync;
+ ZEN_CHECK_COM(backupComp->DoSnapshotSet(snapshotAsync.init()));
+ guardSnapShot.dismiss();
+ waitForComFuture(*snapshotAsync);
- if (FAILED(hr = vssPrepare->Wait()))
- {
- writeErrorMsg(L"Error calling \"vssPrepare->Wait\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ VSS_SNAPSHOT_PROP props = {};
+ ZEN_CHECK_COM(backupComp->GetSnapshotProperties(SnapShotId, &props));
+ ZEN_ON_BLOCK_EXIT(::VssFreeSnapshotProperties(&props));
- vssPrepare->QueryStatus(&hr, NULL); //check if the async operation succeeded...
- if (FAILED(hr))
- {
- writeErrorMsg(L"Error calling \"vssPrepare->QueryStatus\".", hr, errorMessage, errorBufferLen);
- return false;
- }
-
- ComPtr<IVssAsync> vssDoShadowCopy;
- if (FAILED(hr = backupComp->DoSnapshotSet(vssDoShadowCopy.init())))
- {
- writeErrorMsg(L"Error calling \"DoSnapshotSet\".", hr, errorMessage, errorBufferLen);
- return false;
- }
+ //finally: write volume name of newly created shadow copy
+ return shadow::ShadowData(backupComp, props.m_pwszSnapshotDeviceObject);
+}
+}
- if (FAILED(hr = vssDoShadowCopy->Wait()))
- {
- writeErrorMsg(L"Error calling \"vssDoShadowCopy->Wait\".", hr, errorMessage, errorBufferLen);
- return false;
- }
- vssDoShadowCopy->QueryStatus(&hr, NULL); //check if the async operation succeeded...
- if (FAILED(hr))
+shadow::ShadowHandle shadow::createShadowCopy(const wchar_t* volumeName,
+ wchar_t* errorMessage,
+ unsigned int errorBufferLen)
+{
+ try
{
- writeErrorMsg(L"Error calling \"vssDoShadowCopy->QueryStatus\".", hr, errorMessage, errorBufferLen);
- return false;
+ ShadowData result = ::createShadowCopy(volumeName); //shadow handle owned by caller! throw ComError
+ return new ShadowData(result);
}
-
- VSS_SNAPSHOT_PROP props;
- if (FAILED(hr = backupComp->GetSnapshotProperties(SnapShotId, &props)))
+ catch (const zen::ComError& e)
{
- writeErrorMsg(L"Error calling \"GetSnapshotProperties\".", hr, errorMessage, errorBufferLen);
- return false;
+ copyString(e.toString(), errorMessage, errorBufferLen);
+ return nullptr;
}
+}
- //finally: write volume name of newly created shadow copy
- copyString(props.m_pwszSnapshotDeviceObject, shadowVolName, shadowBufferLen);
-
- VssFreeSnapshotProperties(&props);
-
- *handle = backupComp.release();
- return true;
+void shadow::getShadowVolume(shadow::ShadowHandle handle,
+ wchar_t* buffer,
+ unsigned int bufferLen)
+{
+ copyString(handle->shadowVolume_, buffer, bufferLen);
}
void shadow::releaseShadowCopy(ShadowHandle handle)
{
- if (handle)
- handle->Release();
+ delete handle;
}
diff --git a/lib/ShadowCopy/shadow.h b/lib/ShadowCopy/shadow.h
index 0dfd39a9..68b7141f 100644
--- a/lib/ShadowCopy/shadow.h
+++ b/lib/ShadowCopy/shadow.h
@@ -26,23 +26,23 @@ namespace shadow
--------------*/
//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
+struct ShadowData;
+typedef ShadowData* ShadowHandle;
-typedef IVssBackupComponents* ShadowHandle;
-
-//volumeName must end with "\", while shadowVolName does not end with "\"
+//volumeName *must* end with "\"
SHADOWDLL_API
-bool createShadowCopy(const wchar_t* volumeName, // in
- wchar_t* shadowVolName, // out
- unsigned int shadowBufferLen, // in
- ShadowHandle* handle, // out
- wchar_t* errorMessage, // out
- unsigned int errorBufferLen); // in
-
+ShadowHandle createShadowCopy(const wchar_t* volumeName, // in Returns nullptr on failure!
+ wchar_t* errorMessage, // out
+ unsigned int errorBufferLen); // in
//don't forget to release the backupHandle after shadow copy is not needed anymore!
SHADOWDLL_API
void releaseShadowCopy(ShadowHandle handle);
+SHADOWDLL_API
+void getShadowVolume(ShadowHandle handle, //shadowVolName does *not* end with "\"
+ wchar_t* buffer,
+ unsigned int bufferLen);
//##########################################################################################
@@ -50,21 +50,24 @@ void releaseShadowCopy(ShadowHandle handle);
/*----------
|typedefs|
----------*/
-typedef bool (*CreateShadowCopyFct)(const wchar_t* volumeName,
- wchar_t* shadowVolName,
- unsigned int shadowBufferLen,
- ShadowHandle* handle,
- wchar_t* errorMessage,
- unsigned int errorBufferLen);
+typedef ShadowHandle (*CreateShadowCopyFct)(const wchar_t* volumeName,
+ wchar_t* errorMessage,
+ unsigned int errorBufferLen);
typedef void (*ReleaseShadowCopyFct)(ShadowHandle handle);
+typedef void (*GetShadowVolumeFct)(ShadowHandle handle,
+ wchar_t* buffer,
+ unsigned int bufferLen);
+
+
/*--------------
|symbol names|
--------------*/
//(use const pointers to ensure internal linkage)
-const char createShadowCopyFctName[] = "createShadowCopy";
+const char createShadowCopyFctName [] = "createShadowCopy";
const char releaseShadowCopyFctName[] = "releaseShadowCopy";
+const char getShadowVolumeFctName [] = "getShadowVolume";
/*---------------
|library names|
@@ -73,21 +76,24 @@ const char releaseShadowCopyFctName[] = "releaseShadowCopy";
inline
const wchar_t* getDllName()
{
- /*
- distinguish a bunch of VSS builds: we use XP and Server 2003 implementations...
- VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx
- */
- return zen::winServer2003orLater() ?
- (zen::is64BitBuild ?
- L"Shadow_Server2003_x64.dll" :
- L"Shadow_Server2003_Win32.dll") :
-
- (zen::is64BitBuild ?
- L"Shadow_XP_x64.dll" :
- L"Shadow_XP_Win32.dll");
+ // distinguish a bunch of VSS builds: we use XP, Server 2003 and Server 2008 R2 implementations...
+ // VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx
+
+ if (zen::win7OrLater()) //Windows Server 2008 R2 or Windows 7
+ return zen::is64BitBuild ?
+ L"Shadow_Windows7_x64.dll" :
+ L"Shadow_Windows7_Win32.dll";
+ //else if (vistaOrLater()) -> skip Windows Server 2008 and Windows Vista
+ // ;
+ else if (zen::winServer2003orLater()) //Windows Server 2003 and Windows Server 2003 R2
+ return zen::is64BitBuild ?
+ L"Shadow_Server2003_x64.dll" :
+ L"Shadow_Server2003_Win32.dll";
+ else //Windows XP
+ return zen::is64BitBuild ?
+ L"Shadow_XP_x64.dll" :
+ L"Shadow_XP_Win32.dll";
}
}
-
-
#endif //SHADOWCOPY_H
diff --git a/lib/Thumbnail/thumbnail.cpp b/lib/Thumbnail/thumbnail.cpp
index b8d00c38..c3d22cbd 100644
--- a/lib/Thumbnail/thumbnail.cpp
+++ b/lib/Thumbnail/thumbnail.cpp
@@ -5,9 +5,10 @@
// **************************************************************************
#include "thumbnail.h"
+#include <string>
#define WIN32_LEAN_AND_MEAN
-#include "windows.h"
+#include <zen/win.h>
#define STRICT_TYPED_ITEMIDS //better type safety for IDLists
#include <Shlobj.h>
@@ -16,12 +17,12 @@
#include <CommonControls.h>
#include <zen/com_ptr.h>
#include <zen/string_tools.h>
-#include <string>
#include <zen/scope_guard.h>
using namespace zen;
+
thumb::HICON thumb::getThumbnail(const wchar_t* filename, int requestedSize) //return 0 on failure, caller takes ownership!
{
const std::wstring filenameStr(filename);
diff --git a/lib/cmp_filetime.h b/lib/cmp_filetime.h
index e8cd6f50..afc97b9d 100644
--- a/lib/cmp_filetime.h
+++ b/lib/cmp_filetime.h
@@ -18,8 +18,8 @@ bool sameFileTime(const Int64& a, const Int64& b, size_t tolerance)
//---------------------------------------------------------------------------------------------------------------
//number of seconds since Jan 1st 1970 + 1 year (needn't be too precise)
-static const long oneYearFromNow = wxGetUTCTime() + 365 * 24 * 3600; //init at program startup -> avoid MT issues
-
+static const long oneYearFromNow = wxGetUTCTime() + 365 * 24 * 3600; //init at program startup alas in *each* compilation untit -> avoid MT issues
+//refactor when C++11 thread-safe static initialization is availalbe in VS (already in GCC)
class CmpFileTime
{
@@ -37,19 +37,16 @@ public:
Result getResult(const Int64& lhs, const Int64& rhs) const
{
- if (lhs == rhs)
+ if (sameFileTime(lhs, rhs, tolerance_)) //last write time may differ by up to 2 seconds (NTFS vs FAT32)
return TIME_EQUAL;
- //check for erroneous dates (but only if dates are not (EXACTLY) the same)
+ //check for erroneous dates
if (lhs < 0 || lhs > oneYearFromNow) //earlier than Jan 1st 1970 or more than one year in future
return TIME_LEFT_INVALID;
if (rhs < 0 || rhs > oneYearFromNow)
return TIME_RIGHT_INVALID;
- if (sameFileTime(lhs, rhs, tolerance_)) //last write time may differ by up to 2 seconds (NTFS vs FAT32)
- return TIME_EQUAL;
-
//regular time comparison
if (lhs < rhs)
return TIME_RIGHT_NEWER;
diff --git a/lib/custom_grid.cpp b/lib/custom_grid.cpp
index 6da8b275..97db1676 100644
--- a/lib/custom_grid.cpp
+++ b/lib/custom_grid.cpp
@@ -1375,15 +1375,15 @@ void CustomGridRim::setTooltip(const wxMouseEvent& event)
virtual void visit(const FileMapping& fileObj)
{
- tipMsg_ = toWx(fileObj.getRelativeName<side>()) + "\n" +
- _("Size") + ": " + zen::filesizeToShortString(fileObj.getFileSize<side>()) + "\n" +
- _("Date") + ": " + zen::utcToLocalTimeString(fileObj.getLastWriteTime<side>());
+ tipMsg_ = copyStringTo<wxString>(std::wstring() + fileObj.getRelativeName<side>() + L"\n" +
+ _("Size") + L": " + zen::filesizeToShortString(fileObj.getFileSize<side>()) + L"\n" +
+ _("Date") + L": " + zen::utcToLocalTimeString(fileObj.getLastWriteTime<side>()));
}
virtual void visit(const SymLinkMapping& linkObj)
{
- tipMsg_ = toWx(linkObj.getRelativeName<side>()) + "\n" +
- _("Date") + ": " + zen::utcToLocalTimeString(linkObj.getLastWriteTime<side>());
+ tipMsg_ = copyStringTo<wxString>(std::wstring() + linkObj.getRelativeName<side>() + L"\n" +
+ _("Date") + L": " + zen::utcToLocalTimeString(linkObj.getLastWriteTime<side>()));
}
virtual void visit(const DirMapping& dirObj)
diff --git a/lib/db_file.cpp b/lib/db_file.cpp
index 757a95d7..faee4c8a 100644
--- a/lib/db_file.cpp
+++ b/lib/db_file.cpp
@@ -63,7 +63,7 @@ public:
Read(formatDescr, sizeof(formatDescr)); //throw FileError
if (!std::equal(FILE_FORMAT_DESCR, FILE_FORMAT_DESCR + sizeof(FILE_FORMAT_DESCR), formatDescr))
- throw FileError(_("Incompatible synchronization database format:") + " \n" + "\"" + filename + "\"");
+ throw FileError(_("Incompatible synchronization database format:") + L" \n" + L"\"" + filename + L"\"");
}
private:
@@ -89,7 +89,7 @@ private:
class ReadDirInfo : public zen::ReadInputStream
{
public:
- ReadDirInfo(wxInputStream& stream, const wxString& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName)
+ ReadDirInfo(wxInputStream& stream, const Zstring& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName)
{
//|-------------------------------------------------------------------------------------
//| ensure 32/64 bit portability: use fixed size data types only e.g. boost::uint32_t |
@@ -163,7 +163,7 @@ typedef std::map<UniqueId, MemoryStreamPtr> StreamMapping; //list of streams
class ReadFileStream : public zen::ReadInputStream
{
public:
- ReadFileStream(wxInputStream& stream, const wxString& filename, StreamMapping& streamList) : ReadInputStream(stream, filename)
+ ReadFileStream(wxInputStream& stream, const Zstring& filename, StreamMapping& streamList) : ReadInputStream(stream, filename)
{
//|-------------------------------------------------------------------------------------
//| ensure 32/64 bit portability: used fixed size data types only e.g. boost::uint32_t |
@@ -172,7 +172,7 @@ public:
std::int32_t version = readNumberC<std::int32_t>();
if (version != FILE_FORMAT_VER) //read file format version
- throw FileError(_("Incompatible synchronization database format:") + " \n" + "\"" + filename.c_str() + "\"");
+ throw FileError(_("Incompatible synchronization database format:") + L" \n" + L"\"" + filename + L"\"");
streamList.clear();
@@ -195,9 +195,9 @@ namespace
StreamMapping loadStreams(const Zstring& filename) //throw FileError
{
if (!zen::fileExists(filename))
- throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + " \n\n" +
- _("One of the FreeFileSync database files is not yet existing:") + " \n" +
- "\"" + filename + "\"");
+ throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n\n" +
+ _("One of the FreeFileSync database files is not yet existing:") + L" \n" +
+ L"\"" + filename + L"\"");
try
{
@@ -207,12 +207,12 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError
wxZlibInputStream input(uncompressed, wxZLIB_ZLIB);
StreamMapping streamList;
- ReadFileStream(input, toWx(filename), streamList);
+ ReadFileStream(input, filename, streamList);
return streamList;
}
catch (const std::bad_alloc&) //this is most likely caused by a corrupted database file
{
- throw FileError(_("Error reading from synchronization database:") + " (bad_alloc)");
+ throw FileError(_("Error reading from synchronization database:") + L" (bad_alloc)");
}
}
@@ -224,12 +224,12 @@ DirInfoPtr parseStream(const std::vector<char>& stream, const Zstring& fileName)
//read streams into DirInfo
auto dirInfo = std::make_shared<DirInformation>();
wxMemoryInputStream buffer(&stream[0], stream.size()); //convert char-array to inputstream: no copying, ownership not transferred
- ReadDirInfo(buffer, toWx(fileName), *dirInfo); //throw FileError
+ ReadDirInfo(buffer, fileName, *dirInfo); //throw FileError
return dirInfo;
}
catch (const std::bad_alloc&) //this is most likely caused by a corrupted database file
{
- throw FileError(_("Error reading from synchronization database:") + " (bad_alloc)");
+ throw FileError(_("Error reading from synchronization database:") + L" (bad_alloc)");
}
}
}
@@ -262,10 +262,10 @@ std::pair<DirInfoPtr, DirInfoPtr> zen::loadFromDisk(const BaseDirMapping& baseMa
streamRight == streamListRight.end() ||
!streamLeft ->second.get() ||
!streamRight->second.get())
- throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + " \n\n" +
- _("Database files do not share a common synchronization session:") + " \n" +
- "\"" + fileNameLeft + "\"\n" +
- "\"" + fileNameRight + "\"");
+ throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n\n" +
+ _("Database files do not share a common synchronization session:") + L" \n" +
+ L"\"" + fileNameLeft + L"\"\n" +
+ L"\"" + fileNameRight + L"\"");
//read streams into DirInfo
DirInfoPtr dirInfoLeft = parseStream(*streamLeft ->second, fileNameLeft); //throw FileError
DirInfoPtr dirInfoRight = parseStream(*streamRight->second, fileNameRight); //throw FileError
@@ -279,7 +279,7 @@ template <SelectedSide side>
class SaveDirInfo : public WriteOutputStream
{
public:
- SaveDirInfo(const BaseDirMapping& baseMapping, const DirContainer* oldDirInfo, const wxString& errorObjName, wxOutputStream& stream) : WriteOutputStream(errorObjName, stream)
+ SaveDirInfo(const BaseDirMapping& baseMapping, const DirContainer* oldDirInfo, const Zstring& errorObjName, wxOutputStream& stream) : WriteOutputStream(errorObjName, stream)
{
//save filter settings
baseMapping.getFilter()->saveFilter(getStream());
@@ -422,7 +422,7 @@ private:
class WriteFileStream : public WriteOutputStream
{
public:
- WriteFileStream(const StreamMapping& streamList, const wxString& filename, wxOutputStream& stream) : WriteOutputStream(filename, stream)
+ WriteFileStream(const StreamMapping& streamList, const Zstring& filename, wxOutputStream& stream) : WriteOutputStream(filename, stream)
{
//save file format version
writeNumberC<std::int32_t>(FILE_FORMAT_VER);
@@ -456,7 +456,7 @@ void saveFile(const StreamMapping& streamList, const Zstring& filename) //throw
6 1,77 MB - 613 ms
9 (maximal compression) 1,74 MB - 3330 ms */
- WriteFileStream(streamList, toWx(filename), output);
+ WriteFileStream(streamList, filename, output);
}
//(try to) hide database file
#ifdef FFS_WIN
@@ -542,7 +542,7 @@ void zen::saveToDisk(const BaseDirMapping& baseMapping) //throw FileError
{
wxMemoryOutputStream buffer;
const DirContainer* oldDir = oldDirInfoLeft.get() ? &oldDirInfoLeft->baseDirContainer : NULL;
- SaveDirInfo<LEFT_SIDE>(baseMapping, oldDir, toWx(dbNameLeft), buffer);
+ SaveDirInfo<LEFT_SIDE>(baseMapping, oldDir, dbNameLeft, buffer);
newStreamLeft->resize(buffer.GetSize()); //convert output stream to char-array
buffer.CopyTo(&(*newStreamLeft)[0], buffer.GetSize()); //
}
@@ -551,7 +551,7 @@ void zen::saveToDisk(const BaseDirMapping& baseMapping) //throw FileError
{
wxMemoryOutputStream buffer;
const DirContainer* oldDir = oldDirInfoRight.get() ? &oldDirInfoRight->baseDirContainer : NULL;
- SaveDirInfo<RIGHT_SIDE>(baseMapping, oldDir, toWx(dbNameRight), buffer);
+ SaveDirInfo<RIGHT_SIDE>(baseMapping, oldDir, dbNameRight, buffer);
newStreamRight->resize(buffer.GetSize()); //convert output stream to char-array
buffer.CopyTo(&(*newStreamRight)[0], buffer.GetSize()); //
}
diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp
index 29c7ffc6..735fd7b6 100644
--- a/lib/dir_lock.cpp
+++ b/lib/dir_lock.cpp
@@ -5,7 +5,6 @@
#include <wx/log.h>
#include <wx/msgdlg.h>
#include <memory>
-#include <boost/weak_ptr.hpp>
#include <wx+/string_conv.h>
#include <zen/last_error.h>
#include <zen/thread.h> //includes <boost/thread.hpp>
@@ -63,7 +62,7 @@ public:
}
catch (const std::exception& e) //exceptions must be catched per thread
{
- wxSafeShowMessage(wxString(_("An exception occurred!")) + wxT("(Dirlock)"), wxString::FromAscii(e.what())); //simple wxMessageBox won't do for threads
+ wxSafeShowMessage(wxString(_("An exception occurred!")) + wxT("(Dirlock)"), utf8CvrtTo<wxString>(e.what())); //simple wxMessageBox won't do for threads
}
}
@@ -127,7 +126,7 @@ UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExist
{
const DWORD lastError = ::GetLastError();
- std::wstring errorMessage = _("Error reading file attributes:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted(lastError);
+ std::wstring errorMessage = _("Error reading file attributes:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted(lastError);
if (lastError == ERROR_FILE_NOT_FOUND ||
lastError == ERROR_PATH_NOT_FOUND ||
@@ -148,7 +147,7 @@ UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExist
{
const int lastError = errno;
- std::wstring errorMessage = _("Error reading file attributes:") + "\n\"" + filename + "\"" + "\n\n" + getLastErrorFormatted(lastError);
+ std::wstring errorMessage = _("Error reading file attributes:") + L"\n\"" + filename + L"\"" + L"\n\n" + getLastErrorFormatted(lastError);
if (lastError == ENOENT)
throw ErrorNotExisting(errorMessage);
@@ -201,9 +200,9 @@ std::string getComputerId() //returns empty string on error
const wxString fhn = ::wxGetFullHostName();
if (fhn.empty()) return std::string();
#ifdef FFS_WIN
- return "Windows " + std::string(fhn.ToUTF8());
+ return "Windows " + utf8CvrtTo<std::string>(fhn);
#elif defined FFS_LINUX
- return "Linux " + std::string(fhn.ToUTF8());
+ return "Linux " + utf8CvrtTo<std::string>(fhn);
#endif
}
@@ -342,7 +341,7 @@ std::string retrieveLockId(const Zstring& lockfilename) //throw FileError, Error
void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //throw FileError
{
std::wstring infoMsg = _("Waiting while directory is locked (%x)...");
- replace(infoMsg, L"%x", std::wstring(L"\"") + lockfilename + "\"");
+ replace(infoMsg, L"%x", std::wstring(L"\"") + lockfilename + L"\"");
if (callback)
callback->reportInfo(infoMsg);
//---------------------------------------------------------------
@@ -411,7 +410,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
std::wstring remSecMsg = _P("1 sec", "%x sec", remainingSeconds);
replace(remSecMsg, L"%x", toString<std::wstring>(remainingSeconds));
- callback->reportInfo(infoMsg + " " + remSecMsg);
+ callback->reportInfo(infoMsg + L" " + remSecMsg);
}
else
callback->reportInfo(infoMsg); //emit a message in any case (might clear other one)
@@ -455,7 +454,7 @@ bool tryLock(const Zstring& lockfilename) //throw FileError
if (::GetLastError() == ERROR_FILE_EXISTS)
return false;
else
- throw FileError(_("Error setting directory lock:") + "\n\"" + lockfilename + "\"" + "\n\n" + getLastErrorFormatted());
+ throw FileError(_("Error setting directory lock:") + L"\n\"" + lockfilename + L"\"" + L"\n\n" + getLastErrorFormatted());
}
::CloseHandle(fileHandle);
@@ -468,7 +467,7 @@ bool tryLock(const Zstring& lockfilename) //throw FileError
if (errno == EEXIST)
return false;
else
- throw FileError(_("Error setting directory lock:") + "\n\"" + lockfilename + "\"" + "\n\n" + getLastErrorFormatted());
+ throw FileError(_("Error setting directory lock:") + L"\n\"" + lockfilename + L"\"" + L"\n\n" + getLastErrorFormatted());
}
::close(fileHandle);
#endif
@@ -566,8 +565,7 @@ private:
{
UuidToLockMap::const_iterator iterLock = uuidToLock.find(lockId);
return iterLock != uuidToLock.end() ?
- iterLock->second.lock() : //try to get shared_ptr; throw()
- std::shared_ptr<SharedDirLock>();
+ iterLock->second.lock() : nullptr; //try to get shared_ptr; throw()
}
typedef std::weak_ptr<SharedDirLock> SharedLock;
diff --git a/lib/dir_name.cpp b/lib/dir_name.cpp
index 010fb218..71a3e9ef 100644
--- a/lib/dir_name.cpp
+++ b/lib/dir_name.cpp
@@ -124,7 +124,7 @@ void DirectoryName<NameControl>::OnFilesDropped(FFSFileDropEvent& event)
setDirectoryName(fileName, &dirName_, &dirPicker_, dirName_, staticBox_);
else
{
- wxString parentName = beforeLast(fileName, FILE_NAME_SEPARATOR); //returns empty string if ch not found
+ wxString parentName = beforeLast(fileName, utf8CvrtTo<wxString>(FILE_NAME_SEPARATOR)); //returns empty string if ch not found
#ifdef FFS_WIN
if (endsWith(parentName, L":")) //volume name
parentName += FILE_NAME_SEPARATOR;
diff --git a/lib/error_log.cpp b/lib/error_log.cpp
index fe423479..67584dea 100644
--- a/lib/error_log.cpp
+++ b/lib/error_log.cpp
@@ -5,7 +5,7 @@
// **************************************************************************
#include "error_log.h"
-#include <wx/datetime.h>
+#include <zen/time.h>
#include <zen/i18n.h>
#include <algorithm>
@@ -16,7 +16,7 @@ void ErrorLogging::logMsg(const wxString& message, zen::MessageType type)
{
Entry newEntry;
newEntry.type = type;
- newEntry.time = wxDateTime::GetTimeNow();
+ newEntry.time = std::time(NULL);
newEntry.message = message;
messages.push_back(newEntry);
@@ -76,11 +76,11 @@ wxString ErrorLogging::formatMessage(const Entry& msg)
break;
}
- const wxString prefix = wxString(L"[") + wxDateTime(msg.time).FormatTime() + L"] " + typeName + L": ";
+ const wxString prefix = L"[" + formatTime<wxString>(FORMAT_TIME, localTime(msg.time)) + L"] " + typeName + L": ";
wxString formattedText = prefix;
- for (auto i = msg.message.begin(); i != msg.message.end(); ++i)
- if (*i == wxChar('\n'))
+ for (auto iter = msg.message.begin(); iter != msg.message.end(); )
+ if (*iter == L'\n')
{
formattedText += L'\n';
@@ -88,12 +88,14 @@ wxString ErrorLogging::formatMessage(const Entry& msg)
blanks.resize(prefix.size(), L' ');
formattedText += blanks;
- while (*++i == L'\n') //remove duplicate newlines
- ;
- --i;
+ do //remove duplicate newlines
+ {
+ ++iter;
+ }
+ while (iter != msg.message.end() && *iter == L'\n');
}
else
- formattedText += *i;
+ formattedText += *iter++;
return formattedText;
}
diff --git a/lib/ffs_paths.h b/lib/ffs_paths.h
index faecd2e2..0ad02b15 100644
--- a/lib/ffs_paths.h
+++ b/lib/ffs_paths.h
@@ -9,6 +9,7 @@
#include <wx/stdpaths.h>
#include <zen/zstring.h>
+#include <zen/file_handling.h>
#include <wx+/string_conv.h>
namespace zen
@@ -16,11 +17,11 @@ namespace zen
//------------------------------------------------------------------------------
//global program directories
//------------------------------------------------------------------------------
-wxString getResourceDir(); //resource directory WITH path separator at end
-wxString getConfigDir(); //config directory WITH path separator at end
+Zstring getResourceDir(); //resource directory WITH path separator at end
+Zstring getConfigDir(); //config directory WITH path separator at end
//------------------------------------------------------------------------------
-wxString getLauncher(); //full path to application launcher C:\...\FreeFileSync.exe
+Zstring getLauncher(); //full path to application launcher C:\...\FreeFileSync.exe
bool isPortableVersion();
@@ -34,21 +35,22 @@ bool isPortableVersion();
+
//---------------- implementation ----------------
namespace impl
{
inline
-const wxString& getBinaryDir() //directory containing executable WITH path separator at end
+const Zstring& getBinaryDir() //directory containing executable WITH path separator at end
{
- static wxString instance = beforeLast(wxStandardPaths::Get().GetExecutablePath(), FILE_NAME_SEPARATOR) + toWx(Zstring(FILE_NAME_SEPARATOR)); //extern linkage!
+ static Zstring instance = beforeLast(toZ(wxStandardPaths::Get().GetExecutablePath()), FILE_NAME_SEPARATOR) + Zstring(FILE_NAME_SEPARATOR); //extern linkage!
return instance;
}
#ifdef FFS_WIN
inline
-wxString getInstallDir() //root install directory WITH path separator at end
+Zstring getInstallDir() //root install directory WITH path separator at end
{
- return getBinaryDir().BeforeLast(FILE_NAME_SEPARATOR).BeforeLast(FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR;
+ return beforeLast(beforeLast(getBinaryDir(), FILE_NAME_SEPARATOR), FILE_NAME_SEPARATOR) + FILE_NAME_SEPARATOR;
}
#endif
}
@@ -58,25 +60,27 @@ inline
bool isPortableVersion()
{
#ifdef FFS_WIN
- static const bool isPortable = !wxFileExists(impl::getInstallDir() + wxT("uninstall.exe")); //this check is a bit lame...
+ static const bool isPortable = !fileExists(impl::getInstallDir() + L"uninstall.exe"); //this check is a bit lame...
+
#elif defined FFS_LINUX
- static const bool isPortable = !impl::getBinaryDir().EndsWith(wxT("/bin/")); //this check is a bit lame...
+ static const bool isPortable = !endsWith(impl::getBinaryDir(), "/bin/"); //this check is a bit lame...
#endif
return isPortable;
}
inline
-wxString getResourceDir()
+Zstring getResourceDir()
{
#ifdef FFS_WIN
return impl::getInstallDir();
+
#elif defined FFS_LINUX
if (isPortableVersion())
return impl::getBinaryDir();
else //use OS' standard paths
{
- wxString resourceDir = wxStandardPathsBase::Get().GetResourcesDir();
+ Zstring resourceDir = toZ(wxStandardPathsBase::Get().GetResourcesDir());
if (!endsWith(resourceDir, FILE_NAME_SEPARATOR))
resourceDir += FILE_NAME_SEPARATOR;
@@ -88,7 +92,7 @@ wxString getResourceDir()
inline
-wxString getConfigDir()
+Zstring getConfigDir()
{
if (isPortableVersion())
#ifdef FFS_WIN
@@ -100,10 +104,14 @@ wxString getConfigDir()
#endif
else //use OS' standard paths
{
- wxString userDirectory = wxStandardPathsBase::Get().GetUserDataDir();
+ Zstring userDirectory = toZ(wxStandardPathsBase::Get().GetUserDataDir());
- if (!wxDirExists(userDirectory))
- ::wxMkdir(userDirectory); //only top directory needs to be created: no recursion necessary
+ if (!dirExists(userDirectory))
+ try
+ {
+ createDirectory(userDirectory); //only top directory needs to be created: no recursion necessary
+ }
+ catch (const FileError&) {}
if (!endsWith(userDirectory, FILE_NAME_SEPARATOR))
userDirectory += FILE_NAME_SEPARATOR;
@@ -114,12 +122,12 @@ wxString getConfigDir()
inline
-wxString getLauncher()
+Zstring getLauncher()
{
#ifdef FFS_WIN
- return impl::getInstallDir() + wxT("FreeFileSync.exe");
+ return impl::getInstallDir() + Zstr("FreeFileSync.exe");
#elif defined FFS_LINUX
- return impl::getBinaryDir() + wxT("FreeFileSync");
+ return impl::getBinaryDir() + Zstr("FreeFileSync");
#endif
}
}
diff --git a/lib/help_provider.h b/lib/help_provider.h
index 9baf9303..094084b2 100644
--- a/lib/help_provider.h
+++ b/lib/help_provider.h
@@ -35,7 +35,7 @@ wxHelpController& getHelpCtrl()
if (!initialized)
{
initialized = true;
- controller.Initialize(zen::getResourceDir() +
+ controller.Initialize(toWx(zen::getResourceDir()) +
#ifdef FFS_WIN
L"FreeFileSync.chm");
#elif defined FFS_LINUX
diff --git a/lib/icon_buffer.cpp b/lib/icon_buffer.cpp
index bb75a538..4e05e642 100644
--- a/lib/icon_buffer.cpp
+++ b/lib/icon_buffer.cpp
@@ -12,7 +12,6 @@
#include <boost/thread/once.hpp>
#ifdef FFS_WIN
-#include <zen/win.h> //includes "windows.h"
#include <zen/dll.h>
#include "Thumbnail/thumbnail.h"
#include <zen/win_ver.h>
@@ -26,22 +25,24 @@
using namespace zen;
+namespace
+{
const size_t BUFFER_SIZE_MAX = 800; //maximum number of icons to buffer
-int zen::IconBuffer::cvrtSize(IconSize sz) //get size in pixel
+int cvrtSize(IconBuffer::IconSize sz) //get size in pixel
{
switch (sz)
{
- case SIZE_SMALL:
+ case IconBuffer::SIZE_SMALL:
#ifdef FFS_WIN
return 16;
#elif defined FFS_LINUX
return 24;
#endif
- case SIZE_MEDIUM:
+ case IconBuffer::SIZE_MEDIUM:
return 48;
- case SIZE_LARGE:
+ case IconBuffer::SIZE_LARGE:
return 128;
}
assert(false);
@@ -69,9 +70,11 @@ public:
#endif
) {}
- IconHolder& operator=(const IconHolder& other)
+ IconHolder(IconHolder&& other) : handle_(other.handle_) { other.handle_ = NULL; }
+
+ IconHolder& operator=(IconHolder other) //unifying assignment: no need for r-value reference optimization!
{
- IconHolder(other).swap(*this);
+ other.swap(*this);
return *this;
}
@@ -112,7 +115,7 @@ public:
&bmpInfo) != 0) // __out LPVOID lpvObject
{
const int maxExtent = std::max(bmpInfo.bmWidth, bmpInfo.bmHeight);
- if (maxExtent > expectedSize)
+ if (0 < expectedSize && expectedSize < maxExtent)
{
bmpInfo.bmWidth = bmpInfo.bmWidth * expectedSize / maxExtent; //scale those Vista jumbo 256x256 icons down!
bmpInfo.bmHeight = bmpInfo.bmHeight * expectedSize / maxExtent; //
@@ -142,8 +145,6 @@ public:
#ifdef FFS_WIN
-namespace
-{
Zstring getFileExtension(const Zstring& filename)
{
const Zstring shortName = afterLast(filename, Zchar('\\')); //warning: using windows file name separator!
@@ -175,17 +176,11 @@ bool isCheapExtension(const Zstring& extension)
}
-bool wereVistaOrLater = false;
-boost::once_flag initVistaFlagOnce = BOOST_ONCE_INIT;
+const bool wereVistaOrLater = vistaOrLater(); //thread-safety: init at startup
int getShilIconType(IconBuffer::IconSize sz)
{
- boost::call_once(initVistaFlagOnce, []()
- {
- wereVistaOrLater = vistaOrLater();
- });
-
switch (sz)
{
case IconBuffer::SIZE_SMALL:
@@ -234,8 +229,8 @@ IconHolder getAssociatedIconByExt(const Zstring& extension, IconBuffer::IconSize
DllFun<thumb::GetThumbnailFct> getThumbnailIcon;
boost::once_flag initThumbnailOnce = BOOST_ONCE_INIT;
-}
#endif
+}
//################################################################################################################################################
@@ -265,6 +260,51 @@ IconHolder getThumbnail(const Zstring& filename, int requestedSize) //return 0 o
}
+const char* mimeFileIcons[] =
+{
+ "application-x-zerosize", //Kubuntu: /usr/share/icons/oxygen/48x48/mimetypes
+ "empty", //
+ "gtk-file", //Ubuntu: /usr/share/icons/Humanity/mimes/48
+ "gnome-fs-regular", //
+};
+
+
+IconHolder getGenericFileIcon(IconBuffer::IconSize sz)
+{
+#ifdef FFS_WIN
+ return getIconByAttribute(L"dummy", FILE_ATTRIBUTE_NORMAL, sz);
+
+#elif defined FFS_LINUX
+ const int requestedSize = cvrtSize(sz);
+ try
+ {
+ Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default();
+ if (iconTheme)
+ {
+ Glib::RefPtr<Gdk::Pixbuf> iconPixbuf;
+ std::find_if(mimeFileIcons, mimeFileIcons + sizeof(mimeFileIcons) / sizeof(mimeFileIcons[0]),
+ [&](const char* mimeName) -> bool
+ {
+ try
+ {
+ iconPixbuf = iconTheme->load_icon(mimeName, requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN);
+ }
+ catch (const Glib::Error&) { return false; }
+
+ return iconPixbuf;
+ }
+ );
+ if (iconPixbuf)
+ return IconHolder(iconPixbuf->gobj_copy()); // transfer ownership!!
+ }
+ }
+ catch (const Glib::Error&) {}
+
+ return IconHolder();
+#endif
+}
+
+
IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
{
//1. try to load thumbnails
@@ -275,7 +315,7 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
case IconBuffer::SIZE_MEDIUM:
case IconBuffer::SIZE_LARGE:
{
- IconHolder ico = getThumbnail(filename, IconBuffer::cvrtSize(sz));
+ IconHolder ico = getThumbnail(filename, cvrtSize(sz));
if (ico)
return ico;
//else: fallback to non-thumbnail icon
@@ -314,7 +354,7 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
return getIconByIndex ? static_cast<HICON>(getIconByIndex(fileInfo.iIcon, getShilIconType(sz))) : NULL;
#elif defined FFS_LINUX
- const int requestedSize = IconBuffer::cvrtSize(sz);
+ const int requestedSize = cvrtSize(sz);
//call Gtk::Main::init_gtkmm_internals() on application startup!!
try
{
@@ -341,27 +381,23 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
}
catch (const Glib::Error&) {}
- try //fallback: icon lookup may fail because some icons are currently not present on system
- {
- Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default();
- if (iconTheme)
- {
- Glib::RefPtr<Gdk::Pixbuf> iconPixbuf = iconTheme->load_icon("misc", requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN);
- if (!iconPixbuf)
- iconPixbuf = iconTheme->load_icon("text-x-generic", requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN);
- if (iconPixbuf)
- return IconHolder(iconPixbuf->gobj_copy()); //copy and pass icon ownership (may be 0)
- }
- }
- catch (const Glib::Error&) {}
-
- //fallback fallback
- return IconHolder();
+ //fallback: icon lookup may fail because some icons are currently not present on system
+ return ::getGenericFileIcon(sz);
#endif
}
+/* Dependency Diagram:
-IconHolder getDirectoryIcon(IconBuffer::IconSize sz)
+getGenericFileIcon()
+ /|\
+ |
+getAssociatedIcon()
+ /|\
+ |
+getGenericDirectoryIcon()
+*/
+
+IconHolder getGenericDirectoryIcon(IconBuffer::IconSize sz)
{
#ifdef FFS_WIN
return getIconByAttribute(L"dummy", //Windows 7 doesn't like this parameter to be an empty string!
@@ -372,29 +408,6 @@ IconHolder getDirectoryIcon(IconBuffer::IconSize sz)
}
-IconHolder getFileIcon(IconBuffer::IconSize sz)
-{
-#ifdef FFS_WIN
- return getIconByAttribute(L"dummy", FILE_ATTRIBUTE_NORMAL, sz);
-#elif defined FFS_LINUX
- const int requestedSize = IconBuffer::cvrtSize(sz);
- try
- {
- Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default();
- if (iconTheme)
- {
- Glib::RefPtr<Gdk::Pixbuf> iconPixbuf = iconTheme->load_icon("misc", requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN);
- if (!iconPixbuf)
- iconPixbuf = iconTheme->load_icon("text-x-generic", requestedSize, Gtk::ICON_LOOKUP_USE_BUILTIN);
- if (iconPixbuf)
- return IconHolder(iconPixbuf->gobj_copy()); // transfer ownership!!
- }
- }
- catch (const Glib::Error&) {}
-
- return IconHolder();
-#endif
-}
//################################################################################################################################################
@@ -546,8 +559,8 @@ struct IconBuffer::Pimpl
IconBuffer::IconBuffer(IconSize sz) :
pimpl(new Pimpl),
icoSize(sz),
- genDirIcon(::getDirectoryIcon(sz).toWxIcon(cvrtSize(icoSize))),
- genFileIcon(::getFileIcon(sz).toWxIcon(cvrtSize(icoSize)))
+ genDirIcon(::getGenericDirectoryIcon(sz).toWxIcon(cvrtSize(icoSize))),
+ genFileIcon(::getGenericFileIcon(sz).toWxIcon(cvrtSize(icoSize)))
{
pimpl->worker = boost::thread(WorkerThread(pimpl->workload, pimpl->buffer, sz));
}
@@ -561,6 +574,12 @@ IconBuffer::~IconBuffer()
}
+int IconBuffer::getSize() const
+{
+ return cvrtSize(icoSize);
+}
+
+
bool IconBuffer::requestFileIcon(const Zstring& filename, wxIcon* icon)
{
auto getIcon = [&](const Zstring& entryName) -> bool
diff --git a/lib/icon_buffer.h b/lib/icon_buffer.h
index be8a02d8..a13ad3cd 100644
--- a/lib/icon_buffer.h
+++ b/lib/icon_buffer.h
@@ -27,16 +27,14 @@ public:
IconBuffer(IconSize sz);
~IconBuffer();
- int getSize() const { return cvrtSize(icoSize); } //*maximum* icon size in pixel
-
- const wxIcon& genericDirIcon () { return genDirIcon; }
const wxIcon& genericFileIcon() { return genFileIcon; }
+ const wxIcon& genericDirIcon () { return genDirIcon; }
+
+ int getSize() const; //*maximum* icon size in pixel
bool requestFileIcon(const Zstring& filename, wxIcon* icon = NULL); //returns false if icon is not in buffer
void setWorkload(const std::vector<Zstring>& load); //(re-)set new workload of icons to be retrieved;
- static int cvrtSize(IconSize sz);
-
private:
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
diff --git a/lib/localization.cpp b/lib/localization.cpp
index 774ee9ec..e8ff6040 100644
--- a/lib/localization.cpp
+++ b/lib/localization.cpp
@@ -132,7 +132,7 @@ public:
}
virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {}
- virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName) { return Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); }
+ virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName) { return nullptr; }
virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } //errors are not really critical in this context
private:
@@ -180,7 +180,7 @@ ExistingTranslations::ExistingTranslations()
std::vector<Zstring> lngFiles;
FindLngfiles traverseCallback(lngFiles);
- traverseFolder(toZ(zen::getResourceDir() + wxT("Languages")), //throw();
+ traverseFolder(zen::getResourceDir() + Zstr("Languages"), //throw();
false, //don't follow symlinks
traverseCallback);
@@ -193,6 +193,10 @@ ExistingTranslations::ExistingTranslations()
lngfile::TransHeader lngHeader;
lngfile::parseHeader(stream, lngHeader); //throw ParsingError
+ /*
+ There is some buggy behavior in wxWidgets which maps "zh_TW" to simplified chinese.
+ Fortunately locales can be also entered as description. I changed to "Chinese (Traditional)" which works fine.
+ */
const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName));
if (locInfo)
{
@@ -374,10 +378,11 @@ void zen::setLanguage(int language)
{
//(try to) retrieve language file
wxString languageFile;
- for (std::vector<ExistingTranslations::Entry>::const_iterator i = ExistingTranslations::get().begin(); i != ExistingTranslations::get().end(); ++i)
- if (i->languageID == language)
+
+ for (auto iter = ExistingTranslations::get().begin(); iter != ExistingTranslations::get().end(); ++iter)
+ if (iter->languageID == language)
{
- languageFile = i->languageFile;
+ languageFile = iter->languageFile;
break;
}
diff --git a/lib/lock_holder.h b/lib/lock_holder.h
index a7cf3436..d94b0fd6 100644
--- a/lib/lock_holder.h
+++ b/lib/lock_holder.h
@@ -45,7 +45,7 @@ public:
catch (const FileError& e)
{
bool dummy = false; //this warning shall not be shown but logged only
- procCallback.reportWarning(e.msg(), dummy); //may throw!
+ procCallback.reportWarning(e.toString(), dummy); //may throw!
}
}
diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp
index 29d87ee7..96b167b8 100644
--- a/lib/parallel_scan.cpp
+++ b/lib/parallel_scan.cpp
@@ -171,7 +171,7 @@ std::vector<std::set<DirectoryKey>> separateByDistinctDisk(const std::set<Direct
typedef Zbase<wchar_t, StorageRefCountThreadSafe> BasicWString; //thread safe string class for UI texts
-class AsyncCallback
+class AsyncCallback //actor pattern
{
public:
AsyncCallback() :
@@ -207,7 +207,7 @@ public:
boost::lock_guard<boost::mutex> dummy(lockErrorMsg);
if (!errorMsg.empty() && !errorResponse.get())
{
- FillBufferCallback::HandleError rv = callback.reportError(cvrtString<std::wstring>(errorMsg)); //throw!
+ FillBufferCallback::HandleError rv = callback.reportError(copyStringTo<std::wstring>(errorMsg)); //throw!
errorResponse.reset(new FillBufferCallback::HandleError(rv));
//dummy.unlock();
@@ -244,12 +244,12 @@ public:
if (!currentFile.empty())
filename = utf8CvrtTo<std::wstring>(currentFile);
else if (!currentStatus.empty())
- statusMsg = cvrtString<std::wstring>(currentStatus);
+ statusMsg = copyStringTo<std::wstring>(currentStatus);
}
if (!filename.empty())
{
- std::wstring statusText = cvrtString<std::wstring>(textScanning);
+ std::wstring statusText = copyStringTo<std::wstring>(textScanning);
const long activeCount = activeWorker;
if (activeCount >= 2)
{
@@ -293,8 +293,6 @@ private:
};
//-------------------------------------------------------------------------------------------------
-class DirCallback;
-
struct TraverserShared
{
public:
@@ -309,9 +307,6 @@ public:
acb_(acb),
threadID_(threadID) {}
- typedef std::shared_ptr<DirCallback> CallbackPointer;
- std::vector<CallbackPointer> callBackBox; //collection of callback pointers to handle ownership
-
const SymLinkHandling handleSymlinks_;
const HardFilter::FilterRef filterInstance; //always bound!
@@ -332,10 +327,11 @@ public:
relNameParentPf_(relNameParentPf),
output_(output) {}
- virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details);
- virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details);
- virtual ReturnValDir onDir (const Zchar* shortName, const Zstring& fullName);
- virtual HandleError onError (const std::wstring& errorText);
+ virtual std::shared_ptr<TraverseCallback>
+ onDir (const Zchar* shortName, const Zstring& fullName);
+ virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details);
+ virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details);
+ virtual HandleError onError (const std::wstring& errorText);
private:
TraverserShared& cfg;
@@ -405,7 +401,7 @@ void DirCallback::onSymlink(const Zchar* shortName, const Zstring& fullName, con
}
-TraverseCallback::ReturnValDir DirCallback::onDir(const Zchar* shortName, const Zstring& fullName)
+std::shared_ptr<TraverseCallback> DirCallback::onDir(const Zchar* shortName, const Zstring& fullName)
{
boost::this_thread::interruption_point();
@@ -419,16 +415,14 @@ TraverseCallback::ReturnValDir DirCallback::onDir(const Zchar* shortName, const
bool subObjMightMatch = true;
const bool passFilter = cfg.filterInstance->passDirFilter(relName, &subObjMightMatch);
if (!passFilter && !subObjMightMatch)
- return Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); //do NOT traverse subdirs
+ return nullptr; //do NOT traverse subdirs
//else: attention! ensure directory filtering is applied later to exclude actually filtered directories
DirContainer& subDir = output_.addSubDir(shortName);
if (passFilter)
cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator
- TraverserShared::CallbackPointer subDirCallback = std::make_shared<DirCallback>(cfg, relName + FILE_NAME_SEPARATOR, subDir);
- cfg.callBackBox.push_back(subDirCallback); //handle lifetime
- return ReturnValDir(Int2Type<ReturnValDir::TRAVERSING_DIR_CONTINUE>(), *subDirCallback);
+ return std::make_shared<DirCallback>(cfg, relName + FILE_NAME_SEPARATOR, subDir);
}
diff --git a/lib/parse_plural.h b/lib/parse_plural.h
index 847bec35..960172fa 100644
--- a/lib/parse_plural.h
+++ b/lib/parse_plural.h
@@ -112,7 +112,7 @@ struct NumberN : public Expr<int>
};
-typedef Zbase<char> Wstring;
+typedef zen::Zbase<char> Wstring;
class PluralForm
diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp
index 777c3ed6..78e14ff5 100644
--- a/lib/process_xml.cpp
+++ b/lib/process_xml.cpp
@@ -74,7 +74,7 @@ void setXmlType(XmlDoc& doc, XmlType type) //throw()
wxString xmlAccess::getGlobalConfigFile()
{
- return zen::getConfigDir() + wxT("GlobalSettings.xml");
+ return toWx(zen::getConfigDir()) + wxT("GlobalSettings.xml");
}
@@ -810,6 +810,7 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config)
inShared["CopyFilePermissions" ](config.copyFilePermissions);
inShared["TransactionalFileCopy"](config.transactionalFileCopy);
inShared["VerifyCopiedFiles" ](config.verifyFileCopy);
+ inShared["RunWithBackgroundPriority"](config.runWithBackgroundPriority);
//max. allowed file time deviation
inShared["FileTimeTolerance"](config.fileTimeTolerance);
@@ -888,13 +889,13 @@ void readConfig(const Zstring& filename, XmlType type, ConfigType& config)
loadXmlDocument(filename, doc); //throw FfsXmlError
if (getXmlType(doc) != type) //throw()
- throw FfsXmlError(_("Error parsing configuration file:") + "\n\"" + filename + "\"");
+ throw FfsXmlError(_("Error parsing configuration file:") + L"\n\"" + filename + L"\"");
XmlIn in(doc);
::readConfig(in, config);
if (in.errorsOccured())
- throw FfsXmlError(_("Error parsing configuration file:") + "\n\"" + filename + "\"\n\n" +
+ throw FfsXmlError(_("Error parsing configuration file:") + L"\n\"" + filename + L"\"\n\n" +
getErrorMessageFormatted(in), FfsXmlError::WARNING);
}
}
@@ -1067,6 +1068,7 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out)
outShared["CopyFilePermissions" ](config.copyFilePermissions);
outShared["TransactionalFileCopy"](config.transactionalFileCopy);
outShared["VerifyCopiedFiles" ](config.verifyFileCopy);
+ outShared["RunWithBackgroundPriority"](config.runWithBackgroundPriority);
//max. allowed file time deviation
outShared["FileTimeTolerance"](config.fileTimeTolerance);
diff --git a/lib/process_xml.h b/lib/process_xml.h
index 5f1dfb93..7f8b273b 100644
--- a/lib/process_xml.h
+++ b/lib/process_xml.h
@@ -142,6 +142,7 @@ struct XmlGlobalSettings
programLanguage(zen::retrieveSystemLanguage()),
copyLockedFiles(true),
copyFilePermissions(false),
+ runWithBackgroundPriority(false),
fileTimeTolerance(2), //default 2s: FAT vs NTFS
verifyFileCopy(false),
transactionalFileCopy(true) {}
@@ -150,6 +151,8 @@ struct XmlGlobalSettings
bool copyLockedFiles; //VSS usage
bool copyFilePermissions;
+ bool runWithBackgroundPriority;
+
size_t fileTimeTolerance; //max. allowed file time deviation
bool verifyFileCopy; //verify copied files
bool transactionalFileCopy;
@@ -174,7 +177,7 @@ struct XmlGlobalSettings
#elif defined FFS_LINUX
textSearchRespectCase(true),
#endif
- iconSize(ICON_SIZE_MEDIUM),
+ iconSize(ICON_SIZE_SMALL),
lastUpdateCheck(0)
{
//default external apps will be translated "on the fly"!!!
diff --git a/lib/recycler.cpp b/lib/recycler.cpp
index 30083701..abe63a3e 100644
--- a/lib/recycler.cpp
+++ b/lib/recycler.cpp
@@ -65,8 +65,8 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F
const DllFun<GetLastErrorFct> getLastError (getDllName(), getLastErrorFctName);
if (!moveToRecycler || !getLastError)
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + fileNames[0] + "\"" + //report first file only... better than nothing
- "\n\n" + _("Could not load a required DLL:") + " \"" + getDllName() + "\"");
+ throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + fileNames[0] + L"\"" + //report first file only... better than nothing
+ L"\n\n" + _("Could not load a required DLL:") + L" \"" + getDllName() + L"\"");
//#warning moving long file paths to recycler does not work! clarify!
// std::vector<Zstring> temp;
@@ -78,8 +78,8 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F
{
wchar_t errorMessage[2000];
getLastError(errorMessage, 2000);
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + fileNames[0] + "\"" + //report first file only... better than nothing
- "\n\n" + "(" + errorMessage + ")");
+ throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + fileNames[0] + L"\"" + //report first file only... better than nothing
+ L"\n\n" + L"(" + errorMessage + L")");
}
}
else //regular recycle bin usage: available since XP
@@ -106,7 +106,7 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F
if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted)
{
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filenameDoubleNull + "\""); //report first file only... better than nothing
+ throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filenameDoubleNull + L"\""); //report first file only... better than nothing
}
}
}
@@ -132,8 +132,8 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError
try
{
if (!fileObj->trash())
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filename + "\"" +
- "\n\n" + "(unknown error)");
+ throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filename + L"\"" +
+ L"\n\n" + L"(unknown error)");
}
catch (const Glib::Error& errorObj)
{
@@ -152,11 +152,11 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError
}
//assemble error message
- const std::wstring errorMessage = L"Glib Error Code " + toString<std::wstring>(errorObj.code()) + /* ", " +
- g_quark_to_string(errorObj.domain()) + */ ": " + errorObj.what();
+ const std::wstring errorMessage = L"Glib Error Code " + toString<std::wstring>(errorObj.code()) + /* L", " +
+ g_quark_to_string(errorObj.domain()) + */ L": " + utf8CvrtTo<std::wstring>(errorObj.what());
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filename + "\"" +
- "\n\n" + "(" + errorMessage + ")");
+ throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filename + L"\"" +
+ L"\n\n" + L"(" + errorMessage + L")");
}
#endif
return true;
diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp
index 14ad690e..feeb98e3 100644
--- a/lib/resolve_path.cpp
+++ b/lib/resolve_path.cpp
@@ -1,6 +1,6 @@
#include "resolve_path.h"
#include <wx/utils.h>
-#include <wx/datetime.h>
+#include <zen/time.h>
#include <wx+/string_conv.h>
#include <map>
#include <set>
@@ -178,14 +178,13 @@ bool replaceMacro(wxString& macro) //macro without %-characters, return true if
//there are equally named environment variables %TIME%, %DATE% existing, so replace these first!
if (macro.CmpNoCase(wxT("time")) == 0)
{
- macro = wxDateTime::Now().FormatISOTime();
- macro.Replace(wxT(":"), wxT(""));
+ macro = formatTime<wxString>(L"%H%M%S");
return true;
}
if (macro.CmpNoCase(wxT("date")) == 0)
{
- macro = wxDateTime::Now().FormatISODate();
+ macro = formatTime<wxString>(FORMAT_ISO_DATE);
return true;
}
@@ -193,7 +192,8 @@ bool replaceMacro(wxString& macro) //macro without %-characters, return true if
{
if (macro.CmpNoCase(phrase) != 0)
return false;
- macro = wxDateTime::Now().Format(format);
+
+ macro = formatTime<wxString>(format);
return true;
};
@@ -272,10 +272,10 @@ public:
virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {}
virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {}
- virtual ReturnValDir onDir(const Zchar* shortName, const Zstring& fullName)
+ virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName)
{
devices_.insert(std::make_pair(shortName, fullName));
- return Int2Type<ReturnValDir::TRAVERSING_DIR_IGNORE>(); //DON'T traverse into subdirs
+ return nullptr; //DON'T traverse into subdirs
}
virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; }
@@ -379,18 +379,20 @@ void expandVolumeName(Zstring& text) // [volname]:\folder [volname]\folde
{
//this would be a nice job for a C++11 regex...
- size_t posStart = text.find(Zstr("["));
- if (posStart != Zstring::npos)
+
+ //we only expect the [.*] pattern at the beginning => do not touch dir names like "C:\somedir\[stuff]"
+ trim(text, true, false);
+
+ if (startsWith(text, Zstr("[")))
{
- size_t posEnd = text.find(Zstr("]"), posStart);
+ size_t posEnd = text.find(Zstr("]"));
if (posEnd != Zstring::npos)
{
- Zstring before = Zstring(text.c_str(), posStart);
- Zstring volname = Zstring(text.c_str() + posStart + 1, posEnd - posStart - 1);
+ Zstring volname = Zstring(text.c_str() + 1, posEnd - 1);
Zstring after = Zstring(text.c_str() + posEnd + 1);
- if (startsWith(after, ':'))
- after = afterFirst(after, ':');
+ if (startsWith(after, Zstr(':')))
+ after = afterFirst(after, Zstr(':'));
if (startsWith(after, FILE_NAME_SEPARATOR))
after = afterFirst(after, FILE_NAME_SEPARATOR);
@@ -403,7 +405,7 @@ void expandVolumeName(Zstring& text) // [volname]:\folder [volname]\folde
if (!endsWith(volPath, FILE_NAME_SEPARATOR))
volPath += FILE_NAME_SEPARATOR;
- text = before + volPath + after;
+ text = volPath + after;
//successfully replaced pattern
return;
}
diff --git a/lib/resources.cpp b/lib/resources.cpp
index da407920..01a046b1 100644
--- a/lib/resources.cpp
+++ b/lib/resources.cpp
@@ -46,7 +46,7 @@ void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation& anim)
GlobalResources::GlobalResources()
{
- wxFFileInputStream input(zen::getResourceDir() + wxT("Resources.zip"));
+ wxFFileInputStream input(toWx(zen::getResourceDir()) + wxT("Resources.zip"));
if (input.IsOk()) //if not... we don't want to react too harsh here
{
//activate support for .png files
diff --git a/lib/shadow.cpp b/lib/shadow.cpp
index 73a2e8f7..9bc17aff 100644
--- a/lib/shadow.cpp
+++ b/lib/shadow.cpp
@@ -44,33 +44,32 @@ public:
ShadowVolume(const Zstring& volumeNameFormatted) : //throw(FileError)
createShadowCopy (getDllName(), createShadowCopyFctName),
releaseShadowCopy(getDllName(), releaseShadowCopyFctName),
- backupHandle(0)
+ getShadowVolume (getDllName(), getShadowVolumeFctName),
+ backupHandle(nullptr)
{
//check if shadow copy dll was loaded correctly
- if (!createShadowCopy || !releaseShadowCopy)
- throw FileError(_("Error accessing Volume Shadow Copy Service!") + "\n" +
- _("Could not load a required DLL:") + " \"" + getDllName() + "\"");
+ if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume)
+ throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" +
+ _("Could not load a required DLL:") + L" \"" + getDllName() + L"\"");
//VSS does not support running under WOW64 except for Windows XP and Windows Server 2003
//(Reference: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx)
if (runningWOW64())
- throw FileError(_("Error accessing Volume Shadow Copy Service!") + "\n" +
+ throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" +
_("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
//---------------------------------------------------------------------------------------------------------
//start shadow volume copy service:
- wchar_t shadowVolName[1000];
wchar_t errorMessage[1000];
+ backupHandle = createShadowCopy(volumeNameFormatted.c_str(),
+ errorMessage,
+ 1000);
+ if (!backupHandle)
+ throw FileError(_("Error accessing Volume Shadow Copy Service!") + L"\n" +
+ L"(" + errorMessage + L" Volume: \"" + volumeNameFormatted + L"\")");
- if (!createShadowCopy(volumeNameFormatted.c_str(),
- shadowVolName,
- 1000,
- &backupHandle,
- errorMessage,
- 1000))
- throw FileError(_("Error accessing Volume Shadow Copy Service!") + "\n" +
- "(" + errorMessage + " Volume: \"" + volumeNameFormatted + "\")");
-
+ wchar_t shadowVolName[1000];
+ getShadowVolume(backupHandle, shadowVolName, 1000);
shadowVol = Zstring(shadowVolName) + FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash
}
@@ -79,7 +78,7 @@ public:
releaseShadowCopy(backupHandle); //fast! no performance optimization necessary
}
- Zstring getShadowVolume() const //trailing path separator
+ Zstring getShadowVolumeName() const //trailing path separator
{
return shadowVol;
}
@@ -90,6 +89,7 @@ private:
const DllFun<CreateShadowCopyFct> createShadowCopy;
const DllFun<ReleaseShadowCopyFct> releaseShadowCopy;
+ const DllFun<GetShadowVolumeFct> getShadowVolume;
Zstring shadowVol;
@@ -105,7 +105,7 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName,
volumeNameRaw, //__out LPTSTR lpszVolumePathName,
1000)) //__in DWORD cchBufferLength
- throw FileError(_("Could not determine volume name for file:") + "\n\"" + inputFile + "\"");
+ throw FileError(_("Could not determine volume name for file:") + L"\n\"" + inputFile + L"\"");
Zstring volumeNameFormatted = volumeNameRaw;
if (!endsWith(volumeNameFormatted, FILE_NAME_SEPARATOR))
@@ -116,8 +116,8 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
if (pos == Zstring::npos)
{
std::wstring msg = _("Volume name %x not part of filename %y!");
- replace(msg, L"%x", std::wstring(L"\"") + volumeNameFormatted + "\"", false);
- replace(msg, L"%y", std::wstring(L"\"") + inputFile + "\"", false);
+ replace(msg, L"%x", std::wstring(L"\"") + volumeNameFormatted + L"\"", false);
+ replace(msg, L"%y", std::wstring(L"\"") + inputFile + L"\"", false);
throw FileError(msg);
}
@@ -130,5 +130,5 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
}
//return filename alias on shadow copy volume
- return iter->second->getShadowVolume() + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
+ return iter->second->getShadowVolumeName() + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
}
diff --git a/lib/statistics.h b/lib/statistics.h
index 8f974aae..718e4f19 100644
--- a/lib/statistics.h
+++ b/lib/statistics.h
@@ -13,11 +13,12 @@
#include <wx/defs.h>
#include <wx/string.h>
#include <wx/stopwatch.h>
+#include <zen/deprecate.h>
class RetrieveStatistics
{
public:
- wxDEPRECATED(~RetrieveStatistics()); //generate compiler warnings as a reminder to remove code after measurements
+ ZEN_DEPRECATE ~RetrieveStatistics(); //remove code after measurements!
void writeEntry(double value, int objects);
private:
diff --git a/lib/xml_base.cpp b/lib/xml_base.cpp
index b4887dc0..26176776 100644
--- a/lib/xml_base.cpp
+++ b/lib/xml_base.cpp
@@ -31,7 +31,7 @@ void xmlAccess::loadXmlDocument(const Zstring& filename, XmlDoc& doc) //throw Ff
if (!startsWith(fileBegin, xmlBegin) &&
!startsWith(fileBegin, zen::BYTE_ORDER_MARK_UTF8 + xmlBegin)) //respect BOM!
- throw FfsXmlError(_("Error parsing configuration file:") + "\n\"" + filename + "\"");
+ throw FfsXmlError(_("Error parsing configuration file:") + L"\n\"" + filename + L"\"");
}
const zen::UInt64 fs = zen::getFilesize(filename); //throw FileError
@@ -40,14 +40,14 @@ void xmlAccess::loadXmlDocument(const Zstring& filename, XmlDoc& doc) //throw Ff
FileInput inputFile(filename); //throw FileError
const size_t bytesRead = inputFile.read(&stream[0], stream.size()); //throw FileError
if (bytesRead < to<size_t>(fs))
- throw FfsXmlError(_("Error reading file:") + "\n\"" + filename + "\"");
+ throw FfsXmlError(_("Error reading file:") + L"\n\"" + filename + L"\"");
}
catch (const FileError& error)
{
if (!fileExists(filename))
- throw FfsXmlError(_("File does not exist:") + "\n\"" + filename+ "\"");
+ throw FfsXmlError(_("File does not exist:") + L"\n\"" + filename+ L"\"");
- throw FfsXmlError(error.msg());
+ throw FfsXmlError(error.toString());
}
try
@@ -56,14 +56,14 @@ void xmlAccess::loadXmlDocument(const Zstring& filename, XmlDoc& doc) //throw Ff
}
catch (const XmlParsingError&)
{
- throw FfsXmlError(_("Error parsing configuration file:") + "\n\"" + filename + "\"");
+ throw FfsXmlError(_("Error parsing configuration file:") + L"\n\"" + filename + L"\"");
}
}
const std::wstring xmlAccess::getErrorMessageFormatted(const XmlIn& in)
{
- std::wstring errorMessage = _("Could not read values for the following XML nodes:") + "\n";
+ std::wstring errorMessage = _("Could not read values for the following XML nodes:") + L"\n";
std::vector<std::wstring> failedNodes = in.getErrorsAs<std::wstring>();
std::for_each(failedNodes.begin(), failedNodes.end(),
@@ -98,6 +98,6 @@ void xmlAccess::saveXmlDocument(const zen::XmlDoc& doc, const Zstring& filename)
}
catch (const FileError& error) //more detailed error messages than with wxWidgets
{
- throw FfsXmlError(error.msg());
+ throw FfsXmlError(error.toString());
}
}
diff --git a/lib/xml_base.h b/lib/xml_base.h
index 4614615e..dc534dc5 100644
--- a/lib/xml_base.h
+++ b/lib/xml_base.h
@@ -24,9 +24,9 @@ public:
FATAL
};
- FfsXmlError(const std::wstring& message, Severity sev = FATAL) : errorMessage(message), m_severity(sev) {}
+ explicit FfsXmlError(const std::wstring& message, Severity sev = FATAL) : errorMessage(message), m_severity(sev) {}
- const std::wstring& msg() const { return errorMessage; }
+ const std::wstring& toString() const { return errorMessage; }
Severity getSeverity() const { return m_severity; }
private:
const std::wstring errorMessage;
bgstack15