diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:27:42 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:27:42 +0200 |
commit | b916407a2a06f8452e82b74dc44c54acbcc572b0 (patch) | |
tree | 46358e0bb035fca0f42edb4b5b8aa5f1613814af /lib | |
parent | 5.20 (diff) | |
download | FreeFileSync-b916407a2a06f8452e82b74dc44c54acbcc572b0.tar.gz FreeFileSync-b916407a2a06f8452e82b74dc44c54acbcc572b0.tar.bz2 FreeFileSync-b916407a2a06f8452e82b74dc44c54acbcc572b0.zip |
5.21
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ShadowCopy/Shadow_Server2003.vcxproj | 239 | ||||
-rw-r--r-- | lib/ShadowCopy/Shadow_Windows7.vcxproj | 20 | ||||
-rw-r--r-- | lib/ShadowCopy/Shadow_XP.vcxproj | 240 | ||||
-rw-r--r-- | lib/ShadowCopy/shadow.cpp | 19 | ||||
-rw-r--r-- | lib/Thumbnail/Thumbnail.vcxproj | 20 | ||||
-rw-r--r-- | lib/db_file.cpp | 398 | ||||
-rw-r--r-- | lib/db_file.h | 22 | ||||
-rw-r--r-- | lib/dir_exist_async.h | 3 | ||||
-rw-r--r-- | lib/dir_lock.cpp | 2 | ||||
-rw-r--r-- | lib/hard_filter.cpp | 85 | ||||
-rw-r--r-- | lib/hard_filter.h | 7 | ||||
-rw-r--r-- | lib/icon_buffer.cpp | 20 | ||||
-rw-r--r-- | lib/norm_filter.h | 4 | ||||
-rw-r--r-- | lib/osx_file_icon.mm | 2 | ||||
-rw-r--r-- | lib/parallel_scan.cpp | 36 | ||||
-rw-r--r-- | lib/parse_lng.h | 11 | ||||
-rw-r--r-- | lib/process_xml.cpp | 245 | ||||
-rw-r--r-- | lib/process_xml.h | 4 | ||||
-rw-r--r-- | lib/resolve_path.cpp | 8 | ||||
-rw-r--r-- | lib/shadow.cpp | 6 | ||||
-rw-r--r-- | lib/soft_filter.h | 10 | ||||
-rw-r--r-- | lib/versioning.cpp | 26 | ||||
-rw-r--r-- | lib/xml_base.cpp | 2 |
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()); } |