summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:27:42 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:27:42 +0200
commitb916407a2a06f8452e82b74dc44c54acbcc572b0 (patch)
tree46358e0bb035fca0f42edb4b5b8aa5f1613814af /lib
parent5.20 (diff)
downloadFreeFileSync-b916407a2a06f8452e82b74dc44c54acbcc572b0.tar.gz
FreeFileSync-b916407a2a06f8452e82b74dc44c54acbcc572b0.tar.bz2
FreeFileSync-b916407a2a06f8452e82b74dc44c54acbcc572b0.zip
5.21
Diffstat (limited to 'lib')
-rw-r--r--lib/ShadowCopy/Shadow_Server2003.vcxproj239
-rw-r--r--lib/ShadowCopy/Shadow_Windows7.vcxproj20
-rw-r--r--lib/ShadowCopy/Shadow_XP.vcxproj240
-rw-r--r--lib/ShadowCopy/shadow.cpp19
-rw-r--r--lib/Thumbnail/Thumbnail.vcxproj20
-rw-r--r--lib/db_file.cpp398
-rw-r--r--lib/db_file.h22
-rw-r--r--lib/dir_exist_async.h3
-rw-r--r--lib/dir_lock.cpp2
-rw-r--r--lib/hard_filter.cpp85
-rw-r--r--lib/hard_filter.h7
-rw-r--r--lib/icon_buffer.cpp20
-rw-r--r--lib/norm_filter.h4
-rw-r--r--lib/osx_file_icon.mm2
-rw-r--r--lib/parallel_scan.cpp36
-rw-r--r--lib/parse_lng.h11
-rw-r--r--lib/process_xml.cpp245
-rw-r--r--lib/process_xml.h4
-rw-r--r--lib/resolve_path.cpp8
-rw-r--r--lib/shadow.cpp6
-rw-r--r--lib/soft_filter.h10
-rw-r--r--lib/versioning.cpp26
-rw-r--r--lib/xml_base.cpp2
23 files changed, 498 insertions, 931 deletions
diff --git a/lib/ShadowCopy/Shadow_Server2003.vcxproj b/lib/ShadowCopy/Shadow_Server2003.vcxproj
deleted file mode 100644
index a9b8f740..00000000
--- a/lib/ShadowCopy/Shadow_Server2003.vcxproj
+++ /dev/null
@@ -1,239 +0,0 @@
-<?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>Server2003</ProjectName>
- <ProjectGuid>{2F2994D6-FB89-4BAA-A5DF-03BAF7337FF2}</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>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
- <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>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(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>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
- <SmallerTypeCheck>true</SmallerTypeCheck>
- </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>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <BuildLog>
- <Path>$(IntDir)Build.html</Path>
- </BuildLog>
- <Midl>
- <TargetEnvironment>X64</TargetEnvironment>
- </Midl>
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <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>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
- <SmallerTypeCheck>true</SmallerTypeCheck>
- </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>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <BuildLog>
- <Path>$(IntDir)Build.html</Path>
- </BuildLog>
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(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>../..;C:\Program Files\C++\boost</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>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </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>
- <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(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>../..;C:\Program Files\C++\boost</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>MachineX64</TargetMachine>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\..\zen\debug_memory_leaks.cpp" />
- <ClCompile Include="shadow.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="shadow.h" />
- </ItemGroup>
- <ItemGroup>
- <Library Include="Server 2003\lib\$(Platform)\vssapi.lib" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/lib/ShadowCopy/Shadow_Windows7.vcxproj b/lib/ShadowCopy/Shadow_Windows7.vcxproj
index 7c6f1f1d..1f02e675 100644
--- a/lib/ShadowCopy/Shadow_Windows7.vcxproj
+++ b/lib/ShadowCopy/Shadow_Windows7.vcxproj
@@ -30,23 +30,23 @@
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<UseOfAtl>false</UseOfAtl>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -88,7 +88,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
+ <MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
@@ -99,6 +99,7 @@
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
<SmallerTypeCheck>true</SmallerTypeCheck>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
@@ -123,7 +124,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <MinimalRebuild>true</MinimalRebuild>
+ <MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
@@ -135,6 +136,7 @@
<AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SmallerTypeCheck>true</SmallerTypeCheck>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
@@ -168,11 +170,12 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <GenerateDebugInformation>false</GenerateDebugInformation>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -206,11 +209,12 @@
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <GenerateDebugInformation>false</GenerateDebugInformation>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
diff --git a/lib/ShadowCopy/Shadow_XP.vcxproj b/lib/ShadowCopy/Shadow_XP.vcxproj
deleted file mode 100644
index 0d54f2e4..00000000
--- a/lib/ShadowCopy/Shadow_XP.vcxproj
+++ /dev/null
@@ -1,240 +0,0 @@
-<?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>XP</ProjectName>
- <ProjectGuid>{70394AEF-5897-4911-AFA1-82EAF0581EFA}</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>
- <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>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">OBJ\$(ProjectName)_$(Configuration)_$(Platform)\</IntDir>
- <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>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
- <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
- <SmallerTypeCheck>true</SmallerTypeCheck>
- </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>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <BuildLog>
- <Path>$(IntDir)Build.html</Path>
- </BuildLog>
- <Midl>
- <TargetEnvironment>X64</TargetEnvironment>
- </Midl>
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
- <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
- <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
- <SmallerTypeCheck>true</SmallerTypeCheck>
- </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>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <BuildLog>
- <Path>$(IntDir)Build.html</Path>
- </BuildLog>
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(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>../..;C:\Program Files\C++\boost</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>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </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>
- <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(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>../..;C:\Program Files\C++\boost</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>MachineX64</TargetMachine>
- <AdditionalLibraryDirectories>C:\Program Files\C++\Boost\stage_x64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\..\zen\debug_memory_leaks.cpp" />
- <ClCompile Include="shadow.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="shadow.h" />
- </ItemGroup>
- <ItemGroup>
- <Library Include="XP\lib\$(Platform)\vssapi.lib" />
- </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 e915663f..adc7c5c2 100644
--- a/lib/ShadowCopy/shadow.cpp
+++ b/lib/ShadowCopy/shadow.cpp
@@ -89,8 +89,27 @@ shadow::ShadowData createShadowCopy(const wchar_t* volumeName) //throw SysError
}
ZEN_COM_CHECK(backupComp->InitializeForBackup()); //throw SysError
+
+ //SetContext() only required if different than the default, VSS_CTX_BACKUP; not implemented on XP!!!
+ //ZEN_COM_CHECK(backupComp->SetContext(VSS_CTX_BACKUP)); //throw SysError
+
ZEN_COM_CHECK(backupComp->SetBackupState(false, false, VSS_BT_FULL)); //throw SysError
+
+ //the Shadow Copy Optimization Writer removes items it considers non-essential,
+ //http://msdn.microsoft.com/en-US/library/bb968827#shadow_copy_optimization_writer
+ //like the exclusions in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot
+ //http://msdn.microsoft.com/en-us/library/aa819132%28v=vs.85%29.aspx
+ //Outlook *.ost files in particular:
+ //https://sourceforge.net/p/freefilesync/discussion/help/thread/722dcbfb
+ const VSS_ID disabledWriters[] = { { 0x4dc3bdd4, 0xab48, 0x4d07, { 0xad, 0xb0, 0x3b, 0xee, 0x29, 0x26, 0xfd, 0x7f } } }; //Shadow Copy Optimization Writer
+ {
+ HRESULT hr = backupComp->DisableWriterClasses(disabledWriters, 1);
+ if (FAILED(hr) && hr != E_NOTIMPL) //DisableWriterClasses() is not implemented on Windows XP, although MSDN documented otherwise!
+ throw SysError(formatComError(L"Error calling \"backupComp->DisableWriterClasses\".", hr));
+ }
+
+
auto waitForComFuture = [](IVssAsync& fut)
{
ZEN_COM_CHECK(fut.Wait());
diff --git a/lib/Thumbnail/Thumbnail.vcxproj b/lib/Thumbnail/Thumbnail.vcxproj
index 1ec016be..a4719ae7 100644
--- a/lib/Thumbnail/Thumbnail.vcxproj
+++ b/lib/Thumbnail/Thumbnail.vcxproj
@@ -28,23 +28,23 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>Windows7.1SDK</PlatformToolset>
+ <PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -86,7 +86,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;ZEN_WIN;_DEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
+ <MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
@@ -97,6 +97,7 @@
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
<SmallerTypeCheck>true</SmallerTypeCheck>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
@@ -121,7 +122,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;THUMBNAIL_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>true</MinimalRebuild>
+ <MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
@@ -132,6 +133,7 @@
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
<SmallerTypeCheck>true</SmallerTypeCheck>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
@@ -164,11 +166,12 @@
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <GenerateDebugInformation>false</GenerateDebugInformation>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@@ -201,11 +204,12 @@
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <GenerateDebugInformation>false</GenerateDebugInformation>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
diff --git a/lib/db_file.cpp b/lib/db_file.cpp
index ab7f9212..1c2a34f3 100644
--- a/lib/db_file.cpp
+++ b/lib/db_file.cpp
@@ -24,16 +24,12 @@ namespace
{
//-------------------------------------------------------------------------------------------------------------------------------
const char FILE_FORMAT_DESCR[] = "FreeFileSync";
-const int DB_FILE_FORMAT_VER = 9;
-
-warn_static("wee need two version ids!")
-//const int DB_FILE_FORMAT_CONTAINER = 10;
-//const int DB_FILE_FORMAT_STREAM = 1;
-
+const int DB_FORMAT_CONTAINER = 9;
+const int DB_FORMAT_STREAM = 1;
//-------------------------------------------------------------------------------------------------------------------------------
typedef std::string UniqueId;
-typedef std::map<UniqueId, BinaryStream> StreamMapping; //list of streams ordered by session UUID
+typedef std::map<UniqueId, BinaryStream> DbStreams; //list of streams ordered by session UUID
//-----------------------------------------------------------------------------------
//| ensure 32/64 bit portability: use fixed size data types only e.g. std::uint32_t |
@@ -58,7 +54,7 @@ Zstring getDBFilename(const BaseDirPair& baseDirObj, bool tempfile = false)
//#######################################################################################################################################
-void saveStreams(const StreamMapping& streamList, const Zstring& filename) //throw FileError
+void saveStreams(const DbStreams& streamList, const Zstring& filename) //throw FileError
{
BinStreamOut streamOut;
@@ -66,15 +62,15 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr
writeArray(streamOut, FILE_FORMAT_DESCR, sizeof(FILE_FORMAT_DESCR));
//save file format version
- writeNumber<std::int32_t>(streamOut, DB_FILE_FORMAT_VER);
+ writeNumber<std::int32_t>(streamOut, DB_FORMAT_CONTAINER);
//save stream list
writeNumber<std::uint32_t>(streamOut, static_cast<std::uint32_t>(streamList.size())); //number of streams, one for each sync-pair
- for (auto it = streamList.begin(); it != streamList.end(); ++it)
+ for (const auto& stream : streamList)
{
- writeContainer<std::string >(streamOut, it->first );
- writeContainer<BinaryStream>(streamOut, it->second);
+ writeContainer<std::string >(streamOut, stream.first );
+ writeContainer<BinaryStream>(streamOut, stream.second);
}
assert(!somethingExists(filename)); //orphan tmp files should be cleaned up already at this point!
@@ -87,7 +83,7 @@ void saveStreams(const StreamMapping& streamList, const Zstring& filename) //thr
}
-StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting
+DbStreams loadStreams(const Zstring& filename) //throw FileError, FileErrorDatabaseNotExisting
{
try
{
@@ -101,12 +97,12 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD
throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename)));
const int version = readNumber<std::int32_t>(streamIn); //throw UnexpectedEndOfStreamError
- if (version != DB_FILE_FORMAT_VER) //read file format version number
+ if (version != DB_FORMAT_CONTAINER) //read file format version number
throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filename)));
- //read stream lists
- StreamMapping output;
+ DbStreams output;
+ //read stream lists
size_t dbCount = readNumber<std::uint32_t>(streamIn); //number of streams, one for each sync-pair
while (dbCount-- != 0)
{
@@ -159,16 +155,16 @@ public:
{
/* Zlib: optimal level - testcase 1 million files
level/size [MB]/time [ms]
- 0 49.54 272 (uncompressed)
- 1 14.53 1013
- 2 14.13 1106
- 3 13.76 1288 - best compromise between speed and compression
- 4 13.20 1526
- 5 12.73 1916
- 6 12.58 2765
- 7 12.54 3633
- 8 12.51 9032
- 9 12.50 19698 (maximal compression) */
+ 0 49.54 272 (uncompressed)
+ 1 14.53 1013
+ 2 14.13 1106
+ 3 13.76 1288 - best compromise between speed and compression
+ 4 13.20 1526
+ 5 12.73 1916
+ 6 12.58 2765
+ 7 12.54 3633
+ 8 12.51 9032
+ 9 12.50 19698 (maximal compression) */
return compress(stream, 3); //throw ZlibInternalError
}
catch (ZlibInternalError&)
@@ -181,14 +177,18 @@ public:
const BinaryStream tmpR = compStream(generator.outputRight.get(), filenameR);
const BinaryStream tmpB = compStream(generator.outputBoth .get(), filenameL + Zstr("/") + filenameR);
- //distribute "outputBoth" over left and right streams:
BinStreamOut outL;
BinStreamOut outR;
- writeNumber<bool>(outL, true); //this side contains first part of "outputBoth"
- writeNumber<bool>(outR, false);
+ //save format version
+ writeNumber<std::int32_t>(outL, DB_FORMAT_STREAM);
+ writeNumber<std::int32_t>(outR, DB_FORMAT_STREAM);
+
+ //distribute "outputBoth" over left and right streams:
+ writeNumber<std::int8_t>(outL, true); //this side contains first part of "outputBoth"
+ writeNumber<std::int8_t>(outR, false);
- size_t size1stPart = tmpB.size() / 2;
- size_t size2ndPart = tmpB.size() - size1stPart;
+ const size_t size1stPart = tmpB.size() / 2;
+ const size_t size2ndPart = tmpB.size() - size1stPart;
writeNumber<std::uint64_t>(outL, size1stPart);
writeNumber<std::uint64_t>(outR, size2ndPart);
@@ -207,24 +207,42 @@ public:
private:
void recurse(const InSyncDir& container)
{
- // for (const auto& dbFile : container.files) { processFile(dbFile); }); !
-
writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.files.size()));
- std::for_each(container.files.begin(), container.files.end(), [&](const std::pair<Zstring, InSyncFile>& dbFile) { this->process(dbFile); });
+ for (const auto& dbFile : container.files)
+ {
+ writeUtf8(outputBoth, dbFile.first);
+ writeNumber<std::int32_t>(outputBoth, dbFile.second.cmpVar);
+ writeNumber<std::uint64_t>(outputBoth, to<std::uint64_t>(dbFile.second.fileSize));
+
+ writeFile(outputLeft, dbFile.second.left);
+ writeFile(outputRight, dbFile.second.right);
+ }
writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.symlinks.size()));
- std::for_each(container.symlinks.begin(), container.symlinks.end(), [&](const std::pair<Zstring, InSyncSymlink>& dbSymlink) { this->process(dbSymlink); });
+ for (const auto& dbSymlink : container.symlinks)
+ {
+ writeUtf8(outputBoth, dbSymlink.first);
+ writeNumber<std::int32_t>(outputBoth, dbSymlink.second.cmpVar);
+
+ writeLink(outputLeft, dbSymlink.second.left);
+ writeLink(outputRight, dbSymlink.second.right);
+ }
writeNumber<std::uint32_t>(outputBoth, static_cast<std::uint32_t>(container.dirs.size()));
- std::for_each(container.dirs.begin(), container.dirs.end(), [&](const std::pair<Zstring, InSyncDir>& dbDir) { this->process(dbDir); });
+ for (const auto& dbDir : container.dirs)
+ {
+ writeUtf8(outputBoth, dbDir.first);
+ writeNumber<std::int32_t>(outputBoth, dbDir.second.status);
+
+ recurse(dbDir.second);
+ }
}
static void writeUtf8(BinStreamOut& output, const Zstring& str) { writeContainer(output, utfCvrtTo<Zbase<char>>(str)); }
- static void writeFile(BinStreamOut& output, const InSyncDescrFile& descr, const UInt64& fileSize)
+ static void writeFile(BinStreamOut& output, const InSyncDescrFile& descr)
{
writeNumber<std:: int64_t>(output, to<std:: int64_t>(descr.lastWriteTimeRaw));
- writeNumber<std::uint64_t>(output, to<std::uint64_t>(fileSize));
writeNumber<std::uint64_t>(output, descr.fileId.first);
writeNumber<std::uint64_t>(output, descr.fileId.second);
assert_static(sizeof(descr.fileId.first ) <= sizeof(std::uint64_t));
@@ -234,47 +252,6 @@ private:
static void writeLink(BinStreamOut& output, const InSyncDescrLink& descr)
{
writeNumber<std::int64_t>(output, to<std:: int64_t>(descr.lastWriteTimeRaw));
-
- warn_static("implement proper migration!")
- //writeUtf8(output, descr.targetPath);
- writeUtf8(output, Zstring());
- //writeNumber<std::int32_t>(output, descr.type);
- writeNumber<std::int32_t>(output, 0);
- }
-
- static void writeDir(BinStreamOut& output, const InSyncDir::InSyncStatus& status)
- {
- writeNumber<std::int32_t>(output, status);
- }
-
- void process(const std::pair<Zstring, InSyncFile>& dbFile)
- {
- writeUtf8(outputBoth, dbFile.first);
- writeNumber<std::int32_t>(outputBoth, dbFile.second.inSyncType);
-
- warn_static("implement proper migration: get rid of duplicate fileSize!")
-
- writeFile(outputLeft, dbFile.second.left, dbFile.second.fileSize);
- writeFile(outputRight, dbFile.second.right, dbFile.second.fileSize);
- }
-
- void process(const std::pair<Zstring, InSyncSymlink>& dbSymlink)
- {
- writeUtf8(outputBoth, dbSymlink.first);
-
- warn_static("new parameter: imp proper migration!")
- //writeNumber<std::int32_t>(outputBoth, dbSymlink.second.inSyncType);
-
- writeLink(outputLeft, dbSymlink.second.left);
- writeLink(outputRight, dbSymlink.second.right);
- }
-
- void process(const std::pair<Zstring, InSyncDir>& dbDir)
- {
- writeUtf8(outputBoth, dbDir.first);
- writeDir(outputBoth, dbDir.second.status);
-
- recurse(dbDir.second);
}
BinStreamOut outputLeft; //data related to one side only
@@ -283,7 +260,7 @@ private:
};
-class StreamParser //for db-file back-wards compatibility we stick with two output streams until further
+class StreamParser
{
public:
static std::shared_ptr<InSyncDir> execute(const BinaryStream& streamL, //throw FileError
@@ -308,8 +285,33 @@ public:
BinStreamIn inL(streamL);
BinStreamIn inR(streamR);
- bool has1stPartL = readNumber<bool>(inL); //throw UnexpectedEndOfStreamError
- bool has1stPartR = readNumber<bool>(inR); //
+ const int streamVersion = readNumber<std::int32_t>(inL); //throw UnexpectedEndOfStreamError
+ warn_static("remove this case after migration:")
+ bool migrateStreamFromOldFormat = streamVersion != DB_FORMAT_STREAM;
+ if (migrateStreamFromOldFormat)
+ inL = BinStreamIn(streamL);
+ else
+ {
+ const int streamVersionRef = readNumber<std::int32_t>(inR); //throw UnexpectedEndOfStreamError
+ if (streamVersionRef != streamVersion) //throw UnexpectedEndOfStreamError
+ throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filenameR), L"stream format mismatch"));
+ if (streamVersion != DB_FORMAT_STREAM)
+ throw FileError(replaceCpy(_("Database file %x is incompatible."), L"%x", fmtFileName(filenameL), L"stream format"));
+ }
+
+ bool has1stPartL = false;
+ bool has1stPartR = false;
+ if (migrateStreamFromOldFormat)
+ {
+ has1stPartL = readNumber<bool>(inL) != 0; //throw UnexpectedEndOfStreamError
+ has1stPartR = readNumber<bool>(inR) != 0; //
+ }
+ else
+ {
+ has1stPartL = readNumber<std::int8_t>(inL) != 0; //throw UnexpectedEndOfStreamError
+ has1stPartR = readNumber<std::int8_t>(inR) != 0; //
+ }
+
if (has1stPartL == has1stPartR)
throw UnexpectedEndOfStreamError();
@@ -320,7 +322,7 @@ public:
const size_t size2ndPart = static_cast<size_t>(readNumber<std::uint64_t>(in2ndPart));
BinaryStream tmpB;
- tmpB.resize(size1stPart + size2ndPart);
+ tmpB.resize(size1stPart + size2ndPart); //throw bad_alloc
readArray(in1stPart, &*tmpB.begin(), size1stPart);
readArray(in2ndPart, &*tmpB.begin() + size1stPart, size2ndPart);
@@ -330,7 +332,7 @@ public:
auto output = std::make_shared<InSyncDir>(InSyncDir::DIR_STATUS_IN_SYNC);
StreamParser parser(decompStream(tmpL, filenameL),
decompStream(tmpR, filenameR),
- decompStream(tmpB, filenameL + Zstr("/") + filenameR));
+ decompStream(tmpB, filenameL + Zstr("/") + filenameR), migrateStreamFromOldFormat);
parser.recurse(*output); //throw UnexpectedEndOfStreamError
return output;
}
@@ -338,7 +340,7 @@ public:
{
throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR));
}
- catch (const std::bad_alloc& e) //still required?
+ catch (const std::bad_alloc& e)
{
throw FileError(_("Database file is corrupt:") + L"\n" + fmtFileName(filenameL) + L"\n" + fmtFileName(filenameR),
_("Out of memory.") + L" " + utfCvrtTo<std::wstring>(e.what()));
@@ -348,57 +350,47 @@ public:
private:
StreamParser(const BinaryStream& bufferL,
const BinaryStream& bufferR,
- const BinaryStream& bufferB) :
+ const BinaryStream& bufferB,
+ bool migrateStreamFromOldFormat) :
+ migrateStreamFromOldFormat_(migrateStreamFromOldFormat),
inputLeft (bufferL),
inputRight(bufferR),
inputBoth (bufferB) {}
- static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError
-
- static InSyncDescrFile readFile(BinStreamIn& input, UInt64& fileSize)
- {
- //attention: order of function argument evaluation is undefined! So do it one after the other...
- auto lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError
- warn_static("implement proper migration!")
- fileSize = readNumber<std::uint64_t>(input);
- auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(input)); //
- auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings
- return InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx));
- }
-
- static InSyncDescrLink readLink(BinStreamIn& input)
- {
- auto lastWriteTimeRaw = readNumber<std::int64_t>(input);
-
- warn_static("implement proper migration!")
- //descr.targetPath = readUtf8(input);
- readUtf8(input);
- //descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input));
- readNumber<std::int32_t>(input);
-
- return InSyncDescrLink(lastWriteTimeRaw);
- }
-
- static void readDir(BinStreamIn& input, InSyncDir::InSyncStatus& status)
- {
- status = static_cast<InSyncDir::InSyncStatus>(readNumber<std::int32_t>(input));
- }
-
void recurse(InSyncDir& container)
{
size_t fileCount = readNumber<std::uint32_t>(inputBoth);
while (fileCount-- != 0)
{
- warn_static("migrate from InSyncType to CompareVariant!!!")
const Zstring shortName = readUtf8(inputBoth);
- const auto inSyncType = static_cast<InSyncType>(readNumber<std::int32_t>(inputBoth));
- warn_static("implement proper migration: get rid of duplicate fileSize!")
-
- UInt64 fileSize;
- const InSyncDescrFile dataL = readFile(inputLeft, fileSize);
- const InSyncDescrFile dataR = readFile(inputRight, fileSize);
- container.addFile(shortName, dataL, dataR, inSyncType, fileSize);
+ if (migrateStreamFromOldFormat_)
+ {
+ const auto inSyncType = readNumber<std::int32_t>(inputBoth);
+ const CompareVariant cmpVar = inSyncType == 0 ? CMP_BY_CONTENT : CMP_BY_TIME_SIZE;
+
+ auto lastWriteTimeRawL = readNumber<std::int64_t>(inputLeft); //throw UnexpectedEndOfStreamError
+ const UInt64 fileSize = readNumber<std::uint64_t>(inputLeft);
+ auto devIdL = static_cast<DeviceId >(readNumber<std::uint64_t>(inputLeft)); //
+ auto fileIdxL = static_cast<FileIndex>(readNumber<std::uint64_t>(inputLeft)); //silence "loss of precision" compiler warnings
+ const InSyncDescrFile dataL = InSyncDescrFile(lastWriteTimeRawL, FileId(devIdL, fileIdxL));
+
+ auto lastWriteTimeRaw = readNumber<std::int64_t>(inputRight); //throw UnexpectedEndOfStreamError
+ readNumber<std::uint64_t>(inputRight);
+ auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(inputRight)); //
+ auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(inputRight)); //silence "loss of precision" compiler warnings
+ const InSyncDescrFile dataR = InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx));
+
+ container.addFile(shortName, dataL, dataR, cmpVar, fileSize);
+ }
+ else
+ {
+ const auto cmpVar = static_cast<CompareVariant>(readNumber<std::int32_t>(inputBoth));
+ const UInt64 fileSize = readNumber<std::uint64_t>(inputBoth);
+ const InSyncDescrFile dataL = readFile(inputLeft);
+ const InSyncDescrFile dataR = readFile(inputRight);
+ container.addFile(shortName, dataL, dataR, cmpVar, fileSize);
+ }
}
size_t linkCount = readNumber<std::uint32_t>(inputBoth);
@@ -406,28 +398,61 @@ private:
{
const Zstring shortName = readUtf8(inputBoth);
- warn_static("new parameter: imp proper migration!")
- const auto inSyncType = IN_SYNC_BINARY_EQUAL;
- //const auto inSyncType = static_cast<InSyncType>(readNumber<std::int32_t>(inputBoth));
-
- InSyncDescrLink dataL = readLink(inputLeft);
- InSyncDescrLink dataR = readLink(inputRight);
- container.addSymlink(shortName, dataL, dataR, inSyncType);
+ if (migrateStreamFromOldFormat_)
+ {
+ const CompareVariant cmpVar = CMP_BY_CONTENT;
+ auto lastWriteTimeRaw = readNumber<std::int64_t>(inputLeft);
+ readUtf8(inputLeft);//descr.targetPath = readUtf8(input);
+ readNumber<std::int32_t>(inputLeft);//descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input));
+ InSyncDescrLink dataL = InSyncDescrLink(lastWriteTimeRaw);
+
+ auto lastWriteTimeRawR = readNumber<std::int64_t>(inputRight);
+ readUtf8(inputRight);//descr.targetPath = readUtf8(input);
+ readNumber<std::int32_t>(inputRight);//descr.type = static_cast<LinkDescriptor::LinkType>(readNumber<std::int32_t>(input));
+ InSyncDescrLink dataR = InSyncDescrLink(lastWriteTimeRawR);
+
+ container.addSymlink(shortName, dataL, dataR, cmpVar);
+ }
+ else
+ {
+ const auto cmpVar = static_cast<CompareVariant>(readNumber<std::int32_t>(inputBoth));
+ InSyncDescrLink dataL = readLink(inputLeft);
+ InSyncDescrLink dataR = readLink(inputRight);
+ container.addSymlink(shortName, dataL, dataR, cmpVar);
+ }
}
size_t dirCount = readNumber<std::uint32_t>(inputBoth);
while (dirCount-- != 0)
{
const Zstring shortName = readUtf8(inputBoth);
-
- InSyncDir::InSyncStatus status = InSyncDir::DIR_STATUS_STRAW_MAN;
- readDir(inputBoth, status);
+ auto status = static_cast<InSyncDir::InSyncStatus>(readNumber<std::int32_t>(inputBoth));
InSyncDir& subDir = container.addDir(shortName, status);
recurse(subDir);
}
}
+ static Zstring readUtf8(BinStreamIn& input) { return utfCvrtTo<Zstring>(readContainer<Zbase<char>>(input)); } //throw UnexpectedEndOfStreamError
+
+ static InSyncDescrFile readFile(BinStreamIn& input)
+ {
+ //attention: order of function argument evaluation is undefined! So do it one after the other...
+ auto lastWriteTimeRaw = readNumber<std::int64_t>(input); //throw UnexpectedEndOfStreamError
+ auto devId = static_cast<DeviceId >(readNumber<std::uint64_t>(input)); //
+ auto fileIdx = static_cast<FileIndex>(readNumber<std::uint64_t>(input)); //silence "loss of precision" compiler warnings
+ return InSyncDescrFile(lastWriteTimeRaw, FileId(devId, fileIdx));
+ }
+
+ static InSyncDescrLink readLink(BinStreamIn& input)
+ {
+ auto lastWriteTimeRaw = readNumber<std::int64_t>(input);
+ return InSyncDescrLink(lastWriteTimeRaw);
+ }
+
+ warn_static("remove after migration")
+ bool migrateStreamFromOldFormat_;
+
BinStreamIn inputLeft; //data related to one side only
BinStreamIn inputRight; //
BinStreamIn inputBoth; //data concerning both sides
@@ -446,24 +471,14 @@ class UpdateLastSynchronousState
public:
static void execute(const BaseDirPair& baseDirObj, InSyncDir& dir)
{
- bool binaryComparison = false;
- switch (baseDirObj.getCompVariant())
- {
- case CMP_BY_TIME_SIZE:
- break;
- case CMP_BY_CONTENT:
- binaryComparison = true;
- break;
- }
-
- UpdateLastSynchronousState updater(baseDirObj.getFilter(), binaryComparison);
+ UpdateLastSynchronousState updater(baseDirObj.getCompVariant(), baseDirObj.getFilter());
updater.recurse(baseDirObj, dir);
}
private:
- UpdateLastSynchronousState(const HardFilter& filter, bool binaryComparison) :
+ UpdateLastSynchronousState(CompareVariant activeCmpVar, const HardFilter& filter) :
filter_(filter),
- binaryComparison_(binaryComparison) {}
+ activeCmpVar_(activeCmpVar) {}
void recurse(const HierarchyObject& hierObj, InSyncDir& dir)
{
@@ -516,8 +531,7 @@ private:
void process(const HierarchyObject::SubFileVec& currentFiles, const Zstring& parentRelativeNamePf, InSyncDir::FileList& dbFiles)
{
hash_set<const InSyncFile*> toPreserve; //referencing fixed-in-memory std::map elements
- std::for_each(currentFiles.begin(), currentFiles.end(), [&](const FilePair& fileObj)
- {
+ for (const FilePair& fileObj : currentFiles)
if (!fileObj.isEmpty())
{
if (fileObj.getCategory() == FILE_EQUAL) //data in sync: write current state
@@ -534,9 +548,7 @@ private:
fileObj.getFileId <LEFT_SIDE>()),
InSyncDescrFile(fileObj.getLastWriteTime<RIGHT_SIDE>(),
fileObj.getFileId <RIGHT_SIDE>()),
- binaryComparison_ ?
- IN_SYNC_BINARY_EQUAL :
- IN_SYNC_ATTRIBUTES_EQUAL,
+ activeCmpVar_,
fileObj.getFileSize<LEFT_SIDE>()));
toPreserve.insert(&file);
}
@@ -547,7 +559,6 @@ private:
toPreserve.insert(&it->second);
}
}
- });
warn_static("consider temporarily excluded items due to traveral error just like a fixed file filter here!?")
//delete removed items (= "in-sync") from database
@@ -564,8 +575,7 @@ private:
void process(const HierarchyObject::SubLinkVec& currentLinks, const Zstring& parentRelativeNamePf, InSyncDir::LinkList& dbLinks)
{
hash_set<const InSyncSymlink*> toPreserve;
- std::for_each(currentLinks.begin(), currentLinks.end(), [&](const SymlinkPair& linkObj)
- {
+ for (const SymlinkPair& linkObj : currentLinks)
if (!linkObj.isEmpty())
{
if (linkObj.getLinkCategory() == SYMLINK_EQUAL) //data in sync: write current state
@@ -576,9 +586,7 @@ private:
InSyncSymlink& link = updateItem(dbLinks, linkObj.getObjShortName(),
InSyncSymlink(InSyncDescrLink(linkObj.getLastWriteTime<LEFT_SIDE>()),
InSyncDescrLink(linkObj.getLastWriteTime<RIGHT_SIDE>()),
- binaryComparison_ ?
- IN_SYNC_BINARY_EQUAL :
- IN_SYNC_ATTRIBUTES_EQUAL));
+ activeCmpVar_));
toPreserve.insert(&link);
}
else //not in sync: preserve last synchronous state
@@ -588,7 +596,6 @@ private:
toPreserve.insert(&it->second);
}
}
- });
//delete removed items (= "in-sync") from database
map_remove_if(dbLinks, [&](const InSyncDir::LinkList::value_type& v) -> bool
@@ -604,8 +611,7 @@ private:
void process(const HierarchyObject::SubDirVec& currentDirs, const Zstring& parentRelativeNamePf, InSyncDir::DirList& dbDirs)
{
hash_set<const InSyncDir*> toPreserve;
- std::for_each(currentDirs.begin(), currentDirs.end(), [&](const DirPair& dirObj)
- {
+ for (const DirPair& dirObj : currentDirs)
if (!dirObj.isEmpty())
switch (dirObj.getDirCategory())
{
@@ -659,7 +665,6 @@ private:
}
break;
}
- });
//delete removed items (= "in-sync") from database
map_remove_if(dbDirs, [&](const InSyncDir::DirList::value_type& v) -> bool
@@ -676,7 +681,7 @@ private:
}
const HardFilter& filter_; //filter used while scanning directory: generates view on actual files!
- const bool binaryComparison_;
+ const CompareVariant activeCmpVar_;
};
}
@@ -698,17 +703,17 @@ std::shared_ptr<InSyncDir> zen::loadLastSynchronousState(const BaseDirPair& base
}
//read file data: list of session ID + DirInfo-stream
- const StreamMapping streamListLeft = ::loadStreams(fileNameLeft); //throw FileError, FileErrorDatabaseNotExisting
- const StreamMapping streamListRight = ::loadStreams(fileNameRight); //
+ const DbStreams streamsLeft = ::loadStreams(fileNameLeft); //throw FileError, FileErrorDatabaseNotExisting
+ const DbStreams streamsRight = ::loadStreams(fileNameRight); //
//find associated session: there can be at most one session within intersection of left and right ids
- for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft)
+ for (const auto& streamLeft : streamsLeft)
{
- auto iterRight = streamListRight.find(iterLeft->first);
- if (iterRight != streamListRight.end())
+ auto itRight = streamsRight.find(streamLeft.first);
+ if (itRight != streamsRight.end())
{
- return StreamParser::execute(iterLeft ->second, //throw FileError
- iterRight->second,
+ return StreamParser::execute(streamLeft.second, //throw FileError
+ itRight->second,
fileNameLeft,
fileNameRight);
}
@@ -732,38 +737,37 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr
removeFile(dbNameRightTmp); //throw FileError
//(try to) load old database files...
- StreamMapping streamListLeft;
- StreamMapping streamListRight;
+ DbStreams streamsLeft; //list of session ID + DirInfo-stream
+ DbStreams streamsRight;
- //read file data: list of session ID + DirInfo-stream
- try { streamListLeft = ::loadStreams(dbNameLeft ); }
+ try { streamsLeft = ::loadStreams(dbNameLeft ); }
catch (FileError&) {}
- try { streamListRight = ::loadStreams(dbNameRight); }
+ try { streamsRight = ::loadStreams(dbNameRight); }
catch (FileError&) {}
//if error occurs: just overwrite old file! User is already informed about issues right after comparing!
//find associated session: there can be at most one session within intersection of left and right ids
- auto streamIterLeftOld = streamListLeft .cend();
- auto streamIterRightOld = streamListRight.cend();
- for (auto iterLeft = streamListLeft.begin(); iterLeft != streamListLeft.end(); ++iterLeft)
+ auto itStreamLeftOld = streamsLeft .cend();
+ auto itStreamRightOld = streamsRight.cend();
+ for (auto iterLeft = streamsLeft.begin(); iterLeft != streamsLeft.end(); ++iterLeft)
{
- auto iterRight = streamListRight.find(iterLeft->first);
- if (iterRight != streamListRight.end())
+ auto iterRight = streamsRight.find(iterLeft->first);
+ if (iterRight != streamsRight.end())
{
- streamIterLeftOld = iterLeft;
- streamIterRightOld = iterRight;
+ itStreamLeftOld = iterLeft;
+ itStreamRightOld = iterRight;
break;
}
}
//load last synchrounous state
std::shared_ptr<InSyncDir> lastSyncState = std::make_shared<InSyncDir>(InSyncDir::DIR_STATUS_IN_SYNC);
- if (streamIterLeftOld != streamListLeft .end() &&
- streamIterRightOld != streamListRight.end())
+ if (itStreamLeftOld != streamsLeft .end() &&
+ itStreamRightOld != streamsRight.end())
try
{
- lastSyncState = StreamParser::execute(streamIterLeftOld ->second, //throw FileError
- streamIterRightOld->second,
+ lastSyncState = StreamParser::execute(itStreamLeftOld ->second, //throw FileError
+ itStreamRightOld->second,
dbNameLeft,
dbNameRight);
}
@@ -782,28 +786,28 @@ void zen::saveLastSynchronousState(const BaseDirPair& baseDirObj) //throw FileEr
updatedStreamRight); //throw FileError
//check if there is some work to do at all
- if (streamIterLeftOld != streamListLeft .end() && updatedStreamLeft == streamIterLeftOld ->second &&
- streamIterRightOld != streamListRight.end() && updatedStreamRight == streamIterRightOld->second)
+ if (itStreamLeftOld != streamsLeft .end() && updatedStreamLeft == itStreamLeftOld ->second &&
+ itStreamRightOld != streamsRight.end() && updatedStreamRight == itStreamRightOld->second)
return; //some users monitor the *.ffs_db file with RTS => don't touch the file if it isnt't strictly needed
//erase old session data
- if (streamIterLeftOld != streamListLeft.end())
- streamListLeft.erase(streamIterLeftOld);
- if (streamIterRightOld != streamListRight.end())
- streamListRight.erase(streamIterRightOld);
+ if (itStreamLeftOld != streamsLeft.end())
+ streamsLeft.erase(itStreamLeftOld);
+ if (itStreamRightOld != streamsRight.end())
+ streamsRight.erase(itStreamRightOld);
//create new session data
const std::string sessionID = zen::generateGUID();
- streamListLeft [sessionID] = std::move(updatedStreamLeft);
- streamListRight[sessionID] = std::move(updatedStreamRight);
+ streamsLeft [sessionID] = std::move(updatedStreamLeft);
+ streamsRight[sessionID] = std::move(updatedStreamRight);
//write (temp-) files...
zen::ScopeGuard guardTempFileLeft = zen::makeGuard([&] {zen::removeFile(dbNameLeftTmp); });
- saveStreams(streamListLeft, dbNameLeftTmp); //throw FileError
+ saveStreams(streamsLeft, dbNameLeftTmp); //throw FileError
zen::ScopeGuard guardTempFileRight = zen::makeGuard([&] {zen::removeFile(dbNameRightTmp); });
- saveStreams(streamListRight, dbNameRightTmp); //throw FileError
+ saveStreams(streamsRight, dbNameRightTmp); //throw FileError
//operation finished: rename temp files -> this should work transactionally:
//if there were no write access, creation of temp files would have failed
diff --git a/lib/db_file.h b/lib/db_file.h
index b352ba5d..c432704d 100644
--- a/lib/db_file.h
+++ b/lib/db_file.h
@@ -14,12 +14,6 @@ namespace zen
{
const Zstring SYNC_DB_FILE_ENDING = Zstr(".ffs_db");
-enum InSyncType
-{
- IN_SYNC_BINARY_EQUAL, //checked file content
- IN_SYNC_ATTRIBUTES_EQUAL, //only "looks" like they're equal
-};
-
struct InSyncDescrFile //subset of FileDescriptor
{
InSyncDescrFile(const Int64& lastWriteTimeRawIn,
@@ -41,19 +35,19 @@ struct InSyncDescrLink
//artificial hierarchy of last synchronous state:
struct InSyncFile
{
- InSyncFile(const InSyncDescrFile& l, const InSyncDescrFile& r, InSyncType type, const UInt64& fileSizeIn) : left(l), right(r), inSyncType(type), fileSize(fileSizeIn) {}
+ InSyncFile(const InSyncDescrFile& l, const InSyncDescrFile& r, CompareVariant cv, const UInt64& fileSizeIn) : left(l), right(r), cmpVar(cv), fileSize(fileSizeIn) {}
InSyncDescrFile left;
InSyncDescrFile right;
- InSyncType inSyncType;
+ CompareVariant cmpVar; //the one active while finding "file in sync"
UInt64 fileSize; //file size must be identical on both sides!
};
struct InSyncSymlink
{
- InSyncSymlink(const InSyncDescrLink& l, const InSyncDescrLink& r, InSyncType type) : left(l), right(r), inSyncType(type) {}
+ InSyncSymlink(const InSyncDescrLink& l, const InSyncDescrLink& r, CompareVariant cv) : left(l), right(r), cmpVar(cv) {}
InSyncDescrLink left;
InSyncDescrLink right;
- InSyncType inSyncType;
+ CompareVariant cmpVar;
};
struct InSyncDir
@@ -86,14 +80,14 @@ struct InSyncDir
return dirs.insert(std::make_pair(shortName, InSyncDir(st))).first->second;
}
- void addFile(const Zstring& shortName, const InSyncDescrFile& dataL, const InSyncDescrFile& dataR, InSyncType type, const UInt64& fileSize)
+ void addFile(const Zstring& shortName, const InSyncDescrFile& dataL, const InSyncDescrFile& dataR, CompareVariant cmpVar, const UInt64& fileSize)
{
- files.insert(std::make_pair(shortName, InSyncFile(dataL, dataR, type, fileSize)));
+ files.insert(std::make_pair(shortName, InSyncFile(dataL, dataR, cmpVar, fileSize)));
}
- void addSymlink(const Zstring& shortName, const InSyncDescrLink& dataL, const InSyncDescrLink& dataR, InSyncType type)
+ void addSymlink(const Zstring& shortName, const InSyncDescrLink& dataL, const InSyncDescrLink& dataR, CompareVariant cmpVar)
{
- symlinks.insert(std::make_pair(shortName, InSyncSymlink(dataL, dataR, type)));
+ symlinks.insert(std::make_pair(shortName, InSyncSymlink(dataL, dataR, cmpVar)));
}
};
diff --git a/lib/dir_exist_async.h b/lib/dir_exist_async.h
index 39ae6aff..7eb4827e 100644
--- a/lib/dir_exist_async.h
+++ b/lib/dir_exist_async.h
@@ -44,7 +44,8 @@ std::set<Zstring, LessFilename> getExistingDirsUpdating(const std::set<Zstring,
});
std::set<Zstring, LessFilename> output;
- const boost::system_time endTime = boost::get_system_time() + boost::posix_time::seconds(10); //10 sec should be enough even if Win32 waits much longer
+ //don't wait (almost) endlessly like win32 would on not existing network shares:
+ const boost::system_time endTime = boost::get_system_time() + boost::posix_time::seconds(20); //consider CD-rom insert or hard disk spin up time from sleep
auto itDirname = dirnames.begin();
for (auto it = dirEx.begin(); it != dirEx.end(); (void)++it, ++itDirname) //void: prevent ADL from dragging in boost's ,-overload: "MSVC warning C4913: user defined binary operator ',' exists but no overload could convert all operands"
diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp
index d7e3ba56..b58e018b 100644
--- a/lib/dir_lock.cpp
+++ b/lib/dir_lock.cpp
@@ -506,7 +506,7 @@ void releaseLock(const Zstring& lockfilename) //throw ()
{
removeFile(lockfilename); //throw FileError
}
- catch (...) {}
+ catch (FileError&) {}
}
diff --git a/lib/hard_filter.cpp b/lib/hard_filter.cpp
index 39cb07f6..687aecd8 100644
--- a/lib/hard_filter.cpp
+++ b/lib/hard_filter.cpp
@@ -65,52 +65,65 @@ const Zstring asteriskSepAsterisk = asteriskSep + asterisk;
}
-void addFilterEntry(const Zstring& filtername, std::vector<Zstring>& fileFilter, std::vector<Zstring>& directoryFilter)
+void addFilterEntry(const Zstring& filterPhrase, std::vector<Zstring>& fileFilter, std::vector<Zstring>& directoryFilter)
{
- Zstring filterFormatted = filtername;
-
#if defined ZEN_WIN || defined ZEN_MAC
//Windows does NOT distinguish between upper/lower-case
+ Zstring filterFormatted = filterPhrase;
makeUpper(filterFormatted);
#elif defined ZEN_LINUX
+ const Zstring& filterFormatted = filterPhrase;
//Linux DOES distinguish between upper/lower-case: nothing to do here
#endif
- if (startsWith(filterFormatted, FILE_NAME_SEPARATOR)) // \abc
- filterFormatted = afterFirst(filterFormatted, FILE_NAME_SEPARATOR); //leading separator is optional!
-
- //some syntactic sugar:
- if (filterFormatted == asteriskSepAsterisk) // *\* := match everything except files directly in base directory
- {
- fileFilter. push_back(filterFormatted);
- directoryFilter.push_back(asterisk);
- return;
- }
- //more syntactic sugar: handle beginning of filtername
- else if (startsWith(filterFormatted, asteriskSep)) // *\abc
- {
- addFilterEntry(filterFormatted.c_str() + 2, fileFilter, directoryFilter); //recursion is finite
- }
- //--------------------------------------------------------------------------------------------------
- //even more syntactic sugar: handle end of filtername
- if (endsWith(filterFormatted, FILE_NAME_SEPARATOR))
- {
- const Zstring candidate = beforeLast(filterFormatted, FILE_NAME_SEPARATOR);
- if (!candidate.empty())
- directoryFilter.push_back(candidate); //only relevant for directory filtering
- }
- else if (endsWith(filterFormatted, sepAsterisk)) // abc\*
+ /*
+ phrase | action
+ +---------+--------
+ | \blah | remove \
+ | \*blah | remove \
+ | \*\blah | remove \
+ | \*\* | remove \
+ +---------+--------
+ | *blah |
+ | *\blah | -> add blah
+ | *\*blah | -> add *blah
+ +---------+--------
+ | blah\ | remove \; directory only
+ | blah*\ | remove \; directory only
+ | blah\*\ | remove \; directory only
+ +---------+--------
+ | blah* |
+ | blah\* | add blah for directory only
+ | blah*\* | add blah* for directory only
+ +---------+--------
+ */
+ auto processTail = [&fileFilter, &directoryFilter](const Zstring& phrase)
{
- fileFilter .push_back(filterFormatted);
- directoryFilter.push_back(filterFormatted);
+ if (endsWith(phrase, FILE_NAME_SEPARATOR)) //only relevant for directory filtering
+ {
+ const Zstring dirPhrase = beforeLast(phrase, FILE_NAME_SEPARATOR);
+ if (!dirPhrase.empty())
+ directoryFilter.push_back(dirPhrase);
+ }
+ else if (!phrase.empty())
+ {
+ fileFilter .push_back(phrase);
+ directoryFilter.push_back(phrase);
+ if (endsWith(phrase, sepAsterisk)) // abc\*
+ {
+ const Zstring dirPhrase = beforeLast(phrase, sepAsterisk);
+ if (!dirPhrase.empty())
+ directoryFilter.push_back(dirPhrase);
+ }
+ }
+ };
- const Zstring candidate = beforeLast(filterFormatted, FILE_NAME_SEPARATOR);
- if (!candidate.empty())
- directoryFilter.push_back(candidate); //only relevant for directory filtering
- }
- else if (!filterFormatted.empty())
+ if (startsWith(filterFormatted, FILE_NAME_SEPARATOR)) // \abc
+ processTail(afterFirst(filterFormatted, FILE_NAME_SEPARATOR));
+ else
{
- fileFilter. push_back(filterFormatted);
- directoryFilter.push_back(filterFormatted);
+ processTail(filterFormatted);
+ if (startsWith(filterFormatted, asteriskSep)) // *\abc
+ processTail(afterFirst(filterFormatted, asteriskSep));
}
}
diff --git a/lib/hard_filter.h b/lib/hard_filter.h
index e47047a0..e721fe4f 100644
--- a/lib/hard_filter.h
+++ b/lib/hard_filter.h
@@ -4,8 +4,8 @@
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
-#ifndef FFS_FILTER_H_INCLUDED
-#define FFS_FILTER_H_INCLUDED
+#ifndef HARD_FILTER_H_825780275842758345
+#define HARD_FILTER_H_825780275842758345
#include <vector>
#include <memory>
@@ -267,5 +267,4 @@ HardFilter::FilterRef combineFilters(const HardFilter::FilterRef& first,
}
-#endif // FFS_FILTER_H_INCLUDED
-
+#endif //HARD_FILTER_H_825780275842758345
diff --git a/lib/icon_buffer.cpp b/lib/icon_buffer.cpp
index b0874d83..e78b308e 100644
--- a/lib/icon_buffer.cpp
+++ b/lib/icon_buffer.cpp
@@ -102,13 +102,7 @@ public:
return wxBitmap(fileIcon);
#elif defined ZEN_LINUX
-#if wxCHECK_VERSION(2, 9, 4)
return wxBitmap(release()); //ownership passed!
-#else
- wxBitmap newIcon;
- newIcon.SetPixbuf(release()); //ownership passed!
- return newIcon;
-#endif
#elif defined ZEN_MAC
ZEN_ON_SCOPE_EXIT(IconHolder().swap(*this)); //destroy after extraction
@@ -358,7 +352,7 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
0, //DWORD dwFileAttributes,
&fileInfo, //_Inout_ SHFILEINFO *psfi,
sizeof(fileInfo), //UINT cbFileInfo,
- SHGFI_SYSICONINDEX | SHGFI_ATTRIBUTES)) //UINT uFlags
+ SHGFI_SYSICONINDEX /*| SHGFI_ATTRIBUTES*/)) //UINT uFlags
{
(void)imgList;
//imgList->Release(); //empiric study: crash on XP if we release this! Seems we do not own it... -> also no GDI leak on Win7 -> okay
@@ -368,13 +362,13 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
// for example, for use in a list view. Conversely, an HIMAGELIST can be cast as a pointer to an IImageList."
//http://msdn.microsoft.com/en-us/library/windows/desktop/bb762185(v=vs.85).aspx
-#ifndef SFGAO_LINK //Shobjidl.h
+#ifdef __MINGW32__ //Shobjidl.h
#define SFGAO_LINK 0x00010000L // Shortcut (link) or symlinks
#endif
warn_static("support SFGAO_GHOSTED or hidden?")
-
- const bool isLink = (fileInfo.dwAttributes & SFGAO_LINK) != 0;
+ //requires SHGFI_ATTRIBUTES
+ //const bool isLink = (fileInfo.dwAttributes & SFGAO_LINK) != 0;
if (getIconByIndex && releaseImageData)
if (const thumb::ImageData* imgData = getIconByIndex(fileInfo.iIcon, getThumbSizeType(sz)))
@@ -398,7 +392,7 @@ IconHolder getAssociatedIcon(const Zstring& filename, IconBuffer::IconSize sz)
{
return IconHolder(new osx::ImageData(osx::getFileIcon(filename.c_str(), IconBuffer::getSize(sz)))); //throw SysError
}
- catch (zen::SysError&) {}
+ catch (zen::SysError&) { assert(false); }
#endif
return ::getGenericFileIcon(sz); //make sure this does not internally call getAssociatedIcon("someDefaultFile.txt")!!! => endless recursion!
}
@@ -454,7 +448,7 @@ class Buffer
{
public:
//called by main and worker thread:
- bool hasFileIcon(const Zstring& fileName)
+ bool hasFileIcon(const Zstring& fileName) const
{
boost::lock_guard<boost::mutex> dummy(lockIconList);
return iconList.find(fileName) != iconList.end();
@@ -519,7 +513,7 @@ private:
//- prohibit even wxBitmap() default constructor - better be safe than sorry!
};
- boost::mutex lockIconList;
+ mutable boost::mutex lockIconList;
std::map<Zstring, IconData, LessFilename> iconList; //shared resource; Zstring is thread-safe like an int
std::queue<Zstring> iconSequence; //save sequence of buffer entry to delete oldest elements
};
diff --git a/lib/norm_filter.h b/lib/norm_filter.h
index 2d878da2..552931e2 100644
--- a/lib/norm_filter.h
+++ b/lib/norm_filter.h
@@ -66,8 +66,8 @@ bool isNullFilter(const FilterConfig& filterCfg)
inline
NormalizedFilter normalizeFilters(const FilterConfig& global, const FilterConfig& local)
{
- HardFilter::FilterRef globalName(new NameFilter(global.includeFilter, global.excludeFilter));
- HardFilter::FilterRef localName (new NameFilter(local .includeFilter, local .excludeFilter));
+ HardFilter::FilterRef globalName = std::make_shared<NameFilter>(global.includeFilter, global.excludeFilter);
+ HardFilter::FilterRef localName = std::make_shared<NameFilter>(local .includeFilter, local .excludeFilter);
SoftFilter globalTimeSize(global.timeSpan, global.unitTimeSpan,
global.sizeMin, global.unitSizeMin,
diff --git a/lib/osx_file_icon.mm b/lib/osx_file_icon.mm
index 4db6642a..fb3c6490 100644
--- a/lib/osx_file_icon.mm
+++ b/lib/osx_file_icon.mm
@@ -65,7 +65,7 @@ osx::ImageData extractBytes(NSImage* nsImg, int requestedSize) //throw SysError;
::CGContextDrawImage(ctxRef, CGRectMake(0, 0, trgWidth, trgHeight), imgRef); //can this fail? not documented
- //CGContextFlush(ctxRef); //"If you pass [...] a bitmap context, this function does nothing."
+ //::CGContextFlush(ctxRef); //"If you pass [...] a bitmap context, this function does nothing."
osx::ImageData imgOut(trgWidth, trgHeight);
diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp
index 2bac5690..433647ca 100644
--- a/lib/parallel_scan.cpp
+++ b/lib/parallel_scan.cpp
@@ -368,30 +368,24 @@ DirCallback::HandleLink DirCallback::onSymlink(const Zchar* shortName, const Zst
{
boost::this_thread::interruption_point();
+ //update status information no matter whether object is excluded or not!
+ cfg.acb_.reportCurrentFile(fullName, cfg.threadID_);
+
switch (cfg.handleSymlinks_)
{
- case SYMLINK_IGNORE:
+ case SYMLINK_EXCLUDE:
return LINK_SKIP;
case SYMLINK_USE_DIRECTLY:
- {
- //update status information no matter whether object is excluded or not!
- cfg.acb_.reportCurrentFile(fullName, cfg.threadID_);
-
- //------------------------------------------------------------------------------------
- const Zstring& relName = relNameParentPf_ + shortName;
-
- //apply filter before processing (use relative name!)
- if (cfg.filterInstance->passFileFilter(relName)) //always use file filter: Link type may not be "stable" on Linux!
+ if (cfg.filterInstance->passFileFilter(relNameParentPf_ + shortName)) //always use file filter: Link type may not be "stable" on Linux!
{
output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTime));
cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator
}
- }
- return LINK_SKIP;
+ return LINK_SKIP;
case SYMLINK_FOLLOW_LINK:
- return LINK_FOLLOW;
+ return cfg.filterInstance->passFileFilter(relNameParentPf_ + shortName) ? LINK_FOLLOW : LINK_SKIP; //filter broken symlinks before trying to follow them!
}
assert(false);
@@ -546,32 +540,28 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in
zen::ScopeGuard guardWorker = zen::makeGuard([&]
{
- std::for_each(worker.begin(), worker.end(), [](boost::thread& wt) { wt.interrupt(); }); //interrupt all at once first, then join
- std::for_each(worker.begin(), worker.end(), [](boost::thread& wt)
- {
+ for (boost::thread& wt : worker)
+ wt.interrupt(); //interrupt all at once first, then join
+ for (boost::thread& wt : worker)
if (wt.joinable()) //= precondition of thread::join(), which throws an exception if violated!
wt.join(); //in this context it is possible a thread is *not* joinable anymore due to the thread::timed_join() below!
- });
});
auto acb = std::make_shared<AsyncCallback>();
//init worker threads
- std::for_each(keysToRead.begin(), keysToRead.end(),
- [&](const DirectoryKey& key)
+ for (const DirectoryKey& key : keysToRead)
{
assert(buf.find(key) == buf.end());
DirectoryValue& dirOutput = buf[key];
const long threadId = static_cast<long>(worker.size());
worker.emplace_back(WorkerThread(threadId, acb, key, dirOutput));
- });
+ }
//wait until done
- for (auto it = worker.begin(); it != worker.end(); ++it)
+ for (boost::thread& wt : worker)
{
- boost::thread& wt = *it;
-
do
{
//update status
diff --git a/lib/parse_lng.h b/lib/parse_lng.h
index be47b66b..9aa62816 100644
--- a/lib/parse_lng.h
+++ b/lib/parse_lng.h
@@ -107,10 +107,10 @@ public:
template <class Function, class Function2>
void visitItems(Function onTrans, Function2 onPluralTrans) const //onTrans takes (const TranslationMap::value_type&), onPluralTrans takes (const TranslationPluralMap::value_type&)
{
- for (auto it = sequence.begin(); it != sequence.end(); ++it)
- if (auto regular = dynamic_cast<const RegularItem*>(it->get()))
+ for (const auto& item : sequence)
+ if (auto regular = dynamic_cast<const RegularItem*>(item.get()))
onTrans(regular->value);
- else if (auto plural = dynamic_cast<const PluralItem*>(it->get()))
+ else if (auto plural = dynamic_cast<const PluralItem*>(item.get()))
onPluralTrans(plural->value);
else assert(false);
}
@@ -637,11 +637,10 @@ std::string generateLng(const TranslationUnorderedList& in, const TransHeader& h
out += KnownTokens::text(Token::TK_SRC_END) + '\n';
out += KnownTokens::text(Token::TK_TRG_BEGIN);
- if (!forms.empty()) out += '\n';
+ out += '\n';
- for (PluralForms::const_iterator j = forms.begin(); j != forms.end(); ++j)
+ for (std::string plForm : forms)
{
- std::string plForm = *j;
formatMultiLineText(plForm);
out += KnownTokens::text(Token::TK_PLURAL_BEGIN);
diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp
index 49e4c711..4640e472 100644
--- a/lib/process_xml.cpp
+++ b/lib/process_xml.cpp
@@ -14,15 +14,14 @@
using namespace zen;
using namespace xmlAccess; //functionally needed for correct overload resolution!!!
-
using namespace std::rel_ops;
namespace
{
//-------------------------------------------------------------------------------------------------------------------------------
const int XML_FORMAT_VER_GLOBAL = 1;
-const int XML_FORMAT_VER_FFS_GUI = 1;
-const int XML_FORMAT_VER_FFS_BATCH = 1;
+const int XML_FORMAT_VER_FFS_GUI = 2;
+const int XML_FORMAT_VER_FFS_BATCH = 2;
//-------------------------------------------------------------------------------------------------------------------------------
}
@@ -49,7 +48,7 @@ XmlType xmlAccess::getXmlType(const Zstring& filename) //throw()
{
try
{
- //do NOT use zen::loadStream as it will superfluously load even huge files!
+ //do NOT use zen::loadStream as it will needlessly load even huge files!
XmlDoc doc = loadXmlDocument(filename); //throw FfsXmlError, quick exit if file is not an FFS XML
return ::getXmlType(doc);
}
@@ -78,6 +77,7 @@ void setXmlType(XmlDoc& doc, XmlType type) //throw()
break;
}
}
+
//################################################################################################################
Zstring xmlAccess::getGlobalConfigFile()
@@ -110,8 +110,8 @@ xmlAccess::XmlGuiConfig xmlAccess::convertBatchToGui(const xmlAccess::XmlBatchCo
switch (batchCfg.handleError)
{
- case ON_ERROR_EXIT:
case ON_ERROR_POPUP:
+ case ON_ERROR_ABORT:
output.handleError = ON_GUIERROR_POPUP;
break;
case ON_ERROR_IGNORE:
@@ -186,10 +186,10 @@ void writeText(const CompareVariant& value, std::string& output)
switch (value)
{
case zen::CMP_BY_TIME_SIZE:
- output = "ByTimeAndSize";
+ output = "TimeAndSize";
break;
case zen::CMP_BY_CONTENT:
- output = "ByContent";
+ output = "Content";
break;
}
}
@@ -199,12 +199,19 @@ bool readText(const std::string& input, CompareVariant& value)
{
std::string tmp = input;
zen::trim(tmp);
- if (tmp == "ByTimeAndSize")
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "ByTimeAndSize") //obsolete
value = zen::CMP_BY_TIME_SIZE;
- else if (tmp == "ByContent")
+ else if (tmp == "ByContent") //obsolete
value = zen::CMP_BY_CONTENT;
else
- return false;
+
+ if (tmp == "TimeAndSize")
+ value = zen::CMP_BY_TIME_SIZE;
+ else if (tmp == "Content")
+ value = zen::CMP_BY_CONTENT;
+ else
+ return false;
return true;
}
@@ -251,12 +258,12 @@ void writeText(const OnError& value, std::string& output)
case ON_ERROR_IGNORE:
output = "Ignore";
break;
- case ON_ERROR_EXIT:
- output = "Exit";
- break;
case ON_ERROR_POPUP:
output = "Popup";
break;
+ case ON_ERROR_ABORT:
+ output = "Abort";
+ break;
}
}
@@ -265,14 +272,19 @@ bool readText(const std::string& input, OnError& value)
{
std::string tmp = input;
zen::trim(tmp);
- if (tmp == "Ignore")
- value = ON_ERROR_IGNORE;
- else if (tmp == "Exit")
- value = ON_ERROR_EXIT;
- else if (tmp == "Popup")
- value = ON_ERROR_POPUP;
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "Exit") //obsolete
+ value = ON_ERROR_ABORT;
else
- return false;
+
+ if (tmp == "Ignore")
+ value = ON_ERROR_IGNORE;
+ else if (tmp == "Popup")
+ value = ON_ERROR_POPUP;
+ else if (tmp == "Abort")
+ value = ON_ERROR_ABORT;
+ else
+ return false;
return true;
}
@@ -372,7 +384,7 @@ bool readText(const std::string& input, DeletionPolicy& value)
else if (tmp == "MoveToCustomDirectory")//obsolete name
value = DELETE_TO_VERSIONING;
else
- //------------------
+
if (tmp == "Permanent")
value = DELETE_PERMANENTLY;
else if (tmp == "RecycleBin")
@@ -390,14 +402,14 @@ void writeText(const SymLinkHandling& value, std::string& output)
{
switch (value)
{
- case SYMLINK_IGNORE:
- output = "Ignore";
+ case SYMLINK_EXCLUDE:
+ output = "Exclude";
break;
case SYMLINK_USE_DIRECTLY:
- output = "UseDirectly";
+ output = "Direct";
break;
case SYMLINK_FOLLOW_LINK:
- output = "FollowLink";
+ output = "Follow";
break;
}
}
@@ -407,58 +419,23 @@ bool readText(const std::string& input, SymLinkHandling& value)
{
std::string tmp = input;
zen::trim(tmp);
- if (tmp == "Ignore")
- value = SYMLINK_IGNORE;
- else if (tmp == "UseDirectly")
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "UseDirectly") //obsolete!
value = SYMLINK_USE_DIRECTLY;
- else if (tmp == "FollowLink")
+ else if (tmp == "FollowLink") //obsolete!
value = SYMLINK_FOLLOW_LINK;
+ else if (tmp == "Ignore") //obsolete!
+ value = SYMLINK_EXCLUDE;
else
- return false;
- return true;
-}
-
-template <> inline
-void writeText(const UnitTime& value, std::string& output)
-{
- switch (value)
- {
- case UTIME_NONE:
- output = "Inactive";
- break;
- case UTIME_TODAY:
- output = "Today";
- break;
- case UTIME_THIS_MONTH:
- output = "Month";
- break;
- case UTIME_THIS_YEAR:
- output = "Year";
- break;
- case UTIME_LAST_X_DAYS:
- output = "x-days";
- break;
- }
-}
-
-template <> inline
-bool readText(const std::string& input, UnitTime& value)
-{
- std::string tmp = input;
- zen::trim(tmp);
- if (tmp == "Inactive")
- value = UTIME_NONE;
- else if (tmp == "Today")
- value = UTIME_TODAY;
- else if (tmp == "Month")
- value = UTIME_THIS_MONTH;
- else if (tmp == "Year")
- value = UTIME_THIS_YEAR;
- else if (tmp == "x-days")
- value = UTIME_LAST_X_DAYS;
- else
- return false;
+ if (tmp == "Exclude")
+ value = SYMLINK_EXCLUDE;
+ else if (tmp == "Direct")
+ value = SYMLINK_USE_DIRECTLY;
+ else if (tmp == "Follow")
+ value = SYMLINK_FOLLOW_LINK;
+ else
+ return false;
return true;
}
@@ -557,7 +534,7 @@ void writeText(const UnitSize& value, std::string& output)
switch (value)
{
case USIZE_NONE:
- output = "Inactive";
+ output = "None";
break;
case USIZE_BYTE:
output = "Byte";
@@ -576,19 +553,71 @@ bool readText(const std::string& input, UnitSize& value)
{
std::string tmp = input;
zen::trim(tmp);
- if (tmp == "Inactive")
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "Inactive") //obsolete!
value = USIZE_NONE;
- else if (tmp == "Byte")
- value = USIZE_BYTE;
- else if (tmp == "KB")
- value = USIZE_KB;
- else if (tmp == "MB")
- value = USIZE_MB;
else
- return false;
+
+ if (tmp == "None")
+ value = USIZE_NONE;
+ else if (tmp == "Byte")
+ value = USIZE_BYTE;
+ else if (tmp == "KB")
+ value = USIZE_KB;
+ else if (tmp == "MB")
+ value = USIZE_MB;
+ else
+ return false;
return true;
}
+template <> inline
+void writeText(const UnitTime& value, std::string& output)
+{
+ switch (value)
+ {
+ case UTIME_NONE:
+ output = "None";
+ break;
+ case UTIME_TODAY:
+ output = "Today";
+ break;
+ case UTIME_THIS_MONTH:
+ output = "Month";
+ break;
+ case UTIME_THIS_YEAR:
+ output = "Year";
+ break;
+ case UTIME_LAST_X_DAYS:
+ output = "x-days";
+ break;
+ }
+}
+
+template <> inline
+bool readText(const std::string& input, UnitTime& value)
+{
+ std::string tmp = input;
+ zen::trim(tmp);
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "Inactive") //obsolete!
+ value = UTIME_NONE;
+ else
+
+ if (tmp == "None")
+ value = UTIME_NONE;
+ else if (tmp == "Today")
+ value = UTIME_TODAY;
+ else if (tmp == "Month")
+ value = UTIME_THIS_MONTH;
+ else if (tmp == "Year")
+ value = UTIME_THIS_YEAR;
+ else if (tmp == "x-days")
+ value = UTIME_LAST_X_DAYS;
+ else
+ return false;
+ return true;
+}
template <> inline
void writeText(const VersioningStyle& value, std::string& output)
@@ -599,7 +628,7 @@ void writeText(const VersioningStyle& value, std::string& output)
output = "Replace";
break;
case VER_STYLE_ADD_TIMESTAMP:
- output = "AddTimeStamp";
+ output = "TimeStamp";
break;
}
}
@@ -609,12 +638,17 @@ bool readText(const std::string& input, VersioningStyle& value)
{
std::string tmp = input;
zen::trim(tmp);
- if (tmp == "Replace")
- value = VER_STYLE_REPLACE;
- else if (tmp == "AddTimeStamp")
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "AddTimeStamp") //obsolete
value = VER_STYLE_ADD_TIMESTAMP;
else
- return false;
+
+ if (tmp == "Replace")
+ value = VER_STYLE_REPLACE;
+ else if (tmp == "TimeStamp")
+ value = VER_STYLE_ADD_TIMESTAMP;
+ else
+ return false;
return true;
}
@@ -624,8 +658,8 @@ void writeText(const DirectionConfig::Variant& value, std::string& output)
{
switch (value)
{
- case DirectionConfig::AUTOMATIC:
- output = "Automatic";
+ case DirectionConfig::TWOWAY:
+ output = "TwoWay";
break;
case DirectionConfig::MIRROR:
output = "Mirror";
@@ -644,16 +678,21 @@ bool readText(const std::string& input, DirectionConfig::Variant& value)
{
std::string tmp = input;
zen::trim(tmp);
- if (tmp == "Automatic")
- value = DirectionConfig::AUTOMATIC;
- else if (tmp == "Mirror")
- value = DirectionConfig::MIRROR;
- else if (tmp == "Update")
- value = DirectionConfig::UPDATE;
- else if (tmp == "Custom")
- value = DirectionConfig::CUSTOM;
+ warn_static("remove after migration. 2013.08.20")
+ if (tmp == "Automatic") //obsolete!
+ value = DirectionConfig::TWOWAY;
else
- return false;
+
+ if (tmp == "TwoWay")
+ value = DirectionConfig::TWOWAY;
+ else if (tmp == "Mirror")
+ value = DirectionConfig::MIRROR;
+ else if (tmp == "Update")
+ value = DirectionConfig::UPDATE;
+ else if (tmp == "Custom")
+ value = DirectionConfig::CUSTOM;
+ else
+ return false;
return true;
}
@@ -781,6 +820,10 @@ void readConfig(const XmlIn& in, DirectionConfig& directCfg)
inCustDir["RightNewer"](directCfg.custom.rightNewer);
inCustDir["Different" ](directCfg.custom.different);
inCustDir["Conflict" ](directCfg.custom.conflict);
+
+ warn_static("remove check after migration. 2013.08.17")
+ if (in["DetectMovedFiles"]) //new value: remove check
+ in["DetectMovedFiles"](directCfg.detectMovedFiles);
}
@@ -1052,7 +1095,7 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config)
//###########################################################
inWnd["ViewFilterDefault"](config.gui.viewFilterDefault);
- inWnd["Perspective" ](config.gui.guiPerspectiveLast);
+ inWnd["Perspective2" ](config.gui.guiPerspectiveLast);
std::vector<Zstring> tmp = splitFilterByLines(config.gui.defaultExclusionFilter); //default value
inGui["DefaultExclusionFilter"](tmp);
@@ -1236,6 +1279,8 @@ void writeConfig(const DirectionConfig& directCfg, XmlOut& out)
outCustDir["RightNewer"](directCfg.custom.rightNewer);
outCustDir["Different" ](directCfg.custom.different);
outCustDir["Conflict" ](directCfg.custom.conflict);
+
+ out["DetectMovedFiles"](directCfg.detectMovedFiles);
}
@@ -1431,7 +1476,7 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out)
//###########################################################
outWnd["ViewFilterDefault"](config.gui.viewFilterDefault);
- outWnd["Perspective" ](config.gui.guiPerspectiveLast);
+ outWnd["Perspective2" ](config.gui.guiPerspectiveLast);
outGui["DefaultExclusionFilter"](splitFilterByLines(config.gui.defaultExclusionFilter));
diff --git a/lib/process_xml.h b/lib/process_xml.h
index b189e51f..85f2d461 100644
--- a/lib/process_xml.h
+++ b/lib/process_xml.h
@@ -29,9 +29,9 @@ XmlType getXmlType(const Zstring& filename); //throw()
enum OnError
{
- ON_ERROR_POPUP,
ON_ERROR_IGNORE,
- ON_ERROR_EXIT
+ ON_ERROR_POPUP,
+ ON_ERROR_ABORT
};
enum OnGuiError
diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp
index f4049590..083b1007 100644
--- a/lib/resolve_path.cpp
+++ b/lib/resolve_path.cpp
@@ -115,12 +115,8 @@ private:
//================================================================================================
//SHGetKnownFolderPath: API available only with Windows Vista and later:
-#ifdef __MINGW32__ //MinGW is clueless about Vista...
-#define REFKNOWNFOLDERID const GUID&
+#ifdef __MINGW32__
#define KF_FLAG_DONT_VERIFY 0x00004000
- const GUID FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b} };
- const GUID FOLDERID_PublicDownloads = { 0x3d644c9b, 0x1fb8, 0x4f30, { 0x9b, 0x45, 0xf6, 0x70, 0x23, 0x5f, 0x79, 0xc0} };
- const GUID FOLDERID_QuickLaunch = { 0x52a4f021, 0x7b75, 0x48a9, { 0x9f, 0x6b, 0x4b, 0x87, 0xa2, 0x10, 0xbc, 0x8f} };
#endif
typedef HRESULT (STDAPICALLTYPE* SHGetKnownFolderPathFunc)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath);
const SysDllFun<SHGetKnownFolderPathFunc> shGetKnownFolderPath(L"Shell32.dll", "SHGetKnownFolderPath");
@@ -598,7 +594,7 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio
user account: <Domain>\<user> e.g. WIN-XP\ZenJu
network share: \\<server>\<share> e.g. \\WIN-XP\test
- Windows Command Line:
+ Windows Command Line:
- list *all* active network connections, including deviceless ones which are hidden in Explorer:
net use
- delete active connection:
diff --git a/lib/shadow.cpp b/lib/shadow.cpp
index 71372270..808b3b68 100644
--- a/lib/shadow.cpp
+++ b/lib/shadow.cpp
@@ -53,19 +53,19 @@ public:
//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(_("Cannot access Volume Shadow Copy Service."),
+ throw FileError(_("Cannot access the Volume Shadow Copy Service."),
_("Please use FreeFileSync 64-bit version to create shadow copies on this system."));
//check if shadow copy dll was loaded correctly
if (!createShadowCopy || !releaseShadowCopy || !getShadowVolume || !getLastError)
- throw FileError(_("Cannot access Volume Shadow Copy Service."),
+ throw FileError(_("Cannot access the Volume Shadow Copy Service."),
replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName())));
//---------------------------------------------------------------------------------------------------------
//start volume shadow copy service:
backupHandle = createShadowCopy(volumeNamePf.c_str());
if (!backupHandle)
- throw FileError(_("Cannot access Volume Shadow Copy Service."),
+ throw FileError(_("Cannot access the Volume Shadow Copy Service."),
getLastError() + std::wstring(L" Volume: ") + fmtFileName(volumeNamePf));
shadowVolPf = appendSeparator(getShadowVolume(backupHandle)); //shadowVolName NEVER has a trailing backslash
diff --git a/lib/soft_filter.h b/lib/soft_filter.h
index 1073cd43..010a8913 100644
--- a/lib/soft_filter.h
+++ b/lib/soft_filter.h
@@ -18,7 +18,7 @@ namespace zen
Semantics of SoftFilter:
1. It potentially may match only one side => it MUST NOT be applied while traversing a single folder to avoid mismatches
2. => it is applied after traversing and just marks rows, (NO deletions after comparison are allowed)
-3. => equivalent to a user temporarily (de-)selecting rows -> not relevant for <Automatic>-mode! ;)
+3. => equivalent to a user temporarily (de-)selecting rows => not relevant for <two way>-mode!
*/
class SoftFilter
@@ -61,14 +61,6 @@ private:
-
-
-
-
-
-
-
-
// ----------------------- implementation -----------------------
namespace zen
{
diff --git a/lib/versioning.cpp b/lib/versioning.cpp
index a6458196..65373499 100644
--- a/lib/versioning.cpp
+++ b/lib/versioning.cpp
@@ -120,23 +120,22 @@ void moveItemToVersioning(const Zstring& fullName, //throw FileError
//move source to target across volumes
-//no need to check if: - super-directories of target exist - source exists
+//no need to check if: - super-directories of target exist - source exists: done by moveItemToVersioning()
//if target already exists, it is overwritten, even if it is a different type, e.g. a directory!
template <class Function>
void moveObject(const Zstring& sourceFile, //throw FileError
const Zstring& targetFile,
Function copyDelete) //throw FileError; fallback if move failed
{
- assert(!dirExists(sourceFile) || symlinkExists(sourceFile)); //we process files and symlinks only
+ assert(fileExists(sourceFile) || symlinkExists(sourceFile) || !somethingExists(sourceFile)); //we process files and symlinks only
auto removeTarget = [&]
{
//remove target object
- if (fileExists(targetFile)) //file or symlink
- removeFile(targetFile); //throw FileError
- else if (dirExists(targetFile)) //directory or symlink
+ if (dirExists(targetFile)) //directory or dir-symlink
removeDirectory(targetFile); //throw FileError; we do not expect targetFile to be a directory in general => no callback required
- //else assert(false); -> may simply not exist if ErrorDifferentVolume!
+ else //file or (broken) file-symlink
+ removeFile(targetFile); //throw FileError
};
//first try to move directly without copying
@@ -212,17 +211,10 @@ private:
virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details)
{
- switch (getSymlinkType(fullName))
- {
- case SYMLINK_TYPE_DIR:
- dirs_.push_back(shortName);
- break;
-
- case SYMLINK_TYPE_FILE:
- case SYMLINK_TYPE_UNKNOWN:
- files_.push_back(shortName);
- break;
- }
+ if (dirExists(fullName)) //dir symlink
+ dirs_.push_back(shortName);
+ else //file symlink, broken symlink
+ files_.push_back(shortName);
return LINK_SKIP;
}
diff --git a/lib/xml_base.cpp b/lib/xml_base.cpp
index 123060f4..f504d19a 100644
--- a/lib/xml_base.cpp
+++ b/lib/xml_base.cpp
@@ -101,7 +101,7 @@ void xmlAccess::saveXmlDocument(const zen::XmlDoc& doc, const Zstring& filename)
FileOutput outputFile(filename, FileOutput::ACC_OVERWRITE); //throw FileError
outputFile.write(stream.c_str(), stream.length()); //
}
- catch (const FileError& error) //more detailed error messages than with wxWidgets
+ catch (const FileError& error)
{
throw FfsXmlError(error.toString());
}
bgstack15