summaryrefslogtreecommitdiff
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/IFileOperation/FileOperation_Vista.vcxproj6
-rw-r--r--shared/IFileOperation/dll_main.cpp (renamed from shared/IFileOperation/dllmain.cpp)14
-rw-r--r--shared/IFileOperation/file_op.cpp (renamed from shared/IFileOperation/fileOp.cpp)107
-rw-r--r--shared/IFileOperation/file_op.h (renamed from shared/IFileOperation/fileOp.h)0
-rw-r--r--shared/ShadowCopy/Shadow_2003.vcxproj2
-rw-r--r--shared/ShadowCopy/Shadow_XP.vcxproj2
-rw-r--r--shared/ShadowCopy/dll_main.cpp (renamed from shared/ShadowCopy/dllmain.cpp)14
-rw-r--r--shared/ShadowCopy/shadow.cpp139
-rw-r--r--shared/ShadowCopy/shadow.h2
-rw-r--r--shared/Taskbar_Seven/Taskbar_Seven.vcxproj2
-rw-r--r--shared/Taskbar_Seven/dll_main.cpp (renamed from shared/Taskbar_Seven/dllmain.cpp)16
-rw-r--r--shared/Taskbar_Seven/taskbar.cpp30
-rw-r--r--shared/app_main.cpp (renamed from shared/appMain.cpp)6
-rw-r--r--shared/app_main.h (renamed from shared/appMain.h)2
-rw-r--r--shared/assert_static.h37
-rw-r--r--shared/build_info.h (renamed from shared/buildInfo.h)2
-rw-r--r--shared/checkExist.cpp54
-rw-r--r--shared/checkExist.h19
-rw-r--r--shared/check_exist.cpp83
-rw-r--r--shared/check_exist.h25
-rw-r--r--shared/com_error.h77
-rw-r--r--shared/com_ptr.h186
-rw-r--r--shared/com_util.h155
-rw-r--r--shared/custom_button.cpp (renamed from shared/customButton.cpp)2
-rw-r--r--shared/custom_button.h (renamed from shared/customButton.h)0
-rw-r--r--shared/custom_combo_box.cpp (renamed from shared/customComboBox.cpp)2
-rw-r--r--shared/custom_combo_box.h (renamed from shared/customComboBox.h)0
-rw-r--r--shared/custom_tooltip.cpp (renamed from shared/customTooltip.cpp)2
-rw-r--r--shared/custom_tooltip.h (renamed from shared/customTooltip.h)0
-rw-r--r--shared/debug_new.cpp (renamed from shared/debugNew.cpp)2
-rw-r--r--shared/debug_new.h (renamed from shared/debugNew.h)4
-rw-r--r--shared/dll_loader.cpp (renamed from shared/dllLoader.cpp)12
-rw-r--r--shared/dll_loader.h (renamed from shared/dllLoader.h)2
-rw-r--r--shared/drag_n_drop.cpp (renamed from shared/dragAndDrop.cpp)60
-rw-r--r--shared/drag_n_drop.h (renamed from shared/dragAndDrop.h)5
-rw-r--r--shared/file_error.h (renamed from shared/fileError.h)11
-rw-r--r--shared/file_handling.cpp (renamed from shared/fileHandling.cpp)879
-rw-r--r--shared/file_handling.h (renamed from shared/fileHandling.h)22
-rw-r--r--shared/file_id.cpp (renamed from shared/fileID.cpp)28
-rw-r--r--shared/file_id.h (renamed from shared/fileID.h)34
-rw-r--r--shared/file_io.cpp (renamed from shared/fileIO.cpp)52
-rw-r--r--shared/file_io.h (renamed from shared/fileIO.h)10
-rw-r--r--shared/file_traverser.cpp (renamed from shared/fileTraverser.cpp)48
-rw-r--r--shared/file_traverser.h (renamed from shared/fileTraverser.h)4
-rw-r--r--shared/global_func.cpp (renamed from shared/globalFunctions.cpp)10
-rw-r--r--shared/global_func.h (renamed from shared/globalFunctions.h)22
-rw-r--r--shared/guid.cpp18
-rw-r--r--shared/guid.h3
-rw-r--r--shared/help_provider.cpp (renamed from shared/helpProvider.cpp)8
-rw-r--r--shared/help_provider.h (renamed from shared/helpProvider.h)2
-rw-r--r--shared/localization.cpp24
-rw-r--r--shared/localization.h2
-rw-r--r--shared/lock.cpp8
-rw-r--r--shared/long_path_prefix.cpp (renamed from shared/longPathPrefix.cpp)8
-rw-r--r--shared/long_path_prefix.h (renamed from shared/longPathPrefix.h)2
-rw-r--r--shared/parallelCall.cpp159
-rw-r--r--shared/parallelCall.h34
-rw-r--r--shared/perf.h42
-rw-r--r--shared/recycler.cpp42
-rw-r--r--shared/recycler.h4
-rw-r--r--shared/serialize.cpp6
-rw-r--r--shared/serialize.h4
-rw-r--r--shared/shadow.cpp204
-rw-r--r--shared/shadow.h22
-rw-r--r--shared/signal_processing.h166
-rw-r--r--shared/standard_paths.cpp (renamed from shared/standardPaths.cpp)32
-rw-r--r--shared/standard_paths.h (renamed from shared/standardPaths.h)2
-rw-r--r--shared/staticAssert.h24
-rw-r--r--shared/string_conv.h (renamed from shared/stringConv.h)2
-rw-r--r--shared/system_constants.h (renamed from shared/systemConstants.h)2
-rw-r--r--shared/system_func.cpp (renamed from shared/systemFunctions.cpp)10
-rw-r--r--shared/system_func.h (renamed from shared/systemFunctions.h)2
-rw-r--r--shared/taskbar.cpp28
-rw-r--r--shared/taskbar.h2
-rw-r--r--shared/toggle_button.cpp (renamed from shared/toggleButton.cpp)2
-rw-r--r--shared/toggle_button.h (renamed from shared/toggleButton.h)0
-rw-r--r--shared/util.cpp42
-rw-r--r--shared/util.h12
-rw-r--r--shared/xml_base.cpp (renamed from shared/xmlBase.cpp)22
-rw-r--r--shared/xml_base.h (renamed from shared/xmlBase.h)14
-rw-r--r--shared/xml_error.h (renamed from shared/xmlError.h)2
-rw-r--r--shared/zstring.cpp36
-rw-r--r--shared/zstring.h55
83 files changed, 1989 insertions, 1249 deletions
diff --git a/shared/IFileOperation/FileOperation_Vista.vcxproj b/shared/IFileOperation/FileOperation_Vista.vcxproj
index 1cbb4a28..9f9a9c28 100644
--- a/shared/IFileOperation/FileOperation_Vista.vcxproj
+++ b/shared/IFileOperation/FileOperation_Vista.vcxproj
@@ -209,7 +209,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="dllmain.cpp">
+ <ClCompile Include="dll_main.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
@@ -223,10 +223,10 @@
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
</ClCompile>
- <ClCompile Include="fileOp.cpp" />
+ <ClCompile Include="file_op.cpp" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="fileOp.h" />
+ <ClInclude Include="file_op.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/shared/IFileOperation/dllmain.cpp b/shared/IFileOperation/dll_main.cpp
index 8dae897a..142e26a2 100644
--- a/shared/IFileOperation/dllmain.cpp
+++ b/shared/IFileOperation/dll_main.cpp
@@ -8,20 +8,18 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-
-BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
+//optional: add init/teardown logic here
+BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
{
- switch (ul_reason_for_call)
+ switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
+ case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
-
diff --git a/shared/IFileOperation/fileOp.cpp b/shared/IFileOperation/file_op.cpp
index 761ec06d..f37a2e66 100644
--- a/shared/IFileOperation/fileOp.cpp
+++ b/shared/IFileOperation/file_op.cpp
@@ -4,7 +4,9 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "fileOp.h"
+#include "file_op.h"
+#include "../com_ptr.h"
+#include "../com_error.h"
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
@@ -14,7 +16,7 @@
#include <algorithm>
#include <string>
#include <cstdio>
-#include <comdef.h>
+#include <comdef.h>
void writeString(const std::wstring& input, wchar_t* output, size_t outputBufferLen)
@@ -25,44 +27,6 @@ void writeString(const std::wstring& input, wchar_t* output, size_t outputBuffer
}
-std::wstring numberToHexString(long number)
-{
- wchar_t result[100];
- swprintf(result, 100, L"0x%08x", number);
- return std::wstring(result);
-}
-
-
-std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr)
-{
- std::wstring output(input);
- output += L" (";
- output += numberToHexString(hr);
- output += L": ";
- output += _com_error(hr).ErrorMessage();
- output += L")";
- return output;
-}
-
-
-//IShellItem resource management
-template <class T>
-class ReleaseAtExit
-{
-public:
- ReleaseAtExit(T*& item) : item_(item) {}
- ~ReleaseAtExit()
- {
- if (item_ != NULL)
- item_->Release();
- }
-private:
- ReleaseAtExit(const ReleaseAtExit&);
- ReleaseAtExit& operator=(const ReleaseAtExit&);
- T*& item_;
-};
-
-
namespace FileOp
{
std::wstring lastErrorMessage;
@@ -72,15 +36,16 @@ std::wstring lastErrorMessage;
bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
size_t fileNo) //size of fileNames array
{
+ using Util::ComPtr;
+ using Util::generateErrorMsg;
HRESULT hr;
// Create the IFileOperation interface
- IFileOperation* pfo = NULL;
- ReleaseAtExit<IFileOperation> dummy(pfo);
+ ComPtr<IFileOperation> fileOp;
hr = CoCreateInstance(CLSID_FileOperation,
NULL,
CLSCTX_ALL,
- IID_PPV_ARGS(&pfo));
+ IID_PPV_ARGS(fileOp.init()));
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
@@ -91,10 +56,10 @@ bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
// from being shown to the user during the
// operation. This includes error, confirmation
// and progress dialogs.
- hr = pfo->SetOperationFlags(FOF_ALLOWUNDO |
- FOF_NOCONFIRMATION |
- FOF_SILENT |
- FOF_NOERRORUI);
+ hr = fileOp->SetOperationFlags(FOF_ALLOWUNDO |
+ FOF_NOCONFIRMATION |
+ FOF_SILENT |
+ FOF_NOERRORUI);
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"SetOperationFlags\".", hr);
@@ -104,11 +69,10 @@ bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
for (size_t i = 0; i < fileNo; ++i)
{
//create file/folder item object
- IShellItem* psiFile = NULL;
- ReleaseAtExit<IShellItem> dummy2(psiFile);
+ ComPtr<IShellItem> psiFile;
hr = SHCreateItemFromParsingName(fileNames[i],
NULL,
- IID_PPV_ARGS(&psiFile));
+ IID_PPV_ARGS(psiFile.init()));
if (FAILED(hr))
{
std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n");
@@ -118,7 +82,7 @@ bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
return false;
}
- hr = pfo->DeleteItem(psiFile, NULL);
+ hr = fileOp->DeleteItem(psiFile.get(), NULL);
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"DeleteItem\".", hr);
@@ -127,7 +91,7 @@ bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
}
//perform actual operations
- hr = pfo->PerformOperations();
+ hr = fileOp->PerformOperations();
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"PerformOperations\".", hr);
@@ -136,7 +100,7 @@ bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
//check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors!
BOOL pfAnyOperationsAborted = FALSE;
- hr = pfo->GetAnyOperationsAborted(&pfAnyOperationsAborted);
+ hr = fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted);
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr);
@@ -156,15 +120,17 @@ bool FileOp::moveToRecycleBin(const wchar_t* fileNames[],
bool FileOp::copyFile(const wchar_t* sourceFile,
const wchar_t* targetFile)
{
+ using Util::ComPtr;
+ using Util::generateErrorMsg;
+
HRESULT hr;
// Create the IFileOperation interface
- IFileOperation* pfo = NULL;
- ReleaseAtExit<IFileOperation> dummy(pfo);
+ ComPtr<IFileOperation> fileOp;
hr = CoCreateInstance(CLSID_FileOperation,
NULL,
CLSCTX_ALL,
- IID_PPV_ARGS(&pfo));
+ IID_PPV_ARGS(fileOp.init()));
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
@@ -175,10 +141,10 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
// from being shown to the user during the
// operation. This includes error, confirmation
// and progress dialogs.
- hr = pfo->SetOperationFlags(FOF_NOCONFIRMATION |
- FOF_SILENT |
- FOFX_EARLYFAILURE |
- FOF_NOERRORUI);
+ hr = fileOp->SetOperationFlags(FOF_NOCONFIRMATION |
+ FOF_SILENT |
+ FOFX_EARLYFAILURE |
+ FOF_NOERRORUI);
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"SetOperationFlags\".", hr);
@@ -186,11 +152,10 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
}
//create source object
- IShellItem* psiSourceFile = NULL;
- ReleaseAtExit<IShellItem> dummy2(psiSourceFile);
+ ComPtr<IShellItem> psiSourceFile;
hr = SHCreateItemFromParsingName(sourceFile,
NULL,
- IID_PPV_ARGS(&psiSourceFile));
+ IID_PPV_ARGS(psiSourceFile.init()));
if (FAILED(hr))
{
std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for file:\n");
@@ -199,7 +164,7 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
return false;
}
- const size_t pos = std::wstring(targetFile).find_last_of(L'\\');
+ const size_t pos = std::wstring(targetFile).find_last_of(L'\\');
if (pos == std::wstring::npos)
{
lastErrorMessage = L"Target filename does not contain a path separator.";
@@ -210,11 +175,10 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
const std::wstring targetFileNameShort = targetFile + pos + 1;
//create target folder object
- IShellItem* psiTargetFolder = NULL;
- ReleaseAtExit<IShellItem> dummy3(psiTargetFolder);
- hr = SHCreateItemFromParsingName(targetFolder.c_str(),
+ ComPtr<IShellItem> psiTargetFolder;
+ hr = SHCreateItemFromParsingName(targetFolder.c_str(),
NULL,
- IID_PPV_ARGS(&psiTargetFolder));
+ IID_PPV_ARGS(psiTargetFolder.init()));
if (FAILED(hr))
{
std::wstring message(L"Error calling \"SHCreateItemFromParsingName\" for folder:\n");
@@ -224,7 +188,7 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
}
//schedule file copy operation
- hr = pfo->CopyItem(psiSourceFile, psiTargetFolder, targetFileNameShort.c_str(), NULL);
+ hr = fileOp->CopyItem(psiSourceFile.get(), psiTargetFolder.get(), targetFileNameShort.c_str(), NULL);
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"CopyItem\".", hr);
@@ -232,7 +196,7 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
}
//perform actual operations
- hr = pfo->PerformOperations();
+ hr = fileOp->PerformOperations();
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"PerformOperations\".", hr);
@@ -241,14 +205,13 @@ bool FileOp::copyFile(const wchar_t* sourceFile,
//check if errors occured: if FOFX_EARLYFAILURE is not used, PerformOperations() can return with success despite errors!
BOOL pfAnyOperationsAborted = FALSE;
- hr = pfo->GetAnyOperationsAborted(&pfAnyOperationsAborted);
+ hr = fileOp->GetAnyOperationsAborted(&pfAnyOperationsAborted);
if (FAILED(hr))
{
lastErrorMessage = generateErrorMsg(L"Error calling \"GetAnyOperationsAborted\".", hr);
return false;
}
-
if (pfAnyOperationsAborted == TRUE)
{
lastErrorMessage = L"Operation did not complete successfully.";
diff --git a/shared/IFileOperation/fileOp.h b/shared/IFileOperation/file_op.h
index 8fa6a75b..8fa6a75b 100644
--- a/shared/IFileOperation/fileOp.h
+++ b/shared/IFileOperation/file_op.h
diff --git a/shared/ShadowCopy/Shadow_2003.vcxproj b/shared/ShadowCopy/Shadow_2003.vcxproj
index b7d31ae4..5351cc1d 100644
--- a/shared/ShadowCopy/Shadow_2003.vcxproj
+++ b/shared/ShadowCopy/Shadow_2003.vcxproj
@@ -210,7 +210,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="dllmain.cpp">
+ <ClCompile Include="dll_main.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
diff --git a/shared/ShadowCopy/Shadow_XP.vcxproj b/shared/ShadowCopy/Shadow_XP.vcxproj
index 5c531a27..d096297a 100644
--- a/shared/ShadowCopy/Shadow_XP.vcxproj
+++ b/shared/ShadowCopy/Shadow_XP.vcxproj
@@ -211,7 +211,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="dllmain.cpp">
+ <ClCompile Include="dll_main.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
diff --git a/shared/ShadowCopy/dllmain.cpp b/shared/ShadowCopy/dll_main.cpp
index 8dae897a..142e26a2 100644
--- a/shared/ShadowCopy/dllmain.cpp
+++ b/shared/ShadowCopy/dll_main.cpp
@@ -8,20 +8,18 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-
-BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
+//optional: add init/teardown logic here
+BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
{
- switch (ul_reason_for_call)
+ switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
+ case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
-
diff --git a/shared/ShadowCopy/shadow.cpp b/shared/ShadowCopy/shadow.cpp
index 1fb78769..2e739146 100644
--- a/shared/ShadowCopy/shadow.cpp
+++ b/shared/ShadowCopy/shadow.cpp
@@ -8,6 +8,8 @@
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
+#include "../com_ptr.h"
+#include "../com_error.h"
#ifdef USE_SHADOW_XP
#include "xp/inc/vss.h"
@@ -15,7 +17,7 @@
#include "xp/inc/vsbackup.h"
#elif defined USE_SHADOW_2003
-#include "Server 2003/inc/vss.h"
+#include "Server 2003/inc/vss.h"
#include "Server 2003/inc/vswriter.h"
#include "Server 2003/inc/vsbackup.h"
#else
@@ -30,79 +32,37 @@ adapt!
//typedef GUID VSS_ID;
-
-//IShellItem resource management: better handled with boost::shared_ptr or CComPtr, but we avoid dependency with boost and ATL in this case
-template <class T>
-class ItemHolder
-{
-public:
- ItemHolder(T* item) : item_(item) {}
- ~ItemHolder()
- {
- if (item_)
- item_->Release();
- }
-
- T* release()
-{
-T* rv = item_;
-item_ = 0;
- return rv;
- }
-
- T* operator->() const
-{
- return item_;
- }
-private:
- ItemHolder(const ItemHolder&);
- ItemHolder& operator=(const ItemHolder&);
- T* item_;
-};
-
-
void writeString(const wchar_t* input, wchar_t* output, unsigned int outputBufferLen)
{
const size_t newSize = min(wcslen(input) + 1, outputBufferLen); //including null-termination
memcpy(output, input, newSize * sizeof(wchar_t));
- output[newSize-1] = 0; //if output buffer is too small...
-}
-
-
-std::wstring numberToHexString(const long number)
-{
- wchar_t result[100];
- swprintf(result, 100, L"0x%08x", number);
- return std::wstring(result);
+ output[newSize-1] = 0; //if output buffer is too small...
}
void writeErrorMsg(const wchar_t* input, HRESULT hr, wchar_t* output, unsigned int outputBufferLen)
{
- std::wstring formattedMsg(input);
- formattedMsg += L" (";
- formattedMsg += numberToHexString(hr);
- formattedMsg += L": ";
- formattedMsg += _com_error(hr).ErrorMessage();
- formattedMsg += L")";
-
- writeString(formattedMsg.c_str(), output, outputBufferLen);
+ writeString(Util::generateErrorMsg(input, hr).c_str(), output, outputBufferLen);
}
-bool Shadow::createShadowCopy(const wchar_t* volumeName,
+
+bool shadow::createShadowCopy(const wchar_t* volumeName,
wchar_t* shadowVolName,
unsigned int shadowBufferLen,
void** backupHandle,
wchar_t* errorMessage,
unsigned int errorBufferLen)
{
+ using Util::ComPtr;
+ using Util::generateErrorMsg;
+
//MessageBox(0, L"backup err", L"", 0); */
*backupHandle = NULL;
HRESULT hr = NULL;
- IVssBackupComponents* pBackupPtr = NULL;
- if (FAILED(hr = CreateVssBackupComponents(&pBackupPtr)))
+ ComPtr<IVssBackupComponents> backupComp;
+ if (FAILED(hr = CreateVssBackupComponents(backupComp.init())))
{
if (hr == E_ACCESSDENIED)
writeErrorMsg(L"The caller does not have sufficient backup privileges or is not an administrator.", hr, errorMessage, errorBufferLen);
@@ -111,97 +71,96 @@ bool Shadow::createShadowCopy(const wchar_t* volumeName,
return false;
}
- ItemHolder<IVssBackupComponents> pBackupComponents(pBackupPtr);
-
- if (FAILED(hr = pBackupComponents->InitializeForBackup()))
+ if (FAILED(hr = backupComp->InitializeForBackup()))
{
writeErrorMsg(L"Error calling \"InitializeForBackup\".", hr, errorMessage, errorBufferLen);
return false;
}
-
- if (FAILED(hr = pBackupComponents->SetBackupState(false, false, VSS_BT_FULL)))
+ if (FAILED(hr = backupComp->SetBackupState(false, false, VSS_BT_FULL)))
{
writeErrorMsg(L"Error calling \"SetBackupState\".", hr, errorMessage, errorBufferLen);
return false;
}
-
- IVssAsync* pWriteMetaData = NULL;
- if (FAILED(hr = pBackupComponents->GatherWriterMetadata( &pWriteMetaData )))
- { //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build)
+ ComPtr<IVssAsync> vssWriters;
+ if (FAILED(hr = backupComp->GatherWriterMetadata(vssWriters.init())))
+ {
+ //this can happen if XP-version of VSS is used on Windows Vista (which needs at least VSS-Server2003 build)
writeErrorMsg(L"Error calling \"GatherWriterMetadata\".", hr, errorMessage, errorBufferLen);
return false;
}
//wait for shadow copy writers to complete
- hr = pWriteMetaData->Wait();
- if (SUCCEEDED(hr))
- pWriteMetaData->QueryStatus(&hr, NULL); //check if the async operation succeeded...
-
- pWriteMetaData->Release();
- if (FAILED(hr))
+ if (FAILED(hr = vssWriters->Wait()))
{
- writeErrorMsg(L"Error calling \"ppWriteMetaData->Wait\".", hr, errorMessage, errorBufferLen);
+ writeErrorMsg(L"Error calling \"vssWriters->Wait\".", hr, errorMessage, errorBufferLen);
return false;
}
+ vssWriters->QueryStatus(&hr, NULL); //check if the async operation succeeded...
+ if (FAILED(hr))
+ {
+ writeErrorMsg(L"Error calling \"vssWriters->QueryStatus\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
VSS_ID snapshotSetId = {0};
- if (FAILED(hr = pBackupComponents->StartSnapshotSet( &snapshotSetId )))
+ if (FAILED(hr = backupComp->StartSnapshotSet(&snapshotSetId)))
{
writeErrorMsg(L"Error calling \"StartSnapshotSet\".", hr, errorMessage, errorBufferLen);
return false;
}
-
VSS_ID SnapShotId = {0};
- if (FAILED(hr = pBackupComponents->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId)))
+ if (FAILED(hr = backupComp->AddToSnapshotSet(const_cast<wchar_t*>(volumeName), GUID_NULL, &SnapShotId)))
{
writeErrorMsg(L"Error calling \"AddToSnapshotSet\".", hr, errorMessage, errorBufferLen);
return false;
}
-
- IVssAsync* pPrepare = NULL;
- if (FAILED(hr = pBackupComponents->PrepareForBackup( &pPrepare )))
+ ComPtr<IVssAsync> vssPrepare;
+ if (FAILED(hr = backupComp->PrepareForBackup(vssPrepare.init())))
{
writeErrorMsg(L"Error calling \"PrepareForBackup\".", hr, errorMessage, errorBufferLen);
return false;
}
- hr = pPrepare->Wait();
- if (SUCCEEDED(hr))
- pPrepare->QueryStatus(&hr, NULL); //check if the async operation succeeded...
+ if (FAILED(hr = vssPrepare->Wait()))
+ {
+ writeErrorMsg(L"Error calling \"vssPrepare->Wait\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
- pPrepare->Release();
+ vssPrepare->QueryStatus(&hr, NULL); //check if the async operation succeeded...
if (FAILED(hr))
{
- writeErrorMsg(L"Error calling \"pPrepare->Wait\".", hr, errorMessage, errorBufferLen);
+ writeErrorMsg(L"Error calling \"vssPrepare->QueryStatus\".", hr, errorMessage, errorBufferLen);
return false;
}
-
- IVssAsync* pDoShadowCopy = NULL;
- if (FAILED(hr = pBackupComponents->DoSnapshotSet(&pDoShadowCopy)))
+ ComPtr<IVssAsync> vssDoShadowCopy;
+ if (FAILED(hr = backupComp->DoSnapshotSet(vssDoShadowCopy.init())))
{
writeErrorMsg(L"Error calling \"DoSnapshotSet\".", hr, errorMessage, errorBufferLen);
return false;
}
- hr = pDoShadowCopy->Wait();
- if (SUCCEEDED(hr))
- pDoShadowCopy->QueryStatus(&hr, NULL); //check if the async operation succeeded...
+ if (FAILED(hr = vssDoShadowCopy->Wait()))
+ {
+ writeErrorMsg(L"Error calling \"vssDoShadowCopy->Wait\".", hr, errorMessage, errorBufferLen);
+ return false;
+ }
- pDoShadowCopy->Release();
+ vssDoShadowCopy->QueryStatus(&hr, NULL); //check if the async operation succeeded...
if (FAILED(hr))
{
- writeErrorMsg(L"Error calling \"pPrepare->Wait\".", hr, errorMessage, errorBufferLen);
+ writeErrorMsg(L"Error calling \"vssDoShadowCopy->QueryStatus\".", hr, errorMessage, errorBufferLen);
return false;
}
VSS_SNAPSHOT_PROP props;
- if (FAILED(hr = pBackupComponents->GetSnapshotProperties( SnapShotId, &props )))
+ if (FAILED(hr = backupComp->GetSnapshotProperties(SnapShotId, &props)))
{
writeErrorMsg(L"Error calling \"GetSnapshotProperties\".", hr, errorMessage, errorBufferLen);
return false;
@@ -212,13 +171,13 @@ bool Shadow::createShadowCopy(const wchar_t* volumeName,
VssFreeSnapshotProperties(&props);
- *backupHandle = pBackupComponents.release(); //release ownership
+ *backupHandle = backupComp.release(); //release ownership
return true;
}
-void Shadow::releaseShadowCopy(void* backupHandle)
+void shadow::releaseShadowCopy(void* backupHandle)
{
if (backupHandle != NULL)
static_cast<IVssBackupComponents*>(backupHandle)->Release();
diff --git a/shared/ShadowCopy/shadow.h b/shared/ShadowCopy/shadow.h
index 61d6ae7e..a9120e8a 100644
--- a/shared/ShadowCopy/shadow.h
+++ b/shared/ShadowCopy/shadow.h
@@ -14,7 +14,7 @@
#endif
-namespace Shadow
+namespace shadow
{
//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
diff --git a/shared/Taskbar_Seven/Taskbar_Seven.vcxproj b/shared/Taskbar_Seven/Taskbar_Seven.vcxproj
index db8b6feb..5b04a98c 100644
--- a/shared/Taskbar_Seven/Taskbar_Seven.vcxproj
+++ b/shared/Taskbar_Seven/Taskbar_Seven.vcxproj
@@ -208,7 +208,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="dllmain.cpp">
+ <ClCompile Include="dll_main.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
diff --git a/shared/Taskbar_Seven/dllmain.cpp b/shared/Taskbar_Seven/dll_main.cpp
index 18bb453d..142e26a2 100644
--- a/shared/Taskbar_Seven/dllmain.cpp
+++ b/shared/Taskbar_Seven/dll_main.cpp
@@ -7,21 +7,19 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-
-BOOL APIENTRY DllMain( HMODULE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
+//optional: add init/teardown logic here
+BOOL APIENTRY DllMain(HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
{
- switch (ul_reason_for_call)
+ switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
+ case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
break;
- }
+ }
return TRUE;
}
-
diff --git a/shared/Taskbar_Seven/taskbar.cpp b/shared/Taskbar_Seven/taskbar.cpp
index f5249e08..c9a2e7df 100644
--- a/shared/Taskbar_Seven/taskbar.cpp
+++ b/shared/Taskbar_Seven/taskbar.cpp
@@ -13,7 +13,7 @@
#include <map>
#include <string>
#include <comdef.h>
-
+#include "../com_error.h"
namespace
{
@@ -24,27 +24,7 @@ void writeString(const std::wstring& input, wchar_t* output, size_t outputBuffer
output[newSize-1] = 0; //if output buffer is too small...
}
-
-std::wstring numberToHexString(const long number)
-{
- wchar_t result[100];
- swprintf(result, 100, L"0x%08x", number);
- return std::wstring(result);
-}
-
-
-std::wstring writeErrorMsg(const wchar_t* input, HRESULT hr)
-{
- std::wstring output(input);
- output += L" (";
- output += numberToHexString(hr);
- output += L": ";
- output += _com_error(hr).ErrorMessage();
- output += L")";
- return output;
-}
-
-
+using Util::generateErrorMsg;
using TaskbarSeven::TBHandle;
typedef std::map<TBHandle, ITaskbarList3*> TaskBarHandleMap;
@@ -70,7 +50,7 @@ TaskbarSeven::TBHandle TaskbarSeven::init() //call on app initializaiton; return
IID_PPV_ARGS(&pto));
if (FAILED(hr))
{
- lastErrorMessage = writeErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
+ lastErrorMessage = generateErrorMsg(L"Error calling \"CoCreateInstance\".", hr);
return 0;
}
@@ -123,7 +103,7 @@ bool TaskbarSeven::setStatus(TBHandle handle,
flag); //[in] TBPFLAG tbpFlags
if (FAILED(hr))
{
- lastErrorMessage = writeErrorMsg(L"Error calling \"SetProgressState\".", hr);
+ lastErrorMessage = generateErrorMsg(L"Error calling \"SetProgressState\".", hr);
return false;
}
}
@@ -146,7 +126,7 @@ bool TaskbarSeven::setProgress(TBHandle handle,
total); //[in] ULONGLONG ullTotal
if (FAILED(hr))
{
- lastErrorMessage = writeErrorMsg(L"Error calling \"SetProgressValue\".", hr);
+ lastErrorMessage = generateErrorMsg(L"Error calling \"SetProgressValue\".", hr);
return false;
}
}
diff --git a/shared/appMain.cpp b/shared/app_main.cpp
index bf65e6c8..7225ba62 100644
--- a/shared/appMain.cpp
+++ b/shared/app_main.cpp
@@ -4,17 +4,17 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "appMain.h"
+#include "app_main.h"
#include <wx/window.h>
#include <wx/app.h>
-using namespace FreeFileSync;
+using namespace ffs3;
bool AppMainWindow::mainWndAct = false;
-void FreeFileSync::AppMainWindow::setMainWindow(wxWindow* window)
+void ffs3::AppMainWindow::setMainWindow(wxWindow* window)
{
wxTheApp->SetTopWindow(window);
wxTheApp->SetExitOnFrameDelete(true);
diff --git a/shared/appMain.h b/shared/app_main.h
index a4222a75..d0b76122 100644
--- a/shared/appMain.h
+++ b/shared/app_main.h
@@ -9,7 +9,7 @@
class wxWindow;
-namespace FreeFileSync
+namespace ffs3
{
//just some wrapper around a global variable representing the (logical) main application window
class AppMainWindow
diff --git a/shared/assert_static.h b/shared/assert_static.h
new file mode 100644
index 00000000..9eb94f3c
--- /dev/null
+++ b/shared/assert_static.h
@@ -0,0 +1,37 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef ASSERTSTATIC_H_INCLUDED
+#define ASSERTSTATIC_H_INCLUDED
+
+//compile time assert based on Loki (http://loki-lib.sourceforge.net)
+
+#ifdef NDEBUG
+
+#define assert_static(x) ((void)0)
+
+#else /* debugging enabled */
+namespace StaticCheckImpl
+{
+template<int>
+struct CompileTimeError;
+
+template<>
+struct CompileTimeError<true> {};
+}
+
+#define LOKI_CONCAT( X, Y ) LOKI_CONCAT_SUB( X, Y )
+#define LOKI_CONCAT_SUB( X, Y ) X##Y
+
+#define assert_static(expr) \
+ enum { LOKI_CONCAT(loki_enum_dummy_value, __LINE__) = sizeof(StaticCheckImpl::CompileTimeError<static_cast<bool>(expr) >) }
+
+/*#define assert_static(expr) \
+ { Loki::CompileTimeError<((expr) != 0)> Static_Assert_Has_Failed; (void)Static_Assert_Has_Failed; } */
+
+#endif
+
+#endif //ASSERTSTATIC_H_INCLUDED
diff --git a/shared/buildInfo.h b/shared/build_info.h
index 3aed3269..945284d2 100644
--- a/shared/buildInfo.h
+++ b/shared/build_info.h
@@ -7,7 +7,7 @@
#ifndef BUILDINFO_H_INCLUDED
#define BUILDINFO_H_INCLUDED
-namespace Utility
+namespace util
{
//determine build info
//seems to be safer than checking for _WIN64 (defined on windows for 64-bit compilations only) while _WIN32 is always defined (even for x64 compiler!)
diff --git a/shared/checkExist.cpp b/shared/checkExist.cpp
deleted file mode 100644
index 3f71afb8..00000000
--- a/shared/checkExist.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "checkExist.h"
-#include "parallelCall.h"
-#include "fileHandling.h"
-
-
-namespace
-{
-template <bool (*testExist)(const Zstring&)>
-class CheckObjectExists : public Async::Procedure
-{
-public:
- CheckObjectExists(const Zstring& filename) :
- filename_(filename.c_str()), //deep copy: worker thread may run longer than main! Avoid shared data
- isExisting(false) {}
-
- virtual void doWork()
- {
- isExisting = testExist(filename_); //throw()
- }
-
- bool doesExist() const //retrieve result
- {
- return isExisting;
- }
-
-private:
- const Zstring filename_; //no reference, lifetime not known
- bool isExisting;
-};
-
-
-template <bool (*testExist)(const Zstring&)>
-inline
-Utility::ResultExist objExists(const Zstring& filename, size_t timeout) //timeout in ms
-{
- typedef CheckObjectExists<testExist> CheckObjEx;
- boost::shared_ptr<CheckObjEx> proc(new CheckObjEx(filename));
-
- return Async::execute(proc, timeout) == Async::TIMEOUT ? Utility::EXISTING_TIMEOUT :
- (proc->doesExist() ? Utility::EXISTING_TRUE : Utility::EXISTING_FALSE);
-}
-}
-
-
-Utility::ResultExist Utility::fileExists(const Zstring& filename, size_t timeout) //timeout in ms
-{
- return objExists<FreeFileSync::fileExists>(filename, timeout);
-}
-
-
-Utility::ResultExist Utility::dirExists(const Zstring& dirname, size_t timeout) //timeout in ms
-{
- return objExists<FreeFileSync::dirExists>(dirname, timeout);
-}
diff --git a/shared/checkExist.h b/shared/checkExist.h
deleted file mode 100644
index bae5580c..00000000
--- a/shared/checkExist.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef CHECKEXIST_H_INCLUDED
-#define CHECKEXIST_H_INCLUDED
-
-#include "zstring.h"
-
-namespace Utility
-{
-enum ResultExist
-{
- EXISTING_TRUE,
- EXISTING_FALSE,
- EXISTING_TIMEOUT
-};
-
-ResultExist fileExists(const Zstring& filename, size_t timeout); //timeout in ms
-ResultExist dirExists( const Zstring& dirname, size_t timeout); //timeout in ms
-}
-
-#endif // CHECKEXIST_H_INCLUDED
diff --git a/shared/check_exist.cpp b/shared/check_exist.cpp
new file mode 100644
index 00000000..fcb865fd
--- /dev/null
+++ b/shared/check_exist.cpp
@@ -0,0 +1,83 @@
+#include "check_exist.h"
+#include "file_handling.h"
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+
+
+#ifdef __MINGW32__
+//oh well, nothing is for free...
+//https://svn.boost.org/trac/boost/ticket/4258
+#warning fix this issue at some time...
+extern "C" void tss_cleanup_implemented() {}
+#endif
+
+
+namespace
+{
+template <bool (*testExist)(const Zstring&)>
+class ExistenceChecker
+{
+public:
+ ExistenceChecker(const Zstring& filename, const boost::shared_ptr<bool>& isExisting) :
+ filename_(filename.c_str()), //deep copy: worker thread may run longer than main! avoid shared data
+ isExisting_(isExisting) {} //not accessed during thread run
+
+ void operator()()
+ {
+ *isExisting_ = testExist(filename_); //throw()
+ }
+
+private:
+ const Zstring filename_; //no reference, lifetime not known
+ boost::shared_ptr<bool> isExisting_;
+};
+
+
+template <bool (*fun)(const Zstring&)>
+util::ResultExist checkExistence(const Zstring& objName, size_t timeout) //timeout in ms
+{
+ using namespace util;
+
+ boost::shared_ptr<bool> isExisting(new bool(false));
+
+ ExistenceChecker<fun> task(objName, isExisting);
+ boost::thread worker(task);
+
+ if (worker.timed_join(boost::posix_time::milliseconds(timeout)))
+ return *isExisting ? EXISTING_TRUE : EXISTING_FALSE;
+ else
+ return EXISTING_TIMEOUT;
+ /*
+ main/worker thread may access different shared_ptr instances safely (even though they have the same target!)
+ http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm?sess=8153b05b34d890e02d48730db1ff7ddc#ThreadSafety
+ */
+
+#ifndef _MSC_VER
+#warning migrate this at some time...
+#endif
+ /*
+ unfortunately packaged_task/future is not mature enough to be used...
+ boost::packaged_task<bool> pt(boost::bind(fun, objName.c_str())); //attention: Zstring is not thread-safe => make deep copy
+ boost::unique_future<bool> fut = pt.get_future();
+
+ boost::thread worker(boost::move(pt)); //launch task on a thread
+
+ if (fut.timed_wait(boost::posix_time::milliseconds(timeout)))
+ return fut.get() ? EXISTING_TRUE : EXISTING_FALSE;
+ else
+ return EXISTING_TIMEOUT;
+ */
+}
+}
+
+
+util::ResultExist util::fileExists(const Zstring& filename, size_t timeout) //timeout in ms
+{
+ return ::checkExistence<ffs3::fileExists>(filename, timeout);
+}
+
+
+util::ResultExist util::dirExists(const Zstring& dirname, size_t timeout) //timeout in ms
+{
+ return ::checkExistence<ffs3::dirExists>(dirname, timeout);
+}
diff --git a/shared/check_exist.h b/shared/check_exist.h
new file mode 100644
index 00000000..7e9cecd8
--- /dev/null
+++ b/shared/check_exist.h
@@ -0,0 +1,25 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef CHECKEXIST_H_INCLUDED
+#define CHECKEXIST_H_INCLUDED
+
+#include "zstring.h"
+
+namespace util
+{
+enum ResultExist
+{
+ EXISTING_TRUE,
+ EXISTING_FALSE,
+ EXISTING_TIMEOUT
+};
+
+ResultExist fileExists(const Zstring& filename, size_t timeout); //timeout in ms
+ResultExist dirExists( const Zstring& dirname, size_t timeout); //timeout in ms
+}
+
+#endif // CHECKEXIST_H_INCLUDED
diff --git a/shared/com_error.h b/shared/com_error.h
new file mode 100644
index 00000000..ab365977
--- /dev/null
+++ b/shared/com_error.h
@@ -0,0 +1,77 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef COM_ERROR_HEADER
+#define COM_ERROR_HEADER
+
+#include <string>
+#include <cstdio>
+#include <comdef.h>
+
+namespace util
+{
+std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr);
+
+
+class ComException
+{
+public:
+ ComException(const std::wstring& message, HRESULT hr = NO_ERROR)
+ : message_(message), hr_(hr) {}
+
+ std::wstring show() const
+ {
+ return hr_ != NO_ERROR ? generateErrorMsg(message_, hr_) : message_;
+ }
+
+private:
+ const std::wstring message_;
+ const HRESULT hr_;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//################# implementation #####################
+inline
+std::wstring numberToHexString(long number)
+{
+ wchar_t result[100];
+ swprintf(result, 100, L"0x%08x", number);
+ return std::wstring(result);
+}
+
+
+inline
+std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr)
+{
+ std::wstring output(input);
+ output += L" (";
+ output += numberToHexString(hr);
+ output += L": ";
+ output += _com_error(hr).ErrorMessage();
+ output += L")";
+ return output;
+}
+}
+#endif //COM_ERROR_HEADER \ No newline at end of file
diff --git a/shared/com_ptr.h b/shared/com_ptr.h
new file mode 100644
index 00000000..1ce7eae6
--- /dev/null
+++ b/shared/com_ptr.h
@@ -0,0 +1,186 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef SMART_COM_PTR_H
+#define SMART_COM_PTR_H
+
+#include <Objbase.h>
+#include <algorithm>
+
+namespace util
+{
+/*
+ComPtr: RAII class handling COM objects
+
+Example:
+ --------
+ ComPtr<IUPnPDeviceFinder> devFinder;
+ if (FAILED(::CoCreateInstance(CLSID_UPnPDeviceFinder,
+ NULL,
+ CLSCTX_ALL,
+ IID_PPV_ARGS(devFinder.init()))))
+ return -1;
+
+ ComPtr<IEnumUnknown> devEnum = com_dynamic_cast<IEnumUnknown>(devColl);
+ if (!devEnum)
+ return -1;
+*/
+
+template <class T>
+class ComPtr
+{
+public:
+ ComPtr();
+ ComPtr(const ComPtr& rhs);
+ ComPtr& operator=(const ComPtr& rhs);
+ ~ComPtr();
+ T** init(); //get pointer for use with ::CoCreateInstance()
+ T* get() const;
+ T* release();
+ void swap(ComPtr& rhs); //throw()
+ T* operator->() const;
+ operator bool() const;
+
+private:
+ T* ptr;
+};
+
+
+template <class S, class T>
+ComPtr<S> com_dynamic_cast(const ComPtr<T>& other); //throw()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//################# Inline Implementation #############################
+
+template <class T>
+inline
+ComPtr<T>::ComPtr() : ptr(NULL) {}
+
+
+template <class T>
+inline
+ComPtr<T>::ComPtr(const ComPtr& rhs) : ptr(rhs.ptr)
+{
+ if (ptr)
+ ptr->AddRef();
+}
+
+
+template <class T>
+inline
+ComPtr<T>& ComPtr<T>::operator=(const ComPtr<T>& rhs)
+{
+ ComPtr(rhs).swap(*this);
+ return *this;
+}
+
+
+template <class T>
+inline
+ComPtr<T>::~ComPtr()
+{
+ if (ptr)
+ ptr->Release();
+}
+
+
+template <class T>
+inline
+T** ComPtr<T>::init() //get pointer for use with ::CoCreateInstance()
+{
+ ComPtr<T>().swap(*this);
+ return &ptr;
+}
+
+
+template <class T>
+inline
+T* ComPtr<T>::get() const
+{
+ return ptr;
+}
+
+
+template <class T>
+inline
+T* ComPtr<T>::release() //throw()
+{
+ T* tmp = ptr;
+ ptr = NULL;
+ return tmp;
+}
+
+
+template <class T>
+inline
+void ComPtr<T>::swap(ComPtr<T>& rhs) //throw()
+{
+ std::swap(ptr, rhs.ptr);
+}
+
+
+//we cannot specialize std::swap() for a class template and are not allowed to overload it => offer swap in own namespace
+template <class T>
+inline
+void swap(util::ComPtr<T>& lhs, util::ComPtr<T>& rhs)
+{
+ lhs.swap(rhs);
+}
+
+
+template <class T>
+inline
+T* ComPtr<T>::operator->() const
+{
+ return ptr;
+}
+
+
+template <class T>
+inline
+ComPtr<T>::operator bool() const
+{
+ return ptr != NULL;
+}
+
+
+template <class S, class T>
+inline
+ComPtr<S> com_dynamic_cast(const ComPtr<T>& other) //throw()
+{
+ ComPtr<S> outPtr;
+ if (other)
+ other->QueryInterface(IID_PPV_ARGS(outPtr.init()));
+ return outPtr;
+}
+
+}
+
+
+#endif //SMART_COM_PTR_H \ No newline at end of file
diff --git a/shared/com_util.h b/shared/com_util.h
new file mode 100644
index 00000000..bda3c732
--- /dev/null
+++ b/shared/com_util.h
@@ -0,0 +1,155 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#ifndef COM_UTILÎTY_HEADER
+#define COM_UTILÎTY_HEADER
+
+#include "com_ptr.h"
+#include <string>
+#include <cassert>
+
+
+namespace util
+{
+//get an enumeration interface as a std::vector of bound(!) ComPtr(s)
+template <class T, class U>
+std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& enumObj); //enumObj: must have the "_NewEnum" property that supports the IEnumUnknown interface
+
+/*
+extract text from com object member function returning a single BSTR: HRESULT ComInterface::MemFun([out] BSTR *pbstr);
+ Example: ComPtr<...> comObj =...;
+ std::wstring description = getText(comObj, &IUPnPDevice::get_Description);
+*/
+template <class T, class MemFun>
+std::wstring getText(ComPtr<T> comObj, MemFun memFun);
+
+
+//RAII class handling BSTR
+class Bstring
+{
+public:
+ Bstring(const std::wstring& str);
+ ~Bstring();
+
+ const BSTR get() const;
+
+private:
+ Bstring(const Bstring&); //not implemented
+ Bstring& operator=(const Bstring&); //
+
+ BSTR str_;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//############################ inline implemenatation ##################################
+template <class T, class U>
+inline
+std::vector<ComPtr<T> > convertEnum(const ComPtr<U>& enumObj)
+{
+ std::vector<ComPtr<T> > output;
+
+ if (enumObj)
+ {
+ ComPtr<IUnknown> unknown;
+ enumObj->get__NewEnum(unknown.init());
+ ComPtr<IEnumUnknown> enumUnknown = com_dynamic_cast<IEnumUnknown>(unknown);
+
+ assert(enumUnknown); //IEnumUnknown must be supported!
+ if (enumUnknown)
+ {
+ ComPtr<IUnknown> itemTmp;
+ while (enumUnknown->Next(1, itemTmp.init(), NULL) == S_OK) //returns S_FALSE == 1 when finished! Don't use SUCCEEDED()!!!
+ {
+ ComPtr<T> itemNew = com_dynamic_cast<T>(itemTmp);
+ if (itemNew)
+ output.push_back(itemNew);
+ }
+ }
+ }
+
+ return output;
+}
+
+
+template <class T, class MemFun>
+inline
+std::wstring getText(ComPtr<T> comObj, MemFun memFun)
+{
+ std::wstring text;
+ {
+ if (!comObj)
+ return std::wstring();
+
+ BSTR bstr = NULL;
+ if (FAILED((comObj.get()->*memFun)(&bstr)))
+ return std::wstring();
+
+ if (bstr) //NULL means "no text"
+ {
+ text = std::wstring(bstr, ::SysStringLen(bstr)); //correctly copy 0-characters
+ ::SysFreeString(bstr);
+ }
+ }
+ return text;
+}
+
+
+inline
+Bstring::Bstring(const std::wstring& str)
+{
+ str_ = ::SysAllocStringLen(str.data(), str.length()); //string::data() returns unmodified string potentially containing 0-values
+}
+
+
+inline
+Bstring::~Bstring()
+{
+ if (str_)
+ ::SysFreeString(str_);
+}
+
+
+inline
+const BSTR Bstring::get() const
+{
+ return str_;
+}
+}
+
+
+#endif //COM_UTILÎTY_HEADER \ No newline at end of file
diff --git a/shared/customButton.cpp b/shared/custom_button.cpp
index 4e897844..fec3b4bb 100644
--- a/shared/customButton.cpp
+++ b/shared/custom_button.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "customButton.h"
+#include "custom_button.h"
#include <wx/dcmemory.h>
#include <wx/image.h>
diff --git a/shared/customButton.h b/shared/custom_button.h
index b50dd4da..b50dd4da 100644
--- a/shared/customButton.h
+++ b/shared/custom_button.h
diff --git a/shared/customComboBox.cpp b/shared/custom_combo_box.cpp
index c27ce505..3c2a118c 100644
--- a/shared/customComboBox.cpp
+++ b/shared/custom_combo_box.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "customComboBox.h"
+#include "custom_combo_box.h"
CustomComboBox::CustomComboBox(wxWindow* parent,
diff --git a/shared/customComboBox.h b/shared/custom_combo_box.h
index 7db8cecf..7db8cecf 100644
--- a/shared/customComboBox.h
+++ b/shared/custom_combo_box.h
diff --git a/shared/customTooltip.cpp b/shared/custom_tooltip.cpp
index e483f7c7..b915b226 100644
--- a/shared/customTooltip.cpp
+++ b/shared/custom_tooltip.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "customTooltip.h"
+#include "custom_tooltip.h"
#include <wx/stattext.h>
#include <wx/sizer.h>
#include <wx/statbmp.h>
diff --git a/shared/customTooltip.h b/shared/custom_tooltip.h
index c6bf6cd6..c6bf6cd6 100644
--- a/shared/customTooltip.h
+++ b/shared/custom_tooltip.h
diff --git a/shared/debugNew.cpp b/shared/debug_new.cpp
index dad0cdd0..f5cd8368 100644
--- a/shared/debugNew.cpp
+++ b/shared/debug_new.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "debugNew.h"
+#include "debug_new.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include "DbgHelp.h"
diff --git a/shared/debugNew.h b/shared/debug_new.h
index 702cf774..c9c3dbf6 100644
--- a/shared/debugNew.h
+++ b/shared/debug_new.h
@@ -14,9 +14,9 @@
/*all this header does is to globally overwrite "operator new" to give some more detailed error messages and write memory dumps
Usage:
- - Include everywhere before any other file: $(ProjectDir)\shared\debugNew.h
+ - Include everywhere before any other file: $(ProjectDir)\shared\debug_new.h
For Minidumps:
- - Compile "debugNew.cpp"
+ - Compile "debug_new.cpp"
- Include library "Dbghelp.lib"
- Compile in Debug build (need Symbols and less restrictive Optimization)
*/
diff --git a/shared/dllLoader.cpp b/shared/dll_loader.cpp
index f5242d83..6aa48fd7 100644
--- a/shared/dllLoader.cpp
+++ b/shared/dll_loader.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "dllLoader.h"
+#include "dll_loader.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include <map>
#include <cassert>
@@ -26,9 +26,9 @@ public:
if (foundEntry == handles.end())
{
HINSTANCE newHandle = ::LoadLibrary(libraryName.c_str());
- handles.insert(std::make_pair(libraryName, newHandle));
+ if (newHandle != NULL)
+ handles.insert(std::make_pair(libraryName, newHandle));
- assert(handles.find(libraryName) != handles.end());
return newHandle;
}
else
@@ -41,16 +41,16 @@ private:
~DllHandler()
{
for (HandleMap::const_iterator i = handles.begin(); i != handles.end(); ++i)
- if (i->second != NULL) ::FreeLibrary(i->second);
+ ::FreeLibrary(i->second);
}
typedef std::map<std::wstring, HINSTANCE> HandleMap;
- HandleMap handles;
+ HandleMap handles; //only valid handles here!
};
}
-void* Utility::loadSymbol(const std::wstring& libraryName, const std::string& functionName)
+void* util::loadSymbol(const std::wstring& libraryName, const std::string& functionName)
{
const HINSTANCE libHandle = DllHandler::getInstance().getHandle(libraryName);
diff --git a/shared/dllLoader.h b/shared/dll_loader.h
index 318997d5..86723c68 100644
--- a/shared/dllLoader.h
+++ b/shared/dll_loader.h
@@ -9,7 +9,7 @@
#include <string>
-namespace Utility
+namespace util
{
//load function from a DLL library, e.g. from kernel32.dll
diff --git a/shared/dragAndDrop.cpp b/shared/drag_n_drop.cpp
index c5919e76..c4fc98f6 100644
--- a/shared/dragAndDrop.cpp
+++ b/shared/drag_n_drop.cpp
@@ -4,16 +4,16 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "dragAndDrop.h"
+#include "drag_n_drop.h"
#include <wx/dnd.h>
#include <wx/window.h>
#include <wx/combobox.h>
#include <wx/textctrl.h>
#include <wx/filepicker.h>
#include <wx/filename.h>
-#include "fileHandling.h"
-#include "stringConv.h"
-#include "checkExist.h"
+#include "file_handling.h"
+#include "string_conv.h"
+#include "check_exist.h"
//define new event type
@@ -27,17 +27,17 @@ typedef void (wxEvtHandler::*FFSFileDropEventFunction)(FFSFileDropEvent&);
class FFSFileDropEvent : public wxCommandEvent
{
public:
- FFSFileDropEvent(const wxString& nameDropped, const wxWindow* dropWindow) :
+ FFSFileDropEvent(const std::vector<wxString>& filesDropped, const wxWindow* dropWindow) :
wxCommandEvent(FFS_DROP_FILE_EVENT),
- nameDropped_(nameDropped),
+ filesDropped_(filesDropped),
dropWindow_(dropWindow) {}
virtual wxEvent* Clone() const
{
- return new FFSFileDropEvent(nameDropped_, dropWindow_);
+ return new FFSFileDropEvent(filesDropped_, dropWindow_);
}
- const wxString nameDropped_;
+ const std::vector<wxString> filesDropped_;
const wxWindow* dropWindow_;
};
@@ -50,15 +50,17 @@ public:
WindowDropTarget(wxWindow* dropWindow) :
dropWindow_(dropWindow) {}
- virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
+ virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& fileArray)
{
- if (!filenames.IsEmpty())
- {
- const wxString droppedFileName = filenames[0];
+ std::vector<wxString> filenames;
+ for (size_t i = 0; i < fileArray.GetCount(); ++i)
+ filenames.push_back(fileArray[i]);
+ if (!filenames.empty())
+ {
//create a custom event on drop window: execute event after file dropping is completed! (e.g. after mouse is released)
- FFSFileDropEvent evt(droppedFileName, dropWindow_);
- dropWindow_->AddPendingEvent(evt);
+ FFSFileDropEvent evt(filenames, dropWindow_);
+ dropWindow_->GetEventHandler()->AddPendingEvent(evt);
}
return false;
}
@@ -71,7 +73,7 @@ private:
//##############################################################################################################
-using FreeFileSync::DragDropOnMainDlg;
+using ffs3::DragDropOnMainDlg;
DragDropOnMainDlg::DragDropOnMainDlg(wxWindow* dropWindow1,
wxWindow* dropWindow2,
@@ -91,19 +93,22 @@ DragDropOnMainDlg::DragDropOnMainDlg(wxWindow* dropWindow1,
dropWindow2->Connect(FFS_DROP_FILE_EVENT, FFSFileDropEventHandler(DragDropOnMainDlg::OnFilesDropped), NULL, this);
//keep dirPicker and dirName synchronous
- dirName->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DragDropOnMainDlg::OnWriteDirManually ), NULL, this );
- dirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DragDropOnMainDlg::OnDirSelected ), NULL, this );
+ dirName-> Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DragDropOnMainDlg::OnWriteDirManually), NULL, this );
+ dirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler(DragDropOnMainDlg::OnDirSelected), NULL, this );
}
void DragDropOnMainDlg::OnFilesDropped(FFSFileDropEvent& event)
{
+ if (event.filesDropped_.empty())
+ return;
+
if ( this->dropWindow1_ == event.dropWindow_ || //file may be dropped on window 1 or 2
this->dropWindow2_ == event.dropWindow_)
{
- if (AcceptDrop(event.nameDropped_))
+ if (AcceptDrop(event.filesDropped_))
{
- wxString fileName = event.nameDropped_;
+ wxString fileName = event.filesDropped_[0];
if (wxDirExists(fileName))
{
dirName_->SetSelection(wxNOT_FOUND);
@@ -122,8 +127,6 @@ void DragDropOnMainDlg::OnFilesDropped(FFSFileDropEvent& event)
}
}
}
- else //should never be reached
- event.Skip();
}
@@ -131,7 +134,7 @@ void DragDropOnMainDlg::OnWriteDirManually(wxCommandEvent& event)
{
const Zstring newDir = getFormattedDirectoryName(wxToZ(event.GetString()));
- if (Utility::dirExists(newDir, 100) == Utility::EXISTING_TRUE) //potentially slow network access: wait 100 ms at most
+ if (util::dirExists(newDir, 100) == util::EXISTING_TRUE) //potentially slow network access: wait 100 ms at most
dirPicker_->SetPath(zToWx(newDir));
event.Skip();
@@ -150,7 +153,7 @@ void DragDropOnMainDlg::OnDirSelected(wxFileDirPickerEvent& event)
//##############################################################################################################
-using FreeFileSync::DragDropOnDlg;
+using ffs3::DragDropOnDlg;
DragDropOnDlg::DragDropOnDlg(wxWindow* dropWindow,
wxDirPickerCtrl* dirPicker,
@@ -173,9 +176,12 @@ DragDropOnDlg::DragDropOnDlg(wxWindow* dropWindow,
void DragDropOnDlg::OnFilesDropped(FFSFileDropEvent& event)
{
+ if (event.filesDropped_.empty())
+ return;
+
if (this->dropWindow_ == event.dropWindow_)
{
- wxString fileName = event.nameDropped_;
+ wxString fileName = event.filesDropped_[0];
if (wxDirExists(fileName))
{
dirName_->SetValue(fileName);
@@ -191,15 +197,13 @@ void DragDropOnDlg::OnFilesDropped(FFSFileDropEvent& event)
}
}
}
- else //should never be reached
- event.Skip();
}
void DragDropOnDlg::OnWriteDirManually(wxCommandEvent& event)
{
- const Zstring newDir = FreeFileSync::getFormattedDirectoryName(wxToZ(event.GetString()));
- if (Utility::dirExists(newDir, 100) == Utility::EXISTING_TRUE) //potentially slow network access: wait 100 ms at most
+ const Zstring newDir = ffs3::getFormattedDirectoryName(wxToZ(event.GetString()));
+ if (util::dirExists(newDir, 100) == util::EXISTING_TRUE) //potentially slow network access: wait 100 ms at most
dirPicker_->SetPath(zToWx(newDir));
event.Skip();
diff --git a/shared/dragAndDrop.h b/shared/drag_n_drop.h
index 4fc839c0..88bb68c4 100644
--- a/shared/dragAndDrop.h
+++ b/shared/drag_n_drop.h
@@ -8,6 +8,7 @@
#define DRAGANDDROP_H_INCLUDED
#include <wx/event.h>
+#include <vector>
class wxWindow;
class wxDirPickerCtrl;
@@ -19,7 +20,7 @@ class wxCommandEvent;
class wxFileDirPickerEvent;
-namespace FreeFileSync
+namespace ffs3
{
//add drag and drop functionality, coordinating a wxWindow, wxDirPickerCtrl, and wxComboBox/wxTextCtrl
@@ -33,7 +34,7 @@ public:
virtual ~DragDropOnMainDlg() {}
- virtual bool AcceptDrop(const wxString& dropName) = 0; //return true if drop should be processed
+ virtual bool AcceptDrop(const std::vector<wxString>& droppedFiles) = 0; //return true if drop should be processed
private:
void OnFilesDropped(FFSFileDropEvent& event);
diff --git a/shared/fileError.h b/shared/file_error.h
index 210d1029..2804e337 100644
--- a/shared/fileError.h
+++ b/shared/file_error.h
@@ -10,7 +10,7 @@
#include <wx/string.h>
-namespace FreeFileSync
+namespace ffs3
{
class FileError //Exception base class used to notify file/directory copy/delete errors
{
@@ -20,7 +20,7 @@ public:
virtual ~FileError() {}
- const wxString& show() const
+ const wxString& msg() const
{
return errorMessage;
}
@@ -28,6 +28,13 @@ public:
private:
const wxString errorMessage;
};
+
+
+class ErrorNotExisting : public FileError
+{
+public:
+ ErrorNotExisting(const wxString& message) : FileError(message) {}
+};
}
#endif // FILEERROR_H_INCLUDED
diff --git a/shared/fileHandling.cpp b/shared/file_handling.cpp
index 2a8af46a..3f56abe4 100644
--- a/shared/fileHandling.cpp
+++ b/shared/file_handling.cpp
@@ -4,38 +4,40 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "fileHandling.h"
+#include "file_handling.h"
#include <wx/intl.h>
-#include "systemFunctions.h"
-#include "globalFunctions.h"
-#include "systemConstants.h"
-#include "fileTraverser.h"
+#include "system_func.h"
+#include "global_func.h"
+#include "system_constants.h"
+#include "file_traverser.h"
#include <boost/bind.hpp>
#include <algorithm>
#include <wx/datetime.h>
-#include "stringConv.h"
+#include "string_conv.h"
#include <wx/utils.h>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include "loki/TypeManip.h"
#include "loki/ScopeGuard.h"
+#include <map>
#ifdef FFS_WIN
-#include "dllLoader.h"
+#include "dll_loader.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include "longPathPrefix.h"
+#include "long_path_prefix.h"
+#include <Aclapi.h>
#elif defined FFS_LINUX
#include <sys/stat.h>
-#include "fileIO.h"
+#include "file_io.h"
#include <time.h>
#include <utime.h>
#include <cerrno>
#include <sys/time.h>
#endif
-using FreeFileSync::FileError;
+using ffs3::FileError;
namespace
@@ -80,7 +82,7 @@ bool replaceMacro(wxString& macro) //macro without %-characters, return true if
if (macro.CmpNoCase(wxT("time")) == 0)
{
macro = wxDateTime::Now().FormatISOTime();
- macro.Replace(wxT(":"), wxT("-"));
+ macro.Replace(wxT(":"), wxT(""));
return true;
}
@@ -90,6 +92,24 @@ bool replaceMacro(wxString& macro) //macro without %-characters, return true if
return true;
}
+ if (macro.CmpNoCase(wxT("month")) == 0)
+ {
+ macro = wxDateTime::Now().Format(wxT("%B"));
+ return true;
+ }
+
+ if (macro.CmpNoCase(wxT("week")) == 0)
+ {
+ macro = wxDateTime::Now().Format(wxT("%U"));
+ return true;
+ }
+
+ if (macro.CmpNoCase(wxT("year")) == 0)
+ {
+ macro = wxDateTime::Now().Format(wxT("%Y"));
+ return true;
+ }
+
//try to apply environment variables
wxString envValue;
if (wxGetEnv(macro, &envValue))
@@ -143,7 +163,7 @@ void expandMacros(wxString& text)
}
-Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname)
+Zstring ffs3::getFormattedDirectoryName(const Zstring& dirname)
{
//Formatting is needed since functions expect the directory to end with '\' to be able to split the relative names.
//note: don't do directory formatting with wxFileName, as it doesn't respect //?/ - prefix!
@@ -170,14 +190,14 @@ Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname)
*/
dirnameTmp = zToWx(resolveRelativePath(wxToZ(dirnameTmp)));
- if (!dirnameTmp.EndsWith(zToWx(globalFunctions::FILE_NAME_SEPARATOR)))
- dirnameTmp += zToWx(globalFunctions::FILE_NAME_SEPARATOR);
+ if (!dirnameTmp.EndsWith(zToWx(common::FILE_NAME_SEPARATOR)))
+ dirnameTmp += zToWx(common::FILE_NAME_SEPARATOR);
return wxToZ(dirnameTmp);
}
-bool FreeFileSync::fileExists(const Zstring& filename)
+bool ffs3::fileExists(const Zstring& filename)
{
//symbolic links (broken or not) are also treated as existing files!
#ifdef FFS_WIN
@@ -194,7 +214,7 @@ bool FreeFileSync::fileExists(const Zstring& filename)
}
-bool FreeFileSync::dirExists(const Zstring& dirname)
+bool ffs3::dirExists(const Zstring& dirname)
{
//symbolic links (broken or not) are also treated as existing directories!
#ifdef FFS_WIN
@@ -212,7 +232,7 @@ bool FreeFileSync::dirExists(const Zstring& dirname)
}
-bool FreeFileSync::symlinkExists(const Zstring& objname)
+bool ffs3::symlinkExists(const Zstring& objname)
{
#ifdef FFS_WIN
const DWORD ret = ::GetFileAttributes(applyLongPathPrefix(objname).c_str());
@@ -226,7 +246,7 @@ bool FreeFileSync::symlinkExists(const Zstring& objname)
}
-bool FreeFileSync::somethingExists(const Zstring& objname) //throw() check whether any object with this name exists
+bool ffs3::somethingExists(const Zstring& objname) //throw() check whether any object with this name exists
{
#ifdef FFS_WIN
return ::GetFileAttributes(applyLongPathPrefix(objname).c_str()) != INVALID_FILE_ATTRIBUTES;
@@ -244,7 +264,7 @@ namespace
wxULongLong getFileSizeSymlink(const Zstring& linkName) //throw (FileError)
{
//open handle to target of symbolic link
- const HANDLE hFile = ::CreateFile(FreeFileSync::applyLongPathPrefix(linkName).c_str(),
+ const HANDLE hFile = ::CreateFile(ffs3::applyLongPathPrefix(linkName).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -260,14 +280,14 @@ wxULongLong getFileSizeSymlink(const Zstring& linkName) //throw (FileError)
return wxULongLong(fileInfoByHandle.nFileSizeHigh, fileInfoByHandle.nFileSizeLow);
}
- const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + FreeFileSync::zToWx(linkName) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + ffs3::zToWx(linkName) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
#endif
-wxULongLong FreeFileSync::getFilesize(const Zstring& filename) //throw (FileError)
+wxULongLong ffs3::getFilesize(const Zstring& filename) //throw (FileError)
{
#ifdef FFS_WIN
WIN32_FIND_DATA fileMetaData;
@@ -275,7 +295,7 @@ wxULongLong FreeFileSync::getFilesize(const Zstring& filename) //throw (FileErro
if (searchHandle == INVALID_HANDLE_VALUE)
{
const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(filename) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
::FindClose(searchHandle);
@@ -290,7 +310,7 @@ wxULongLong FreeFileSync::getFilesize(const Zstring& filename) //throw (FileErro
if (::stat(filename.c_str(), &fileInfo) != 0) //follow symbolic links
{
const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(filename) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
return fileInfo.st_size;
@@ -313,8 +333,8 @@ DWORD retrieveVolumeSerial(const Zstring& pathName) //return 0 on error!
return 0;
Zstring volumePath = buffer.get();
- if (!volumePath.EndsWith(globalFunctions::FILE_NAME_SEPARATOR))
- volumePath += globalFunctions::FILE_NAME_SEPARATOR;
+ if (!volumePath.EndsWith(common::FILE_NAME_SEPARATOR))
+ volumePath += common::FILE_NAME_SEPARATOR;
DWORD volumeSerial = 0;
if (!::GetVolumeInformation(volumePath.c_str(), //__in_opt LPCTSTR lpRootPathName,
@@ -336,13 +356,13 @@ dev_t retrieveVolumeSerial(const Zstring& pathName) //return 0 on error!
Zstring volumePathName = pathName;
//remove trailing slash
- if (volumePathName.size() > 1 && volumePathName.EndsWith(globalFunctions::FILE_NAME_SEPARATOR)) //exception: allow '/'
- volumePathName = volumePathName.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
+ if (volumePathName.size() > 1 && volumePathName.EndsWith(common::FILE_NAME_SEPARATOR)) //exception: allow '/'
+ volumePathName = volumePathName.BeforeLast(common::FILE_NAME_SEPARATOR);
struct stat fileInfo;
while (::lstat(volumePathName.c_str(), &fileInfo) != 0)
{
- volumePathName = volumePathName.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR); //returns empty string if ch not found
+ volumePathName = volumePathName.BeforeLast(common::FILE_NAME_SEPARATOR); //returns empty string if ch not found
if (volumePathName.empty())
return 0; //this includes path "/" also!
}
@@ -353,7 +373,7 @@ dev_t retrieveVolumeSerial(const Zstring& pathName) //return 0 on error!
}
-FreeFileSync::ResponseSameVol FreeFileSync::onSameVolume(const Zstring& folderLeft, const Zstring& folderRight) //throw()
+ffs3::ResponseSameVol ffs3::onSameVolume(const Zstring& folderLeft, const Zstring& folderRight) //throw()
{
#ifdef FFS_WIN
typedef DWORD VolSerial;
@@ -369,7 +389,7 @@ FreeFileSync::ResponseSameVol FreeFileSync::onSameVolume(const Zstring& folderLe
}
-void FreeFileSync::removeFile(const Zstring& filename) //throw (FileError);
+void ffs3::removeFile(const Zstring& filename) //throw (FileError);
{
//no error situation if file is not existing! manual deletion relies on it!
if (!somethingExists(filename))
@@ -395,13 +415,13 @@ void FreeFileSync::removeFile(const Zstring& filename) //throw (FileError);
}
wxString errorMessage = wxString(_("Error deleting file:")) + wxT("\n\"") + zToWx(filename) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
#elif defined FFS_LINUX
if (::unlink(filename.c_str()) != 0)
{
wxString errorMessage = wxString(_("Error deleting file:")) + wxT("\n\"") + zToWx(filename) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
#endif
}
@@ -409,7 +429,7 @@ void FreeFileSync::removeFile(const Zstring& filename) //throw (FileError);
namespace
{
-struct ErrorDifferentVolume : public FreeFileSync::FileError
+struct ErrorDifferentVolume : public ffs3::FileError
{
ErrorDifferentVolume(const wxString& message) : FileError(message) {}
};
@@ -425,7 +445,7 @@ struct ErrorDifferentVolume : public FreeFileSync::FileError
//throw (FileError); ErrorDifferentVolume if it is due to moving file to another volume
void renameFileInternal(const Zstring& oldName, const Zstring& newName) //throw (FileError, ErrorDifferentVolume)
{
- using namespace FreeFileSync; //for zToWx()
+ using namespace ffs3; //for zToWx()
#ifdef FFS_WIN
const Zstring oldNameFmt = applyLongPathPrefix(oldName);
@@ -467,7 +487,7 @@ void renameFileInternal(const Zstring& oldName, const Zstring& newName) //throw
}
const wxString errorMessage = wxString(_("Error moving file:")) + wxT("\n\"") + zToWx(oldName) + wxT("\" ->\n\"") + zToWx(newName) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted();
+ wxT("\n\n") + ffs3::getLastErrorFormatted();
if (::GetLastError() == ERROR_NOT_SAME_DEVICE)
throw ErrorDifferentVolume(errorMessage);
else
@@ -479,7 +499,7 @@ void renameFileInternal(const Zstring& oldName, const Zstring& newName) //throw
if (::rename(oldName.c_str(), newName.c_str()) != 0)
{
const wxString errorMessage = wxString(_("Error moving file:")) + wxT("\n\"") + zToWx(oldName) + wxT("\" ->\n\"") + zToWx(newName) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted();
+ wxT("\n\n") + ffs3::getLastErrorFormatted();
if (errno == EXDEV)
throw ErrorDifferentVolume(errorMessage);
else
@@ -506,7 +526,7 @@ void renameFileInternalNoThrow(const Zstring& oldName, const Zstring& newName) /
template <typename Function>
Zstring getFilenameFmt(const Zstring& filename, Function fun) //throw(); returns empty string on error
{
- const Zstring filenameFmt = FreeFileSync::applyLongPathPrefix(filename);
+ const Zstring filenameFmt = ffs3::applyLongPathPrefix(filename);
const DWORD bufferSize = fun(filenameFmt.c_str(), NULL, 0);
if (bufferSize == 0)
@@ -526,10 +546,10 @@ Zstring getFilenameFmt(const Zstring& filename, Function fun) //throw(); returns
Zstring createTemp8Dot3Name(const Zstring& fileName) //find a unique 8.3 short name
{
- const Zstring pathPrefix = fileName.Find(globalFunctions::FILE_NAME_SEPARATOR) != Zstring::npos ?
- (fileName.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) + globalFunctions::FILE_NAME_SEPARATOR) : Zstring();
+ const Zstring pathPrefix = fileName.Find(common::FILE_NAME_SEPARATOR) != Zstring::npos ?
+ (fileName.BeforeLast(common::FILE_NAME_SEPARATOR) + common::FILE_NAME_SEPARATOR) : Zstring();
- Zstring extension = fileName.AfterLast(globalFunctions::FILE_NAME_SEPARATOR).AfterLast(DefaultChar('.')); //extension needn't contain reasonable data
+ Zstring extension = fileName.AfterLast(common::FILE_NAME_SEPARATOR).AfterLast(DefaultChar('.')); //extension needn't contain reasonable data
if (extension.empty())
extension = DefaultStr("FFS");
extension.Truncate(3);
@@ -537,7 +557,7 @@ Zstring createTemp8Dot3Name(const Zstring& fileName) //find a unique 8.3 short n
for (int index = 0; index < 100000000; ++index) //filename must be representable by <= 8 characters
{
const Zstring output = pathPrefix + numberToZstring(index) + DefaultChar('.') + extension;
- if (!FreeFileSync::somethingExists(output)) //ensure uniqueness
+ if (!ffs3::somethingExists(output)) //ensure uniqueness
return output;
}
@@ -548,26 +568,26 @@ Zstring createTemp8Dot3Name(const Zstring& fileName) //find a unique 8.3 short n
//try to handle issues with already existing short 8.3 file names on Windows 7
bool fix8Dot3NameClash(const Zstring& oldName, const Zstring& newName) //throw (FileError); return "true" if rename operation succeeded
{
- using namespace FreeFileSync;
+ using namespace ffs3;
- if (newName.Find(globalFunctions::FILE_NAME_SEPARATOR) == Zstring::npos)
+ if (newName.Find(common::FILE_NAME_SEPARATOR) == Zstring::npos)
return false;
- if (FreeFileSync::somethingExists(newName)) //name OR directory!
+ if (ffs3::somethingExists(newName)) //name OR directory!
{
- const Zstring fileNameOrig = newName.AfterLast(globalFunctions::FILE_NAME_SEPARATOR); //returns the whole string if ch not found
- const Zstring fileNameShort = getFilenameFmt(newName, ::GetShortPathName).AfterLast(globalFunctions::FILE_NAME_SEPARATOR); //throw() returns empty string on error
- const Zstring fileNameLong = getFilenameFmt(newName, ::GetLongPathName).AfterLast(globalFunctions::FILE_NAME_SEPARATOR); //throw() returns empty string on error
+ const Zstring fileNameOrig = newName.AfterLast(common::FILE_NAME_SEPARATOR); //returns the whole string if ch not found
+ const Zstring fileNameShort = getFilenameFmt(newName, ::GetShortPathName).AfterLast(common::FILE_NAME_SEPARATOR); //throw() returns empty string on error
+ const Zstring fileNameLong = getFilenameFmt(newName, ::GetLongPathName).AfterLast(common::FILE_NAME_SEPARATOR); //throw() returns empty string on error
if ( !fileNameShort.empty() &&
!fileNameLong.empty() &&
- fileNameOrig.cmpFileName(fileNameShort) == 0 &&
- fileNameShort.cmpFileName(fileNameLong) != 0)
+ cmpFileName(fileNameOrig, fileNameShort) == 0 &&
+ cmpFileName(fileNameShort, fileNameLong) != 0)
{
//we detected an event where newName is in shortname format (although it is intended to be a long name) and
//writing target file failed because another unrelated file happens to have the same short name
- const Zstring newNameFullPathLong = newName.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) + globalFunctions::FILE_NAME_SEPARATOR +
+ const Zstring newNameFullPathLong = newName.BeforeLast(common::FILE_NAME_SEPARATOR) + common::FILE_NAME_SEPARATOR +
fileNameLong;
//find another name in short format: this ensures the actual short name WILL be renamed as well!
@@ -575,7 +595,7 @@ bool fix8Dot3NameClash(const Zstring& oldName, const Zstring& newName) //throw
//move already existing short name out of the way for now
renameFileInternal(newNameFullPathLong, parkedTarget); //throw (FileError, ErrorDifferentVolume);
- //DON'T call FreeFileSync::renameFile() to avoid reentrance!
+ //DON'T call ffs3::renameFile() to avoid reentrance!
//schedule cleanup; the file system should assign this unrelated file a new (unique) short name
Loki::ScopeGuard guard = Loki::MakeGuard(renameFileInternalNoThrow, parkedTarget, newNameFullPathLong);//equivalent to Boost.ScopeExit in this case
@@ -592,7 +612,7 @@ bool fix8Dot3NameClash(const Zstring& oldName, const Zstring& newName) //throw
//rename file: no copying!!!
-void FreeFileSync::renameFile(const Zstring& oldName, const Zstring& newName) //throw (FileError, ErrorDifferentVolume);
+void ffs3::renameFile(const Zstring& oldName, const Zstring& newName) //throw (FileError, ErrorDifferentVolume);
{
try
{
@@ -609,9 +629,9 @@ void FreeFileSync::renameFile(const Zstring& oldName, const Zstring& newName) //
}
-using FreeFileSync::MoveFileCallback;
+using ffs3::MoveFileCallback;
-class CopyCallbackImpl : public FreeFileSync::CopyFileCallback //callback functionality
+class CopyCallbackImpl : public ffs3::CopyFileCallback //callback functionality
{
public:
CopyCallbackImpl(MoveFileCallback* callback) : moveCallback(callback) {}
@@ -634,7 +654,7 @@ private:
};
-void FreeFileSync::moveFile(const Zstring& sourceFile, const Zstring& targetFile, MoveFileCallback* callback) //throw (FileError);
+void ffs3::moveFile(const Zstring& sourceFile, const Zstring& targetFile, MoveFileCallback* callback) //throw (FileError);
{
if (somethingExists(targetFile)) //test file existence: e.g. Linux might silently overwrite existing symlinks
{
@@ -660,6 +680,7 @@ void FreeFileSync::moveFile(const Zstring& sourceFile, const Zstring& targetFile
copyFile(sourceFile,
targetFile,
true, //copy symbolic links
+ false, //dont copy filesystem permissions
#ifdef FFS_WIN
NULL, //supply handler for making shadow copies
#endif
@@ -671,7 +692,7 @@ void FreeFileSync::moveFile(const Zstring& sourceFile, const Zstring& targetFile
}
-class TraverseOneLevel : public FreeFileSync::TraverseCallback
+class TraverseOneLevel : public ffs3::TraverseCallback
{
public:
typedef std::vector<std::pair<Zstring, Zstring> > NamePair;
@@ -710,12 +731,12 @@ private:
void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExistingDirs, MoveFileCallback* callback) //throw (FileError);
{
- using namespace FreeFileSync;
+ using namespace ffs3;
//handle symbolic links
if (symlinkExists(sourceDir))
{
- createDirectory(targetDir, sourceDir, true); //copy symbolic link
+ createDirectory(targetDir, sourceDir, true, false); //copy symbolic link, don't copy permissions
removeDirectory(sourceDir); //if target is already another symlink or directory, sourceDir-symlink is silently deleted
return;
}
@@ -740,7 +761,7 @@ void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool
catch (const ErrorDifferentVolume&) {}
//create target
- createDirectory(targetDir, sourceDir, false); //throw (FileError);
+ createDirectory(targetDir, sourceDir, false, false); //throw (FileError); don't copy permissions
}
//call back once per folder
@@ -763,13 +784,13 @@ void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool
TraverseOneLevel traverseCallback(fileList, dirList);
traverseFolder(sourceDir, false, &traverseCallback); //traverse one level, don't follow symlinks
- const Zstring targetDirFormatted = targetDir.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ? //ends with path separator
+ const Zstring targetDirFormatted = targetDir.EndsWith(common::FILE_NAME_SEPARATOR) ? //ends with path separator
targetDir :
- targetDir + globalFunctions::FILE_NAME_SEPARATOR;
+ targetDir + common::FILE_NAME_SEPARATOR;
//move files
for (TraverseOneLevel::NamePair::const_iterator i = fileList.begin(); i != fileList.end(); ++i)
- FreeFileSync::moveFile(i->second, targetDirFormatted + i->first, callback);
+ ffs3::moveFile(i->second, targetDirFormatted + i->first, callback);
//move directories
for (TraverseOneLevel::NamePair::const_iterator i = dirList.begin(); i != dirList.end(); ++i)
@@ -782,7 +803,7 @@ void moveDirectoryImpl(const Zstring& sourceDir, const Zstring& targetDir, bool
}
-void FreeFileSync::moveDirectory(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExistingDirs, MoveFileCallback* callback) //throw (FileError);
+void ffs3::moveDirectory(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExistingDirs, MoveFileCallback* callback) //throw (FileError);
{
#ifdef FFS_WIN
const Zstring& sourceDirFormatted = sourceDir;
@@ -790,12 +811,12 @@ void FreeFileSync::moveDirectory(const Zstring& sourceDir, const Zstring& target
#elif defined FFS_LINUX
const Zstring sourceDirFormatted = //remove trailing slash
- sourceDir.size() > 1 && sourceDir.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ? //exception: allow '/'
- sourceDir.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) :
+ sourceDir.size() > 1 && sourceDir.EndsWith(common::FILE_NAME_SEPARATOR) ? //exception: allow '/'
+ sourceDir.BeforeLast(common::FILE_NAME_SEPARATOR) :
sourceDir;
const Zstring targetDirFormatted = //remove trailing slash
- targetDir.size() > 1 && targetDir.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ? //exception: allow '/'
- targetDir.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) :
+ targetDir.size() > 1 && targetDir.EndsWith(common::FILE_NAME_SEPARATOR) ? //exception: allow '/'
+ targetDir.BeforeLast(common::FILE_NAME_SEPARATOR) :
targetDir;
#endif
@@ -803,7 +824,7 @@ void FreeFileSync::moveDirectory(const Zstring& sourceDir, const Zstring& target
}
-class FilesDirsOnlyTraverser : public FreeFileSync::TraverseCallback
+class FilesDirsOnlyTraverser : public ffs3::TraverseCallback
{
public:
FilesDirsOnlyTraverser(std::vector<Zstring>& files, std::vector<Zstring>& dirs) :
@@ -837,7 +858,7 @@ private:
};
-void FreeFileSync::removeDirectory(const Zstring& directory)
+void ffs3::removeDirectory(const Zstring& directory)
{
//no error situation if directory is not existing! manual deletion relies on it!
if (!somethingExists(directory))
@@ -852,7 +873,7 @@ void FreeFileSync::removeDirectory(const Zstring& directory)
FILE_ATTRIBUTE_NORMAL)) // attributes to set
{
wxString errorMessage = wxString(_("Error deleting directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
#endif
@@ -867,7 +888,7 @@ void FreeFileSync::removeDirectory(const Zstring& directory)
#endif
{
wxString errorMessage = wxString(_("Error deleting directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
return;
}
@@ -877,7 +898,7 @@ void FreeFileSync::removeDirectory(const Zstring& directory)
//get all files and directories from current directory (WITHOUT subdirectories!)
FilesDirsOnlyTraverser traverser(fileList, dirList);
- FreeFileSync::traverseFolder(directory, false, &traverser); //don't follow symlinks
+ ffs3::traverseFolder(directory, false, &traverser); //don't follow symlinks
//delete files
std::for_each(fileList.begin(), fileList.end(), removeFile);
@@ -893,13 +914,13 @@ void FreeFileSync::removeDirectory(const Zstring& directory)
#endif
{
wxString errorMessage = wxString(_("Error deleting directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
//optionally: copy directory last change date, DO NOTHING if something fails
-bool FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& targetDir, bool deRefSymlinks) //throw()
+void ffs3::copyFileTimes(const Zstring& sourceObj, const Zstring& targetObj, bool deRefSymlinks) //throw (FileError)
{
#ifdef FFS_WIN
FILETIME creationTime = {0};
@@ -908,30 +929,39 @@ bool FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target
{
WIN32_FILE_ATTRIBUTE_DATA sourceAttr;
- if (!::GetFileAttributesEx(applyLongPathPrefix(sourceDir).c_str(), //__in LPCTSTR lpFileName,
+ if (!::GetFileAttributesEx(applyLongPathPrefix(sourceObj).c_str(), //__in LPCTSTR lpFileName,
GetFileExInfoStandard, //__in GET_FILEEX_INFO_LEVELS fInfoLevelId,
&sourceAttr)) //__out LPVOID lpFileInformation
- return false;
+ {
+ const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
if ((sourceAttr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && deRefSymlinks) //we have a symlink AND need to dereference...
{
- HANDLE hDirRead = ::CreateFile(applyLongPathPrefix(sourceDir).c_str(),
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS, //needed to open a directory; no FILE_FLAG_OPEN_REPARSE_POINT => deref symlinks
- NULL);
- if (hDirRead == INVALID_HANDLE_VALUE)
- return false;
-
- boost::shared_ptr<void> dummy(hDirRead, ::CloseHandle);
-
- if (!::GetFileTime(hDirRead, //__in HANDLE hFile,
+ HANDLE hSource = ::CreateFile(applyLongPathPrefix(sourceObj).c_str(),
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, //needed to open a directory; no FILE_FLAG_OPEN_REPARSE_POINT => deref symlinks
+ NULL);
+ if (hSource == INVALID_HANDLE_VALUE)
+ {
+ const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
+
+ boost::shared_ptr<void> dummy(hSource, ::CloseHandle);
+
+ if (!::GetFileTime(hSource, //__in HANDLE hFile,
&creationTime, //__out_opt LPFILETIME lpCreationTime,
&lastAccessTime, //__out_opt LPFILETIME lpLastAccessTime,
&lastWriteTime)) //__out_opt LPFILETIME lpLastWriteTime
- return false;
+ {
+ const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
}
else
{
@@ -941,59 +971,75 @@ bool FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target
}
}
+ HANDLE hTarget = ::CreateFile(applyLongPathPrefix(targetObj).c_str(),
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | //needed to open a directory
+ (deRefSymlinks ? 0 : FILE_FLAG_OPEN_REPARSE_POINT), //process symlinks
+ NULL);
+ if (hTarget == INVALID_HANDLE_VALUE)
+ {
+ wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
- HANDLE hDirWrite = ::CreateFile(applyLongPathPrefix(targetDir).c_str(),
- FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | //needed to open a directory
- (deRefSymlinks ? 0 : FILE_FLAG_OPEN_REPARSE_POINT), //process symlinks
- NULL);
- if (hDirWrite == INVALID_HANDLE_VALUE)
- return false;
-
- boost::shared_ptr<void> dummy(hDirWrite, ::CloseHandle);
+ boost::shared_ptr<void> dummy(hTarget, ::CloseHandle);
- if (!::SetFileTime(hDirWrite,
+ if (!::SetFileTime(hTarget,
&creationTime,
&lastAccessTime,
&lastWriteTime)) //return value not evalutated!
- return false;
+ {
+ wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
#elif defined FFS_LINUX
if (deRefSymlinks)
{
- struct stat dirInfo;
- if (::stat(sourceDir.c_str(), &dirInfo) != 0) //read file attributes from source directory
- return false;
+ struct stat objInfo;
+ if (::stat(sourceObj.c_str(), &objInfo) != 0) //read file attributes from source directory
+ {
+ const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
struct utimbuf newTimes;
- newTimes.actime = dirInfo.st_atime;
- newTimes.modtime = dirInfo.st_mtime;
+ newTimes.actime = objInfo.st_atime;
+ newTimes.modtime = objInfo.st_mtime;
//(try to) set new "last write time"
- if (::utime(targetDir.c_str(), &newTimes) != 0) //return value not evalutated!
- return false;
+ if (::utime(targetObj.c_str(), &newTimes) != 0) //return value not evalutated!
+ {
+ wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
}
else
{
- struct stat dirInfo;
- if (::lstat(sourceDir.c_str(), &dirInfo) != 0) //read file attributes from source directory
- return false;
+ struct stat objInfo;
+ if (::lstat(sourceObj.c_str(), &objInfo) != 0) //read file attributes from source directory
+ {
+ const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
struct timeval newTimes[2];
- newTimes[0].tv_sec = dirInfo.st_atime; /* seconds */
+ newTimes[0].tv_sec = objInfo.st_atime; /* seconds */
newTimes[0].tv_usec = 0; /* microseconds */
- newTimes[1].tv_sec = dirInfo.st_mtime; /* seconds */
+ newTimes[1].tv_sec = objInfo.st_mtime; /* seconds */
newTimes[1].tv_usec = 0; /* microseconds */
- if (::lutimes(targetDir.c_str(), newTimes) != 0) //return value not evalutated!
- return false;
+ if (::lutimes(targetObj.c_str(), newTimes) != 0) //return value not evalutated!
+ {
+ wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetObj) + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
+ }
}
#endif
- return true;
}
@@ -1003,7 +1049,7 @@ namespace
Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory
{
//open handle to target of symbolic link
- const HANDLE hDir = ::CreateFile(FreeFileSync::applyLongPathPrefix(dirLinkName).c_str(),
+ const HANDLE hDir = ::CreateFile(ffs3::applyLongPathPrefix(dirLinkName).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -1018,7 +1064,6 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
const size_t BUFFER_SIZE = 10000;
TCHAR targetPath[BUFFER_SIZE];
-
//dynamically load windows API function
typedef DWORD (WINAPI *GetFinalPathNameByHandleWFunc)(
HANDLE hFile,
@@ -1026,7 +1071,7 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
DWORD cchFilePath,
DWORD dwFlags);
static const GetFinalPathNameByHandleWFunc getFinalPathNameByHandle =
- Utility::loadDllFunction<GetFinalPathNameByHandleWFunc>(L"kernel32.dll", "GetFinalPathNameByHandleW");
+ util::loadDllFunction<GetFinalPathNameByHandleWFunc>(L"kernel32.dll", "GetFinalPathNameByHandleW");
if (getFinalPathNameByHandle == NULL)
throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\""));
@@ -1042,55 +1087,11 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
return targetPath;
}
-//#include <aclapi.h>
-////optionally: copy additional metadata, DO NOTHING if something fails
-//void copyAdditionalMetadata(const Zstring& sourceDir, const Zstring& targetDir)
-//{
-// //copy NTFS permissions
-//
-// PSECURITY_DESCRIPTOR pSD;
-//
-// PACL pDacl;
-// if (::GetNamedSecurityInfo(
-// const_cast<DefaultChar*>(sourceDir.c_str()),
-// SE_FILE_OBJECT, //file or directory
-// DACL_SECURITY_INFORMATION,
-// NULL,
-// NULL,
-// &pDacl,
-// NULL,
-// &pSD
-// ) == ERROR_SUCCESS)
-// {
-// //(try to) set new security information
-// if (::SetNamedSecurityInfo(
-// const_cast<DefaultChar*>(targetDir.c_str()),
-// SE_FILE_OBJECT, //file or directory
-// DACL_SECURITY_INFORMATION,
-// NULL,
-// NULL,
-// pDacl,
-// NULL) != ERROR_SUCCESS) //return value not evalutated!
-// {
-// const wxString errorMessage = wxString(wxT("Error 2:")) + wxT("\n\"") + targetDir.c_str() + wxT("\"");
-// throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
-// }
-//
-//#warning BUG!
-// LocalFree(pSD);
-// }
-// else
-// {
-// const wxString errorMessage = wxString(wxT("Error 1:")) + wxT("\n\"") + sourceDir.c_str() + wxT("\"");
-// throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
-// }
-//
-//}
#elif defined FFS_LINUX
-void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink) //throw (FileError)
+void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink, bool copyFilePermissions) //throw (FileError)
{
- using namespace FreeFileSync;
+ using namespace ffs3;
//copy symbolic link
const int BUFFER_SIZE = 10000;
@@ -1099,7 +1100,7 @@ void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink) /
if (bytesWritten < 0 || bytesWritten == BUFFER_SIZE)
{
wxString errorMessage = wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + zToWx(sourceLink) + wxT("\"");
- if (bytesWritten < 0) errorMessage += wxString(wxT("\n\n")) + FreeFileSync::getLastErrorFormatted();
+ if (bytesWritten < 0) errorMessage += wxString(wxT("\n\n")) + ffs3::getLastErrorFormatted();
throw FileError(errorMessage);
}
//set null-terminating char
@@ -1108,54 +1109,325 @@ void copySymlinkInternal(const Zstring& sourceLink, const Zstring& targetLink) /
if (::symlink(buffer, targetLink.c_str()) != 0)
{
const wxString errorMessage = wxString(_("Error copying symbolic link:")) + wxT("\n\"") + zToWx(sourceLink) + wxT("\" ->\n\"") + zToWx(targetLink) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
//allow only consistent objects to be created -> don't place before ::symlink, targetLink may already exist
Loki::ScopeGuard guardTargetLink = Loki::MakeGuard(::unlink, targetLink);
- if (!copyFileTimes(sourceLink, targetLink, false))
+ copyFileTimes(sourceLink, targetLink, false); //throw (FileError)
+
+ if (copyFilePermissions)
+ copyObjectPermissions(sourceLink, targetLink, false); //throw FileError()
+
+ guardTargetLink.Dismiss();
+}
+#endif
+}
+
+
+namespace ffs3
+{
+#ifdef FFS_WIN
+class Privileges
+{
+public:
+ static Privileges& getInstance()
{
- wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetLink) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ static Privileges instance;
+ return instance;
}
- guardTargetLink.Dismiss();
+ void ensureActive(LPCTSTR privilege) //throw FileError()
+ {
+ if (activePrivileges.find(privilege) != activePrivileges.end())
+ return; //privilege already active
+
+ if (privilegeIsActive(privilege)) //privilege was already active before starting this tool
+ activePrivileges.insert(std::make_pair(privilege, false));
+ else
+ {
+ setPrivilege(privilege, true);
+ activePrivileges.insert(std::make_pair(privilege, true));
+ }
+ }
+
+private:
+ Privileges() {}
+ Privileges(Privileges&);
+ void operator=(Privileges&);
+
+ ~Privileges() //clean up: deactivate all privileges that have been activated by this application
+ {
+ for (PrivBuffType::const_iterator i = activePrivileges.begin(); i != activePrivileges.end(); ++i)
+ try
+ {
+ if (i->second)
+ Privileges::setPrivilege(i->first, false);
+ }
+ catch(...) {}
+ }
+
+ static bool privilegeIsActive(LPCTSTR privilege); //throw FileError()
+ static void setPrivilege(LPCTSTR privilege, bool enable); //throw FileError()
+
+ typedef std::map<Zstring, bool> PrivBuffType; //bool: enabled by this application
+
+ PrivBuffType activePrivileges;
+};
+
+
+bool Privileges::privilegeIsActive(LPCTSTR privilege) //throw FileError()
+{
+ HANDLE hToken = NULL;
+ if (!::OpenProcessToken(::GetCurrentProcess(), //__in HANDLE ProcessHandle,
+ TOKEN_QUERY, //__in DWORD DesiredAccess,
+ &hToken)) //__out PHANDLE TokenHandle
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+ boost::shared_ptr<void> dummy(hToken, ::CloseHandle);
+
+ LUID luid = {0};
+ if (!::LookupPrivilegeValue(
+ NULL, //__in_opt LPCTSTR lpSystemName,
+ privilege, //__in LPCTSTR lpName,
+ &luid )) //__out PLUID lpLuid
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+
+ PRIVILEGE_SET priv = {0};
+ priv.PrivilegeCount = 1;
+ priv.Control = PRIVILEGE_SET_ALL_NECESSARY;
+ priv.Privilege[0].Luid = luid;
+ priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ BOOL alreadyGranted = FALSE;
+ if (!::PrivilegeCheck(
+ hToken, //__in HANDLE ClientToken,
+ &priv, //__inout PPRIVILEGE_SET RequiredPrivileges,
+ &alreadyGranted)) //__out LPBOOL pfResult
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+
+ return alreadyGranted == TRUE;
}
+
+
+void Privileges::setPrivilege(LPCTSTR privilege, bool enable) //throw FileError()
+{
+ HANDLE hToken = NULL;
+ if (!::OpenProcessToken(::GetCurrentProcess(), //__in HANDLE ProcessHandle,
+ TOKEN_ADJUST_PRIVILEGES, //__in DWORD DesiredAccess,
+ &hToken)) //__out PHANDLE TokenHandle
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+ boost::shared_ptr<void> dummy(hToken, ::CloseHandle);
+
+ LUID luid = {0};
+ if (!::LookupPrivilegeValue(
+ NULL, //__in_opt LPCTSTR lpSystemName,
+ privilege, //__in LPCTSTR lpName,
+ &luid )) //__out PLUID lpLuid
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+
+ TOKEN_PRIVILEGES tp = {0};
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
+
+ if (!::AdjustTokenPrivileges(
+ hToken, //__in HANDLE TokenHandle,
+ false, //__in BOOL DisableAllPrivileges,
+ &tp, //__in_opt PTOKEN_PRIVILEGES NewState,
+ 0, //__in DWORD BufferLength,
+ NULL, //__out_opt PTOKEN_PRIVILEGES PreviousState,
+ NULL)) //__out_opt PDWORD ReturnLength
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+
+ if (::GetLastError() == ERROR_NOT_ALL_ASSIGNED) //check although previous function returned with success!
+ {
+ const wxString errorMessage = wxString(_("Error setting privilege:")) + wxT(" \"") + privilege + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+}
+#endif
+}
+
+
+//copy permissions for files, directories or symbolic links
+void ffs3::copyObjectPermissions(const Zstring& source, const Zstring& target, bool derefSymlinks) //throw FileError(); probably requires admin rights
+{
+#ifdef FFS_WIN
+ //enable privilege: required to read/write SACL information
+ Privileges::getInstance().ensureActive(SE_SECURITY_NAME); //polling allowed...
+
+ //enable privilege: required to copy owner information
+ Privileges::getInstance().ensureActive(SE_RESTORE_NAME);
+
+ //the following privilege may be required according to http://msdn.microsoft.com/en-us/library/aa364399(VS.85).aspx (although not needed nor active in my tests)
+ Privileges::getInstance().ensureActive(SE_BACKUP_NAME);
+
+ PSECURITY_DESCRIPTOR buffer = NULL;
+ PSID owner = NULL;
+ PSID group = NULL;
+ PACL dacl = NULL;
+ PACL sacl = NULL;
+
+ //http://msdn.microsoft.com/en-us/library/aa364399(v=VS.85).aspx
+ const HANDLE hSource = ::CreateFile(ffs3::applyLongPathPrefix(source).c_str(),
+ READ_CONTROL | ACCESS_SYSTEM_SECURITY, //ACCESS_SYSTEM_SECURITY required for SACL access
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | (derefSymlinks ? 0 : FILE_FLAG_OPEN_REPARSE_POINT), //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory
+ NULL);
+ if (hSource == INVALID_HANDLE_VALUE)
+ throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(source) + wxT("\"") +
+ wxT("\n\n") + ffs3::getLastErrorFormatted());
+ boost::shared_ptr<void> dummy(hSource, ::CloseHandle);
+
+// DWORD rc = ::GetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(source).c_str()), -> does NOT dereference symlinks!
+ DWORD rc = ::GetSecurityInfo(
+ hSource, //__in LPTSTR pObjectName,
+ SE_FILE_OBJECT, //__in SE_OBJECT_TYPE ObjectType,
+ OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION SecurityInfo,
+ &owner, //__out_opt PSID *ppsidOwner,
+ &group, //__out_opt PSID *ppsidGroup,
+ &dacl, //__out_opt PACL *ppDacl,
+ &sacl, //__out_opt PACL *ppSacl,
+ &buffer); //__out_opt PSECURITY_DESCRIPTOR *ppSecurityDescriptor
+ if (rc != ERROR_SUCCESS)
+ {
+ const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc));
+ }
+ boost::shared_ptr<void> dummy2(buffer, ::LocalFree);
+
+
+ const Zstring targetFmt = ffs3::applyLongPathPrefix(target);
+
+ //read-only file attribute may cause trouble: temporarily reset it
+ const DWORD targetAttr = ::GetFileAttributes(targetFmt.c_str());
+ Loki::ScopeGuard resetAttributes = Loki::MakeGuard(::SetFileAttributes, targetFmt, targetAttr);
+ if ( targetAttr != INVALID_FILE_ATTRIBUTES &&
+ (targetAttr & FILE_ATTRIBUTE_READONLY))
+ ::SetFileAttributes(targetFmt.c_str(), targetAttr & (~FILE_ATTRIBUTE_READONLY)); //try to...
+ else
+ resetAttributes.Dismiss();
+
+
+ HANDLE hTarget = ::CreateFile( targetFmt.c_str(), // lpFileName
+ FILE_GENERIC_WRITE | WRITE_OWNER | WRITE_DAC | ACCESS_SYSTEM_SECURITY, // dwDesiredAccess: all four seem to be required!!!
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // dwShareMode
+ NULL, // lpSecurityAttributes
+ OPEN_EXISTING, // dwCreationDisposition
+ FILE_FLAG_BACKUP_SEMANTICS | (derefSymlinks ? 0 : FILE_FLAG_OPEN_REPARSE_POINT), // dwFlagsAndAttributes
+ NULL); // hTemplateFile
+ if (hTarget == INVALID_HANDLE_VALUE)
+ throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(target) + wxT("\"") +
+ wxT("\n\n") + ffs3::getLastErrorFormatted());
+ boost::shared_ptr<void> dummy3(hTarget, ::CloseHandle);
+
+// rc = ::SetNamedSecurityInfo(const_cast<WCHAR*>(applyLongPathPrefix(target).c_str()), //__in LPTSTR pObjectName, -> does NOT dereference symlinks!
+ rc = ::SetSecurityInfo(
+ hTarget, //__in LPTSTR pObjectName,
+ SE_FILE_OBJECT, //__in SE_OBJECT_TYPE ObjectType,
+ OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION SecurityInfo,
+ owner, //__in_opt PSID psidOwner,
+ group, //__in_opt PSID psidGroup,
+ dacl, //__in_opt PACL pDacl,
+ sacl); //__in_opt PACL pSacl
+
+ if (rc != ERROR_SUCCESS)
+ {
+ const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted(rc));
+ }
+
+#elif defined FFS_LINUX
+ if (derefSymlinks)
+ {
+ struct stat fileInfo;
+ if ( ::stat(source.c_str(), &fileInfo) != 0 ||
+ ::chown(target.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0 || // may require admin rights!
+ ::chmod(target.c_str(), fileInfo.st_mode) != 0)
+ {
+ const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+ }
+ else
+ {
+ struct stat fileInfo;
+ if ( ::lstat(source.c_str(), &fileInfo) != 0 ||
+ ::lchown(target.c_str(), fileInfo.st_uid, fileInfo.st_gid) != 0 || // may require admin rights!
+ (!symlinkExists(target) && ::chmod(target.c_str(), fileInfo.st_mode) != 0)) //setting access permissions doesn't make sense for symlinks on Linux: there is no lchmod()
+ {
+ const wxString errorMessage = wxString(_("Error copying file permissions:")) + wxT("\n\"") + zToWx(source) + wxT("\" ->\n\"") + zToWx(target) + wxT("\"") + wxT("\n\n");
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted());
+ }
+ }
#endif
}
-void createDirectoryRecursively(const Zstring& directory, const Zstring& templateDir, const bool copyDirectorySymLinks, const int level)
+
+void createDirectoryRecursively(const Zstring& directory, const Zstring& templateDir, bool copyDirectorySymLinks, bool copyFilePermissions, int level)
{
- using namespace FreeFileSync;
+ using namespace ffs3;
- if (FreeFileSync::dirExists(directory))
+ if (ffs3::dirExists(directory))
return;
if (level == 100) //catch endless recursion
return;
//try to create parent folders first
- const Zstring dirParent = directory.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
- if (!dirParent.empty() && !FreeFileSync::dirExists(dirParent))
+ const Zstring dirParent = directory.BeforeLast(common::FILE_NAME_SEPARATOR);
+ if (!dirParent.empty() && !ffs3::dirExists(dirParent))
{
//call function recursively
- const Zstring templateParent = templateDir.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR);
- createDirectoryRecursively(dirParent, templateParent, false, level + 1); //don't create symbolic links in recursion!
+ const Zstring templateParent = templateDir.BeforeLast(common::FILE_NAME_SEPARATOR);
+ createDirectoryRecursively(dirParent, templateParent, false, copyFilePermissions, level + 1); //don't create symbolic links in recursion!
}
+ struct TryCleanUp
+ {
+ static void tryDeleteDir(const Zstring& linkname) //throw ()
+ {
+ try
+ {
+ removeDirectory(linkname);
+ }
+ catch (...) {}
+ }
+ };
+
//now creation should be possible
#ifdef FFS_WIN
- const DWORD templateAttr = templateDir.empty() ?
- INVALID_FILE_ATTRIBUTES :
+ const DWORD templateAttr = templateDir.empty() ? INVALID_FILE_ATTRIBUTES :
::GetFileAttributes(applyLongPathPrefix(templateDir).c_str()); //returns successful for broken symlinks
if (templateAttr == INVALID_FILE_ATTRIBUTES) //fallback
{
if (!::CreateDirectory(applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL) && level == 0)
+ NULL))
{
+ if (level != 0) return;
const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
else
@@ -1169,22 +1441,18 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
const Zstring linkPath = resolveDirectorySymlink(templateDir);
if (linkPath.empty())
{
- if (level == 0)
- throw FileError(wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\""));
+ if (level != 0) return;
+ throw FileError(wxString(_("Error resolving symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\""));
}
- else
- {
- if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
- applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
- applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL) && level == 0)
- {
- const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
- }
- //(try to) copy additional metadata like last modification time: no measurable performance drawback
- //copyAdditionalMetadata(linkPath, directory);
+ if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
+ applyLongPathPrefix(linkPath).c_str(), // pointer to path string of template directory
+ applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
+ NULL))
+ {
+ if (level != 0) return;
+ const wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\"");
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
}
else //in all other cases
@@ -1192,45 +1460,28 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
if (!::CreateDirectoryEx( // this function automatically copies symbolic links if encountered
applyLongPathPrefix(templateDir).c_str(), // pointer to path string of template directory
applyLongPathPrefixCreateDir(directory).c_str(), // pointer to a directory path string
- NULL) && level == 0)
+ NULL))
{
+ if (level != 0) return;
const wxString errorMessage = isSymlink ?
//give a more meaningful errormessage if copying a symbolic link failed, e.g. "C:\Users\ZenJu\Application Data"
(wxString(_("Error copying symbolic link:")) + wxT("\n\"") + templateDir.c_str() + wxT("\" ->\n\"") + directory.c_str() + wxT("\"")) :
(wxString(_("Error creating directory:")) + wxT("\n\"") + directory.c_str() + wxT("\""));
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
+ }
+ //ensure cleanup:
+ Loki::ScopeGuard guardNewDir = Loki::MakeGuard(&TryCleanUp::tryDeleteDir, directory);
- if (copyDirectorySymLinks && isSymlink) //we need to copy the Symbolic Link's change date manually
- {
- struct TryCleanUp
- {
- static void tryDeleteLink(const Zstring& linkname) //throw ()
- {
- try
- {
- removeDirectory(linkname);
- }
- catch (...) {}
- }
- };
- //allow only consistent objects to be created -> don't place before ::CreateDirectoryEx, targetLink may already exist
- Loki::ScopeGuard guardTargetLink = Loki::MakeGuard(&TryCleanUp::tryDeleteLink, directory);
-
- if (!copyFileTimes(templateDir, directory, false))
- {
- wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
- }
+ if (copyDirectorySymLinks && isSymlink) //we need to copy the Symbolic Link's change date manually
+ copyFileTimes(templateDir, directory, false); //throw (FileError)
- guardTargetLink.Dismiss();
- }
+ if (copyFilePermissions)
+ copyObjectPermissions(templateDir, directory, !copyDirectorySymLinks); //throw FileError()
- //(try to) copy additional metadata like last modification time: no measurable performance drawback
- //copyAdditionalMetadata(templateDir, directory);
- }
+ guardNewDir.Dismiss(); //target has been created successfully!
}
#elif defined FFS_LINUX
//symbolic link handling
@@ -1238,51 +1489,45 @@ void createDirectoryRecursively(const Zstring& directory, const Zstring& templat
!templateDir.empty() &&
symlinkExists(templateDir))
//there is no directory-type symlink in Linux! => just copy as file
- return copySymlinkInternal(templateDir, directory); //throw (FileError)
+ return copySymlinkInternal(templateDir, directory, copyFilePermissions); //throw (FileError)
//default directory creation
- if (::mkdir(directory.c_str(), 0755) != 0 && level == 0)
+ if (::mkdir(directory.c_str(), 0755) != 0)
{
+ if (level != 0) return;
wxString errorMessage = wxString(_("Error creating directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
-//copy directory permissions: not sure if this is a good idea: if a directory is read-only copying/sync'ing of files will fail...
- /*
- if (templateDirExists)
- {
- struct stat fileInfo;
- if (stat(templateDir.c_str(), &fileInfo) != 0) //read permissions from template directory
- throw FileError(Zstring(_("Error reading file attributes:")) + wxT("\n\"") + templateDir + wxT("\""));
+ //ensure cleanup:
+ Loki::ScopeGuard guardNewDir = Loki::MakeGuard(&TryCleanUp::tryDeleteDir, directory);
- // reset the umask as we want to create the directory with exactly the same permissions as the template
- wxCHANGE_UMASK(0);
+ if (!templateDir.empty() && copyFilePermissions)
+ copyObjectPermissions(templateDir, directory, true); //throw FileError()
- if (mkdir(directory.c_str(), fileInfo.st_mode) != 0 && level == 0)
- throw FileError(Zstring(_("Error creating directory:")) + wxT("\n\"") + directory + wxT("\""));
- }
- else
- {
- if (mkdir(directory.c_str(), 0777) != 0 && level == 0)
- throw FileError(Zstring(_("Error creating directory:")) + wxT("\n\"") + directory + wxT("\""));
- }
- */
+ guardNewDir.Dismiss(); //target has been created successfully!
#endif
}
-void FreeFileSync::createDirectory(const Zstring& directory, const Zstring& templateDir, bool copyDirectorySymLinks)
+void ffs3::createDirectory(const Zstring& directory, const Zstring& templateDir, bool copyDirectorySymLinks, bool copyFilePermissions)
{
//remove trailing separator
- const Zstring dirFormatted = directory.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ?
- directory.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) :
+ const Zstring dirFormatted = directory.EndsWith(common::FILE_NAME_SEPARATOR) ?
+ directory.BeforeLast(common::FILE_NAME_SEPARATOR) :
directory;
- const Zstring templateFormatted = templateDir.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ?
- templateDir.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) :
+ const Zstring templateFormatted = templateDir.EndsWith(common::FILE_NAME_SEPARATOR) ?
+ templateDir.BeforeLast(common::FILE_NAME_SEPARATOR) :
templateDir;
- createDirectoryRecursively(dirFormatted, templateFormatted, copyDirectorySymLinks, 0);
+ createDirectoryRecursively(dirFormatted, templateFormatted, copyDirectorySymLinks, copyFilePermissions, 0);
+}
+
+
+void ffs3::createDirectory(const Zstring& directory)
+{
+ ffs3::createDirectory(directory, Zstring(), false, false);
}
@@ -1290,11 +1535,15 @@ namespace
{
Zstring createTempName(const Zstring& filename)
{
- Zstring output = filename + FreeFileSync::TEMP_FILE_ENDING;
+ Zstring output = filename + ffs3::TEMP_FILE_ENDING;
+
+#ifndef _MSC_VER
+#warning TEMP_FILE_ENDING -> harmonize with other "endings" remove trailing dot
+#endif
//ensure uniqueness
- for (int i = 1; FreeFileSync::somethingExists(output); ++i)
- output = filename + DefaultChar('_') + numberToZstring(i) + FreeFileSync::TEMP_FILE_ENDING;
+ for (int i = 1; ffs3::somethingExists(output); ++i)
+ output = filename + DefaultChar('_') + numberToZstring(i) + ffs3::TEMP_FILE_ENDING;
return output;
}
@@ -1318,7 +1567,7 @@ DWORD CALLBACK copyCallbackInternal(
HANDLE hDestinationFile,
LPVOID lpData)
{
- using FreeFileSync::CopyFileCallback;
+ using ffs3::CopyFileCallback;
//small performance optimization: it seems this callback function is called for every 64 kB (depending on cluster size).
static size_t callNr = 0;
@@ -1334,15 +1583,20 @@ DWORD CALLBACK copyCallbackInternal(
This will then be handled in future versions of FreeFileSync.\n\nThanks -ZenJu"),
NULL, 0);
-
CopyFileCallback* callback = static_cast<CopyFileCallback*>(lpData);
-
- switch (callback->updateCopyStatus(wxULongLong(totalBytesTransferred.HighPart, totalBytesTransferred.LowPart)))
+ try
{
- case CopyFileCallback::CONTINUE:
- break;
- case CopyFileCallback::CANCEL:
- return PROGRESS_CANCEL;
+ switch (callback->updateCopyStatus(wxULongLong(totalBytesTransferred.HighPart, totalBytesTransferred.LowPart)))
+ {
+ case CopyFileCallback::CONTINUE:
+ break;
+ case CopyFileCallback::CANCEL:
+ return PROGRESS_CANCEL;
+ }
+ }
+ catch (...)
+ {
+ ::MessageBox(NULL, wxT("Exception in callback ffs3::copyFile! Please contact the author of FFS."), NULL, 0);
}
}
}
@@ -1354,7 +1608,7 @@ DWORD CALLBACK copyCallbackInternal(
bool supportForSymbolicLinks()
{
OSVERSIONINFO osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ ::ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
//symbolic links are supported starting with Vista
@@ -1377,7 +1631,7 @@ bool supportForNonEncryptedDestination()
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
//encrypted destination is not supported with Windows 2000
- if (GetVersionEx(&osvi))
+ if (::GetVersionEx(&osvi))
return osvi.dwMajorVersion > 5 ||
(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion > 0); //2000 has majorVersion == 5, minorVersion == 0
//overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
@@ -1386,16 +1640,16 @@ bool supportForNonEncryptedDestination()
}
-void FreeFileSync::copyFile(const Zstring& sourceFile,
- const Zstring& targetFile,
- bool copyFileSymLinks,
- FreeFileSync::ShadowCopy* shadowCopyHandler,
- FreeFileSync::CopyFileCallback* callback)
+void ffs3::copyFile(const Zstring& sourceFile,
+ const Zstring& targetFile,
+ bool copyFileSymLinks,
+ bool copyFilePermissions,
+ shadow::ShadowCopy* shadowCopyHandler,
+ ffs3::CopyFileCallback* callback)
{
- //FreeFileSync::fileExists(targetFile) -> avoid this call, performance;
+ //ffs3::fileExists(targetFile) -> avoid this call, performance;
//if target exists (very unlikely, because sync-algorithm deletes it) renaming below will fail!
-
DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS;
//copy symbolic links instead of the files pointed at
@@ -1442,47 +1696,71 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
lastError == ERROR_LOCK_VIOLATION))
{
//shadowFilename already contains prefix: E.g. "\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Program Files\FFS\sample.dat"
- const Zstring shadowFilename(shadowCopyHandler->makeShadowCopy(sourceFile));
+
+ Zstring shadowFilename;
+ try
+ {
+ shadowFilename = shadowCopyHandler->makeShadowCopy(sourceFile); //throw (FileError)
+ }
+ catch (const FileError& e)
+ {
+ wxString errorMsg = _("Error copying locked file %x!");
+ errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + zToWx(sourceFile) + wxT("\""));
+ errorMsg += wxT("\n\n") + e.msg();
+ throw FileError(errorMsg);
+ }
+
return copyFile(shadowFilename, //transferred bytes is automatically reset when new file is copied
targetFile,
copyFileSymLinks,
+ copyFilePermissions,
NULL,
callback);
}
//assemble error message...
const wxString errorMessage = wxString(_("Error copying file:")) + wxT("\n\"") + sourceFile.c_str() + wxT("\" ->\n\"") + targetFile.c_str() + wxT("\"") + wxT("\n\n");
- throw FileError(errorMessage + FreeFileSync::getLastErrorFormatted(lastError));
+ throw FileError(errorMessage + ffs3::getLastErrorFormatted(lastError));
}
//rename temporary file: do not add anything else here (note specific error handing)
- FreeFileSync::renameFile(temporary, targetFile);
+ ffs3::renameFile(temporary, targetFile);
guardTempFile.Dismiss(); //no need to delete temp file anymore
- //copy creation date (last modification date is redundantly written, too, even for symlinks)
- copyFileTimes(sourceFile, targetFile, !copyFileSymLinks); //throw()
+ Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(&TryCleanUp::tryDeleteFile, targetFile);
+
+ if (copyFilePermissions)
+ copyObjectPermissions(sourceFile, targetFile, !copyFileSymLinks); //throw FileError()
+
+ //copy creation date (last modification date is REDUNDANTLY written, too, even for symlinks)
+ copyFileTimes(sourceFile, targetFile, !copyFileSymLinks); //throw (FileError)
+
+ guardTargetFile.Dismiss();
}
#elif defined FFS_LINUX
-void FreeFileSync::copyFile(const Zstring& sourceFile,
- const Zstring& targetFile,
- bool copyFileSymLinks,
- CopyFileCallback* callback)
+void ffs3::copyFile(const Zstring& sourceFile,
+ const Zstring& targetFile,
+ bool copyFileSymLinks,
+ bool copyFilePermissions,
+ CopyFileCallback* callback)
{
- using FreeFileSync::CopyFileCallback;
+ using ffs3::CopyFileCallback;
//symbolic link handling
if ( copyFileSymLinks &&
symlinkExists(sourceFile))
- return copySymlinkInternal(sourceFile, targetFile); //throw (FileError)
+ {
+ return copySymlinkInternal(sourceFile, targetFile, copyFilePermissions); //throw (FileError)
+ }
//begin of regular file copy
struct stat fileInfo;
if (::stat(sourceFile.c_str(), &fileInfo) != 0) //read file attributes from source file (resolving symlinks)
{
const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(sourceFile) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ throw FileError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
}
//open sourceFile for reading
@@ -1528,26 +1806,19 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
//close output stream before changing attributes
fileOut.close();
- //adapt file modification time:
- if (!copyFileTimes(sourceFile, temporary, true)) //throw()
- {
- wxString errorMessage = wxString(_("Error changing modification time:")) + wxT("\n\"") + zToWx(targetFile) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
- }
-
//rename temporary file
- FreeFileSync::renameFile(temporary, targetFile);
+ ffs3::renameFile(temporary, targetFile);
guardTempFile.Dismiss();
//ensure cleanup:
- Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(::unlink, targetFile.c_str()); //don't use Utility::CleanUp here
+ Loki::ScopeGuard guardTargetFile = Loki::MakeGuard(::unlink, targetFile.c_str());
- //set file access rights
- if (::chmod(targetFile.c_str(), fileInfo.st_mode) != 0)
- {
- const wxString errorMessage = wxString(_("Error writing file attributes:")) + wxT("\n\"") + zToWx(targetFile) + wxT("\"");
- throw FileError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
- }
+ //adapt file modification time:
+ copyFileTimes(sourceFile, targetFile, true); //throw (FileError)
+
+ //set file permissions
+ if (copyFilePermissions)
+ copyObjectPermissions(sourceFile, targetFile, true); //throw FileError()
guardTargetFile.Dismiss(); //target has been created successfully!
}
@@ -1564,11 +1835,11 @@ Zstring getDriveName(const Zstring& directoryName) //GetVolume() doesn't work un
if (volumeName.empty())
return Zstring();
- return volumeName + wxFileName::GetVolumeSeparator().c_str() + globalFunctions::FILE_NAME_SEPARATOR;
+ return volumeName + wxFileName::GetVolumeSeparator().c_str() + common::FILE_NAME_SEPARATOR;
}
-bool FreeFileSync::isFatDrive(const Zstring& directoryName)
+bool ffs3::isFatDrive(const Zstring& directoryName)
{
const Zstring driveName = getDriveName(directoryName);
if (driveName.empty())
diff --git a/shared/fileHandling.h b/shared/file_handling.h
index 6c57e8e4..36bf976f 100644
--- a/shared/fileHandling.h
+++ b/shared/file_handling.h
@@ -8,7 +8,7 @@
#define FILE_HANDLING_H_INCLUDED
#include "zstring.h"
-#include "fileError.h"
+#include "file_error.h"
#include <wx/longlong.h>
#ifdef FFS_WIN
@@ -16,7 +16,7 @@
#endif
-namespace FreeFileSync
+namespace ffs3
{
Zstring getFormattedDirectoryName(const Zstring& dirname);
@@ -35,9 +35,11 @@ enum ResponseSameVol
};
ResponseSameVol onSameVolume(const Zstring& folderLeft, const Zstring& folderRight); //throw()
-//optionally: copy file or directory create/last change date, DOES NOTHING if something fails
-//does NOT dereference symlinks!
-bool copyFileTimes(const Zstring& sourceDir, const Zstring& targetDir, bool deRefSymlinks); //throw(); returns true on success
+//copy file or directory create/last change date,
+void copyFileTimes(const Zstring& sourceDir, const Zstring& targetDir, bool derefSymlinks); //throw (FileError)
+
+//copy filesystem permissions: probably requires admin rights
+void copyObjectPermissions(const Zstring& source, const Zstring& target, bool derefSymlinks); //throw FileError();
//symlink handling: always evaluate target
wxULongLong getFilesize(const Zstring& filename); //throw (FileError)
@@ -71,7 +73,8 @@ void moveFile(const Zstring& sourceFile, const Zstring& targetFile, MoveFileCall
void moveDirectory(const Zstring& sourceDir, const Zstring& targetDir, bool ignoreExistingDirs, MoveFileCallback* callback = NULL); //throw (FileError);
//creates superdirectories automatically:
-void createDirectory(const Zstring& directory, const Zstring& templateDir = Zstring(), bool copyDirectorySymLinks = false); //throw (FileError);
+void createDirectory(const Zstring& directory, const Zstring& templateDir, bool copyDirectorySymLinks, bool copyFilePermissions); //throw (FileError);
+void createDirectory(const Zstring& directory); //throw (FileError); -> function overload avoids default parameter ambiguity issues!
struct CopyFileCallback //callback functionality
{
@@ -85,13 +88,14 @@ struct CopyFileCallback //callback functionality
virtual Response updateCopyStatus(const wxULongLong& totalBytesTransferred) = 0; //DON'T throw exceptions here, at least in Windows build!
};
-void copyFile(const Zstring& sourceFile,
+void copyFile(const Zstring& sourceFile, //throw (FileError);
const Zstring& targetFile,
bool copyFileSymLinks,
+ bool copyFilePermissions,
#ifdef FFS_WIN
- ShadowCopy* shadowCopyHandler = NULL, //supply handler for making shadow copies
+ shadow::ShadowCopy* shadowCopyHandler, //supply handler for making shadow copies, may be NULL
#endif
- CopyFileCallback* callback = NULL); //throw (FileError);
+ CopyFileCallback* callback); //may be NULL
//Note: it MAY happen that copyFile() leaves temp files behind, e.g. temporary network drop.
// => clean them up at an appropriate time (automatically set sync directions to delete them). They have the following ending:
const Zstring TEMP_FILE_ENDING = DefaultStr(".ffs_tmp");
diff --git a/shared/fileID.cpp b/shared/file_id.cpp
index 2c608afc..f61108c0 100644
--- a/shared/fileID.cpp
+++ b/shared/file_id.cpp
@@ -4,12 +4,12 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "fileID.h"
+#include "file_id.h"
#ifdef FFS_WIN
-#include "staticAssert.h"
+#include "assert_static.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include "longPathPrefix.h"
+#include "long_path_prefix.h"
#include <boost/shared_ptr.hpp>
#elif defined FFS_LINUX
@@ -19,15 +19,15 @@
#ifdef FFS_WIN
-Utility::FileID Utility::retrieveFileID(const Zstring& filename)
+util::FileID util::retrieveFileID(const Zstring& filename)
{
//ensure our DWORD_FFS really is the same as DWORD
- assert_static(sizeof(Utility::FileID::DWORD_FFS) == sizeof(DWORD));
+ assert_static(sizeof(util::FileID::DWORD_FFS) == sizeof(DWORD));
//WARNING: CreateFile() is SLOW, while GetFileInformationByHandle() is quite cheap!
//http://msdn.microsoft.com/en-us/library/aa363788(VS.85).aspx
- const HANDLE hFile = ::CreateFile(FreeFileSync::applyLongPathPrefix(filename).c_str(),
+ const HANDLE hFile = ::CreateFile(ffs3::applyLongPathPrefix(filename).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -41,31 +41,31 @@ Utility::FileID Utility::retrieveFileID(const Zstring& filename)
BY_HANDLE_FILE_INFORMATION info;
if (::GetFileInformationByHandle(hFile, &info))
{
- return Utility::FileID(info.dwVolumeSerialNumber,
+ return util::FileID(info.dwVolumeSerialNumber,
info.nFileIndexHigh,
info.nFileIndexLow);
}
}
- return Utility::FileID(); //empty ID
+ return util::FileID(); //empty ID
}
#elif defined FFS_LINUX
-Utility::FileID Utility::retrieveFileID(const Zstring& filename)
+util::FileID util::retrieveFileID(const Zstring& filename)
{
struct stat fileInfo;
if (::lstat(filename.c_str(), &fileInfo) == 0) //lstat() does not resolve symlinks
- return Utility::FileID(fileInfo.st_dev, fileInfo.st_ino);
+ return util::FileID(fileInfo.st_dev, fileInfo.st_ino);
- return Utility::FileID(); //empty ID
+ return util::FileID(); //empty ID
}
#endif
-bool Utility::sameFileSpecified(const Zstring& file1, const Zstring& file2)
+bool util::sameFileSpecified(const Zstring& file1, const Zstring& file2)
{
- const Utility::FileID id1 = retrieveFileID(file1);
- const Utility::FileID id2 = retrieveFileID(file2);
+ const util::FileID id1 = retrieveFileID(file1);
+ const util::FileID id2 = retrieveFileID(file2);
if (id1 != FileID() && id2 != FileID())
return id1 == id2;
diff --git a/shared/fileID.h b/shared/file_id.h
index 7b48412a..d00ca20a 100644
--- a/shared/fileID.h
+++ b/shared/file_id.h
@@ -17,7 +17,7 @@
//unique file identifier
-namespace Utility
+namespace util
{
class FileID
{
@@ -60,7 +60,7 @@ FileID retrieveFileID(const Zstring& filename);
//test whether two distinct paths point to the same file or directory:
// true: paths point to same files/dirs
-// false: error occured OR point to different files/dirs
+// false: error occurred OR point to different files/dirs
bool sameFileSpecified(const Zstring& file1, const Zstring& file2);
}
@@ -85,13 +85,13 @@ bool sameFileSpecified(const Zstring& file1, const Zstring& file2);
//---------------Inline Implementation---------------------------------------------------
#ifdef FFS_WIN
inline
-Utility::FileID::FileID() :
+util::FileID::FileID() :
dwVolumeSerialNumber(0),
nFileIndexHigh(0),
nFileIndexLow(0) {}
inline
-Utility::FileID::FileID(DWORD_FFS dwVolumeSN,
+util::FileID::FileID(DWORD_FFS dwVolumeSN,
DWORD_FFS fileIndexHi,
DWORD_FFS fileIndexLo) :
dwVolumeSerialNumber(dwVolumeSN),
@@ -99,7 +99,7 @@ Utility::FileID::FileID(DWORD_FFS dwVolumeSN,
nFileIndexLow(fileIndexLo) {}
inline
-bool Utility::FileID::isNull() const
+bool util::FileID::isNull() const
{
return dwVolumeSerialNumber == 0 &&
nFileIndexHigh == 0 &&
@@ -107,7 +107,7 @@ bool Utility::FileID::isNull() const
}
inline
-bool Utility::FileID::operator==(const FileID& rhs) const
+bool util::FileID::operator==(const FileID& rhs) const
{
return dwVolumeSerialNumber == rhs.dwVolumeSerialNumber &&
nFileIndexHigh == rhs.nFileIndexHigh &&
@@ -115,7 +115,7 @@ bool Utility::FileID::operator==(const FileID& rhs) const
}
inline
-bool Utility::FileID::operator<(const FileID& rhs) const
+bool util::FileID::operator<(const FileID& rhs) const
{
if (dwVolumeSerialNumber != rhs.dwVolumeSerialNumber)
return dwVolumeSerialNumber < rhs.dwVolumeSerialNumber;
@@ -127,7 +127,7 @@ bool Utility::FileID::operator<(const FileID& rhs) const
}
inline
-Utility::FileID::FileID(wxInputStream& stream) //read
+util::FileID::FileID(wxInputStream& stream) //read
{
stream.Read(&dwVolumeSerialNumber, sizeof(dwVolumeSerialNumber));
stream.Read(&nFileIndexHigh, sizeof(nFileIndexHigh));
@@ -135,7 +135,7 @@ Utility::FileID::FileID(wxInputStream& stream) //read
}
inline
-void Utility::FileID::toStream(wxOutputStream& stream) const //write
+void util::FileID::toStream(wxOutputStream& stream) const //write
{
stream.Write(&dwVolumeSerialNumber, sizeof(dwVolumeSerialNumber));
stream.Write(&nFileIndexHigh, sizeof(nFileIndexHigh));
@@ -144,32 +144,32 @@ void Utility::FileID::toStream(wxOutputStream& stream) const //write
#elif defined FFS_LINUX
inline
-Utility::FileID::FileID() :
+util::FileID::FileID() :
deviceId(0),
inodeId(0) {}
inline
-Utility::FileID::FileID(dev_t devId,
+util::FileID::FileID(dev_t devId,
ino_t inId) :
deviceId(devId),
inodeId(inId) {}
inline
-bool Utility::FileID::isNull() const
+bool util::FileID::isNull() const
{
return deviceId == 0 &&
inodeId == 0;
}
inline
-bool Utility::FileID::operator==(const FileID& rhs) const
+bool util::FileID::operator==(const FileID& rhs) const
{
return deviceId == rhs.deviceId &&
inodeId == rhs.inodeId;
}
inline
-bool Utility::FileID::operator<(const FileID& rhs) const
+bool util::FileID::operator<(const FileID& rhs) const
{
if (deviceId != rhs.deviceId)
return deviceId < rhs.deviceId;
@@ -178,21 +178,21 @@ bool Utility::FileID::operator<(const FileID& rhs) const
}
inline
-Utility::FileID::FileID(wxInputStream& stream) //read
+util::FileID::FileID(wxInputStream& stream) //read
{
stream.Read(&deviceId, sizeof(deviceId));
stream.Read(&inodeId, sizeof(inodeId));
}
inline
-void Utility::FileID::toStream(wxOutputStream& stream) const //write
+void util::FileID::toStream(wxOutputStream& stream) const //write
{
stream.Write(&deviceId, sizeof(deviceId));
stream.Write(&inodeId, sizeof(inodeId));
}
#endif
inline
-bool Utility::FileID::operator!=(const FileID& rhs) const
+bool util::FileID::operator!=(const FileID& rhs) const
{
return !(*this == rhs);
}
diff --git a/shared/fileIO.cpp b/shared/file_io.cpp
index 92fb7193..345234fd 100644
--- a/shared/fileIO.cpp
+++ b/shared/file_io.cpp
@@ -4,16 +4,18 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "fileIO.h"
+#include "file_io.h"
#include <wx/intl.h>
-#include "stringConv.h"
-#include "systemFunctions.h"
+#include "string_conv.h"
+#include "system_func.h"
#ifdef FFS_WIN
-#include "longPathPrefix.h"
+#include "long_path_prefix.h"
+#elif defined FFS_LINUX
+#include <errno.h>
#endif
-using namespace FreeFileSync;
+using namespace ffs3;
FileInput::FileInput(const Zstring& filename) : //throw FileError()
@@ -23,7 +25,7 @@ FileInput::FileInput(const Zstring& filename) : //throw FileError()
filename_(filename)
{
#ifdef FFS_WIN
- fileHandle = ::CreateFile(FreeFileSync::applyLongPathPrefix(filename).c_str(),
+ fileHandle = ::CreateFile(ffs3::applyLongPathPrefix(filename).c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, //all shared modes are required to read files that are open in other applications
NULL,
@@ -55,13 +57,25 @@ FileInput::FileInput(const Zstring& filename) : //throw FileError()
*/
NULL);
if (fileHandle == INVALID_HANDLE_VALUE)
- throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ {
+ const DWORD lastError = ::GetLastError();
+ const wxString& errorMessage = wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") + wxT("\n\n") + ffs3::getLastErrorFormatted(lastError);
+ if (lastError == ERROR_FILE_NOT_FOUND)
+ throw ErrorNotExisting(errorMessage);
+ else
+ throw FileError(errorMessage);
+ }
#elif defined FFS_LINUX
fileHandle = ::fopen(filename.c_str(), "rb,type=record,noseek"); //utilize UTF-8 filename
- if (!fileHandle)
- throw FileError(wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ if (fileHandle == NULL)
+ {
+ const int lastError = errno;
+ const wxString& errorMessage = wxString(_("Error opening file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") + wxT("\n\n") + ffs3::getLastErrorFormatted(lastError);
+ if (lastError == ENOENT)
+ throw ErrorNotExisting(errorMessage);
+ else
+ throw FileError(errorMessage);
+ }
#endif
}
@@ -84,12 +98,12 @@ size_t FileInput::read(void* buffer, size_t bytesToRead) //returns actual number
if (!::ReadFile(
fileHandle, //__in HANDLE hFile,
buffer, //__out LPVOID lpBuffer,
- static_cast<DWORD>(bytesToRead), //__in DWORD nNumberOfBytesToRead,
+ static_cast<DWORD>(bytesToRead), //__in DWORD nNumberOfBytesToRead,
&bytesRead, //__out_opt LPDWORD lpNumberOfBytesRead,
NULL) //__inout_opt LPOVERLAPPED lpOverlapped
|| bytesRead > bytesToRead) //must be fulfilled
throw FileError(wxString(_("Error reading file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ wxT("\n\n") + ffs3::getLastErrorFormatted());
if (bytesRead < bytesToRead)
eofReached = true;
@@ -99,7 +113,7 @@ size_t FileInput::read(void* buffer, size_t bytesToRead) //returns actual number
const size_t bytesRead = ::fread(buffer, 1, bytesToRead, fileHandle);
if (::ferror(fileHandle) != 0)
throw FileError(wxString(_("Error reading file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ wxT("\n\n") + ffs3::getLastErrorFormatted());
return bytesRead;
#endif
}
@@ -119,7 +133,7 @@ FileOutput::FileOutput(const Zstring& filename) : //throw FileError()
filename_(filename)
{
#ifdef FFS_WIN
- fileHandle = ::CreateFile(FreeFileSync::applyLongPathPrefix(filename).c_str(),
+ fileHandle = ::CreateFile(ffs3::applyLongPathPrefix(filename).c_str(),
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
@@ -128,12 +142,12 @@ FileOutput::FileOutput(const Zstring& filename) : //throw FileError()
NULL);
if (fileHandle == INVALID_HANDLE_VALUE)
throw FileError(wxString(_("Error writing file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ wxT("\n\n") + ffs3::getLastErrorFormatted());
#elif defined FFS_LINUX
fileHandle = ::fopen(filename.c_str(), "wb,type=record,noseek"); //utilize UTF-8 filename
if (!fileHandle)
throw FileError(wxString(_("Error writing file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ wxT("\n\n") + ffs3::getLastErrorFormatted());
#endif
}
@@ -157,12 +171,12 @@ void FileOutput::write(const void* buffer, size_t bytesToWrite) //throw FileErro
NULL) //__inout_opt LPOVERLAPPED lpOverlapped
|| bytesWritten != bytesToWrite) //must be fulfilled for synchronous writes!
throw FileError(wxString(_("Error writing file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ wxT("\n\n") + ffs3::getLastErrorFormatted() + wxT(" (w)")); //w -> distinguish from fopen error message!
#elif defined FFS_LINUX
const size_t bytesWritten = ::fwrite(buffer, 1, bytesToWrite, fileHandle);
if (::ferror(fileHandle) != 0 || bytesWritten != bytesToWrite)
throw FileError(wxString(_("Error writing file:")) + wxT("\n\"") + zToWx(filename_) + wxT("\"") +
- wxT("\n\n") + FreeFileSync::getLastErrorFormatted() + wxT(" (w)")); //w -> distinguish from fopen error message!
+ wxT("\n\n") + ffs3::getLastErrorFormatted() + wxT(" (w)")); //w -> distinguish from fopen error message!
#endif
}
diff --git a/shared/fileIO.h b/shared/file_io.h
index a04d8a0e..c3fb3f65 100644
--- a/shared/fileIO.h
+++ b/shared/file_io.h
@@ -16,19 +16,19 @@
#endif
#include "zstring.h"
-#include "fileError.h"
+#include "file_error.h"
-namespace FreeFileSync
+namespace ffs3
{
-//file IO optimized for sequential read/write accesses + better error reporting + long path support
+//file IO optimized for sequential read/write accesses + better error reporting + long path support (following symlinks)
class FileInput
{
public:
- FileInput(const Zstring& filename); //throw FileError()
+ FileInput(const Zstring& filename); //throw (FileError, ErrorNotExisting)
~FileInput();
- size_t read(void* buffer, size_t bytesToRead); //returns actual number of bytes read; throw FileError()
+ size_t read(void* buffer, size_t bytesToRead); //throw FileError(); returns actual number of bytes read
bool eof(); //end of file reached
private:
diff --git a/shared/fileTraverser.cpp b/shared/file_traverser.cpp
index 465c2f8f..8e9d5f0d 100644
--- a/shared/fileTraverser.cpp
+++ b/shared/file_traverser.cpp
@@ -4,18 +4,18 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "fileTraverser.h"
-#include "systemConstants.h"
-#include "systemFunctions.h"
+#include "file_traverser.h"
+#include "system_constants.h"
+#include "system_func.h"
#include <wx/intl.h>
-#include "stringConv.h"
+#include "string_conv.h"
#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp>
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include "WinIoCtl.h"
-#include "longPathPrefix.h"
+#include "long_path_prefix.h"
#elif defined FFS_LINUX
#include <sys/stat.h>
@@ -29,8 +29,8 @@
//{
//public:
// DisableWow64Redirection() :
-// wow64DisableWow64FsRedirection(Utility::loadDllFunction<Wow64DisableWow64FsRedirectionFunc>(L"kernel32.dll", "Wow64DisableWow64FsRedirection")),
-// wow64RevertWow64FsRedirection(Utility::loadDllFunction<Wow64RevertWow64FsRedirectionFunc>(L"kernel32.dll", "Wow64RevertWow64FsRedirection")),
+// wow64DisableWow64FsRedirection(util::loadDllFunction<Wow64DisableWow64FsRedirectionFunc>(L"kernel32.dll", "Wow64DisableWow64FsRedirection")),
+// wow64RevertWow64FsRedirection(util::loadDllFunction<Wow64RevertWow64FsRedirectionFunc>(L"kernel32.dll", "Wow64RevertWow64FsRedirection")),
// oldValue(NULL)
// {
// if ( wow64DisableWow64FsRedirection &&
@@ -164,7 +164,7 @@ inline
void setWin32FileInformation(const FILETIME& lastWriteTime,
const DWORD fileSizeHigh,
const DWORD fileSizeLow,
- FreeFileSync::TraverseCallback::FileInfo& output)
+ ffs3::TraverseCallback::FileInfo& output)
{
output.lastWriteTimeRaw = getWin32TimeInformation(lastWriteTime);
output.fileSize = wxULongLong(fileSizeHigh, fileSizeLow);
@@ -172,10 +172,10 @@ void setWin32FileInformation(const FILETIME& lastWriteTime,
inline
-bool setWin32FileInformationFromSymlink(const Zstring& linkName, FreeFileSync::TraverseCallback::FileInfo& output)
+bool setWin32FileInformationFromSymlink(const Zstring& linkName, ffs3::TraverseCallback::FileInfo& output)
{
//open handle to target of symbolic link
- HANDLE hFile = ::CreateFile(FreeFileSync::applyLongPathPrefix(linkName).c_str(),
+ HANDLE hFile = ::CreateFile(ffs3::applyLongPathPrefix(linkName).c_str(),
0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@@ -199,9 +199,9 @@ bool setWin32FileInformationFromSymlink(const Zstring& linkName, FreeFileSync::T
template <bool followSymlinks>
-void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback* sink, int level)
+void traverseDirectory(const Zstring& directory, ffs3::TraverseCallback* sink, int level)
{
- using namespace FreeFileSync;
+ using namespace ffs3;
if (level == 100) //catch endless recursion
{
@@ -211,9 +211,9 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
#ifdef FFS_WIN
//ensure directoryFormatted ends with backslash
- const Zstring directoryFormatted = directory.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ?
+ const Zstring directoryFormatted = directory.EndsWith(common::FILE_NAME_SEPARATOR) ?
directory :
- directory + globalFunctions::FILE_NAME_SEPARATOR;
+ directory + common::FILE_NAME_SEPARATOR;
WIN32_FIND_DATA fileMetaData;
HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(directoryFormatted + DefaultChar('*')).c_str(), //__in LPCTSTR lpFileName
@@ -228,7 +228,7 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
//else: we have a problem... report it:
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") + wxT("\n\n") +
- FreeFileSync::getLastErrorFormatted(lastError);
+ ffs3::getLastErrorFormatted(lastError);
sink->onError(errorMessage);
return;
@@ -298,7 +298,7 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
//else: we have a problem... report it:
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- sink->onError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted(lastError));
+ sink->onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted(lastError));
return;
#elif defined FFS_LINUX
@@ -306,7 +306,7 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
if (dirObj == NULL)
{
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- sink->onError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ sink->onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
return;
}
@@ -323,7 +323,7 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
//else: we have a problem... report it:
const wxString errorMessage = wxString(_("Error traversing directory:")) + wxT("\n\"") + zToWx(directory) + wxT("\"") ;
- sink->onError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ sink->onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
return;
}
@@ -334,15 +334,15 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
shortName[1] == wxChar('\0')))
continue;
- const Zstring fullName = directory.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ? //e.g. "/"
+ const Zstring fullName = directory.EndsWith(common::FILE_NAME_SEPARATOR) ? //e.g. "/"
directory + shortName :
- directory + globalFunctions::FILE_NAME_SEPARATOR + shortName;
+ directory + common::FILE_NAME_SEPARATOR + shortName;
struct stat fileInfo;
if (::lstat(fullName.c_str(), &fileInfo) != 0) //lstat() does not resolve symlinks
{
const wxString errorMessage = wxString(_("Error reading file attributes:")) + wxT("\n\"") + zToWx(fullName) + wxT("\"");
- sink->onError(errorMessage + wxT("\n\n") + FreeFileSync::getLastErrorFormatted());
+ sink->onError(errorMessage + wxT("\n\n") + ffs3::getLastErrorFormatted());
continue;
}
@@ -401,7 +401,7 @@ void traverseDirectory(const Zstring& directory, FreeFileSync::TraverseCallback*
}
-void FreeFileSync::traverseFolder(const Zstring& directory,
+void ffs3::traverseFolder(const Zstring& directory,
bool followSymlinks,
TraverseCallback* sink)
{
@@ -409,8 +409,8 @@ void FreeFileSync::traverseFolder(const Zstring& directory,
const Zstring& directoryFormatted = directory;
#elif defined FFS_LINUX
const Zstring directoryFormatted = //remove trailing slash
- directory.size() > 1 && directory.EndsWith(globalFunctions::FILE_NAME_SEPARATOR) ? //exception: allow '/'
- directory.BeforeLast(globalFunctions::FILE_NAME_SEPARATOR) :
+ directory.size() > 1 && directory.EndsWith(common::FILE_NAME_SEPARATOR) ? //exception: allow '/'
+ directory.BeforeLast(common::FILE_NAME_SEPARATOR) :
directory;
#endif
diff --git a/shared/fileTraverser.h b/shared/file_traverser.h
index b9cd3ff1..d61ff1cd 100644
--- a/shared/fileTraverser.h
+++ b/shared/file_traverser.h
@@ -13,7 +13,7 @@
//advanced file traverser returning metadata and hierarchical information on files and directories
-namespace FreeFileSync
+namespace ffs3
{
class TraverseCallback
{
@@ -61,7 +61,7 @@ public:
void traverseFolder(const Zstring& directory, bool followSymlinks, TraverseCallback* sink); //throw();
//followSymlinks:
//"true": Symlinks dereferenced and reported via onFile() and onDir() => onSymlink not used!
-//"false": Symlinks directly reported via onSymlink()
+//"false": Symlinks directly reported via onSymlink(), directory symlinks are not followed
}
#endif // FILETRAVERSER_H_INCLUDED
diff --git a/shared/globalFunctions.cpp b/shared/global_func.cpp
index 63831e1a..d1ab9d2c 100644
--- a/shared/globalFunctions.cpp
+++ b/shared/global_func.cpp
@@ -4,14 +4,14 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "globalFunctions.h"
+#include "global_func.h"
#include <wx/msgdlg.h>
#include <wx/file.h>
#include <wx/stopwatch.h>
-#include "systemConstants.h"
+#include "system_constants.h"
-size_t globalFunctions::getDigitCount(size_t number) //count number of digits
+size_t common::getDigitCount(size_t number) //count number of digits
{
return number == 0 ? 1 : static_cast<size_t>(::log10(static_cast<double>(number))) + 1;
}
@@ -81,7 +81,7 @@ void DebugLog::write(const wxString& logText)
}
logFile->Write(wxString(wxT("[")) + wxDateTime::Now().FormatTime() + wxT("] "));
- logFile->Write(logText + globalFunctions::LINE_BREAK);
+ logFile->Write(logText + common::LINE_BREAK);
}
//DebugLog logDebugInfo;
@@ -89,5 +89,5 @@ void DebugLog::write(const wxString& logText)
wxString getCodeLocation(const wxString file, const int line)
{
- return wxString(file).AfterLast(globalFunctions::FILE_NAME_SEPARATOR) + wxT(", LINE ") + wxLongLong(line).ToString() + wxT(" | ");
+ return wxString(file).AfterLast(common::FILE_NAME_SEPARATOR) + wxT(", LINE ") + wxLongLong(line).ToString() + wxT(" | ");
}
diff --git a/shared/globalFunctions.h b/shared/global_func.h
index fe65889f..ba455371 100644
--- a/shared/globalFunctions.h
+++ b/shared/global_func.h
@@ -19,7 +19,7 @@
class wxStopWatch;
-namespace globalFunctions
+namespace common
{
//------------------------------------------------
// FUNCTIONS
@@ -34,7 +34,7 @@ template <class T>
inline
T abs(const T& d) //absolute value
{
- return(d < 0 ? -d : d);
+ return d < 0 ? -d : d;
}
@@ -136,7 +136,7 @@ wxString getCodeLocation(const wxString file, const int line);
//---------------Inline Implementation---------------------------------------------------
template <class CharType, class T>
inline
-std::basic_string<CharType> globalFunctions::numberToString(const T& number) //convert number to string the C++ way
+std::basic_string<CharType> common::numberToString(const T& number) //convert number to string the C++ way
{
std::basic_ostringstream<CharType> ss;
ss << number;
@@ -146,7 +146,7 @@ std::basic_string<CharType> globalFunctions::numberToString(const T& number) //c
template <class T, class CharType>
inline
-T globalFunctions::stringToNumber(const std::basic_string<CharType>& input) //convert number to string the C++ way
+T common::stringToNumber(const std::basic_string<CharType>& input) //convert number to string the C++ way
{
std::basic_istringstream<CharType> ss(input);
T number;
@@ -157,7 +157,7 @@ T globalFunctions::stringToNumber(const std::basic_string<CharType>& input) //co
template <class T>
inline
-wxString globalFunctions::numberToString(const T& number)
+wxString common::numberToString(const T& number)
{
return numberToString<wxChar, T>(number).c_str();
}
@@ -165,16 +165,16 @@ wxString globalFunctions::numberToString(const T& number)
template <class T>
inline
-T globalFunctions::stringToNumber(const wxString& input)
+T common::stringToNumber(const wxString& input)
{
- const std::basic_string<wxChar> inputConv = input.c_str();
+ const std::basic_string<wxChar> inputConv(input.c_str());
return stringToNumber<T, wxChar>(inputConv);
}
//Note: the following lines are a performance optimization for deleting elements from a vector: linear runtime at most!
template <class T>
-void globalFunctions::removeRowsFromVector(const std::set<size_t>& rowsToRemove, std::vector<T>& grid)
+void common::removeRowsFromVector(const std::set<size_t>& rowsToRemove, std::vector<T>& grid)
{
if (rowsToRemove.empty())
return;
@@ -208,7 +208,7 @@ void globalFunctions::removeRowsFromVector(const std::set<size_t>& rowsToRemove,
//enhanced binary search template: returns an iterator
template <class ForwardIterator, class T, typename Compare>
inline
-ForwardIterator globalFunctions::custom_binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp)
+ForwardIterator common::custom_binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp)
{
first = lower_bound(first, last, value, comp);
if (first != last && !comp(value, *first))
@@ -220,7 +220,7 @@ ForwardIterator globalFunctions::custom_binary_search(ForwardIterator first, For
template <class T>
inline
-T globalFunctions::readNumber(std::istream& stream)
+T common::readNumber(std::istream& stream)
{
T result = 0;
stream.read(reinterpret_cast<char*>(&result), sizeof(T));
@@ -230,7 +230,7 @@ T globalFunctions::readNumber(std::istream& stream)
template <class T>
inline
-void globalFunctions::writeNumber(std::ostream& stream, T number)
+void common::writeNumber(std::ostream& stream, T number)
{
stream.write(reinterpret_cast<const char*>(&number), sizeof(T));
}
diff --git a/shared/guid.cpp b/shared/guid.cpp
index 7a2ec68f..d359c29c 100644
--- a/shared/guid.cpp
+++ b/shared/guid.cpp
@@ -8,17 +8,17 @@
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <cassert>
-#include <algorithm>
-#include <vector>
+#include <algorithm>
+#include <vector>
+
+using namespace util;
+
-using namespace Utility;
-
-
struct UniqueId::IntData
-{
- boost::uuids::uuid nativeRep;
+{
+ boost::uuids::uuid nativeRep;
};
-
+
UniqueId::UniqueId() : pData(new IntData)
{
@@ -35,7 +35,7 @@ bool UniqueId::operator==(const UniqueId rhs) const
bool UniqueId::operator<(const UniqueId rhs) const
{
return pData->nativeRep < rhs.pData->nativeRep;
-}
+}
UniqueId::UniqueId(wxInputStream& stream) : //read
diff --git a/shared/guid.h b/shared/guid.h
index d639fff5..49d2f008 100644
--- a/shared/guid.h
+++ b/shared/guid.h
@@ -10,7 +10,7 @@
#include <wx/stream.h>
#include <boost/shared_ptr.hpp>
-namespace Utility
+namespace util
{
class UniqueId
{
@@ -27,7 +27,6 @@ private:
struct IntData;
boost::shared_ptr<IntData> pData;
};
-
}
diff --git a/shared/helpProvider.cpp b/shared/help_provider.cpp
index 73c71eb1..0110934c 100644
--- a/shared/helpProvider.cpp
+++ b/shared/help_provider.cpp
@@ -4,9 +4,9 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "helpProvider.h"
+#include "help_provider.h"
#include <wx/help.h>
-#include "standardPaths.h"
+#include "standard_paths.h"
#include <wx/image.h>
namespace
@@ -16,7 +16,7 @@ class HelpProvider
public:
HelpProvider()
{
- controller.Initialize(FreeFileSync::getResourceDir() +
+ controller.Initialize(ffs3::getResourceDir() +
#ifdef FFS_WIN
wxT("FreeFileSync.chm"));
#elif defined FFS_LINUX
@@ -39,7 +39,7 @@ private:
};
}
-void FreeFileSync::displayHelpEntry(const wxString& section)
+void ffs3::displayHelpEntry(const wxString& section)
{
static HelpProvider provider;
provider.showHelp(section);
diff --git a/shared/helpProvider.h b/shared/help_provider.h
index 538e151c..b59f47a8 100644
--- a/shared/helpProvider.h
+++ b/shared/help_provider.h
@@ -9,7 +9,7 @@
#include <wx/string.h>
-namespace FreeFileSync
+namespace ffs3
{
void displayHelpEntry(const wxString& section = wxEmptyString);
}
diff --git a/shared/localization.cpp b/shared/localization.cpp
index 1ff7f6bd..ef3e02d2 100644
--- a/shared/localization.cpp
+++ b/shared/localization.cpp
@@ -6,15 +6,15 @@
//
#include "localization.h"
#include <wx/msgdlg.h>
-#include "../shared/standardPaths.h"
-#include "../shared/stringConv.h"
-#include "systemConstants.h"
+#include "../shared/standard_paths.h"
+#include "../shared/string_conv.h"
+#include "system_constants.h"
#include <fstream>
#include <map>
#include <wx/ffile.h>
-using FreeFileSync::CustomLocale;
-using FreeFileSync::LocalizationInfo;
+using ffs3::CustomLocale;
+using ffs3::LocalizationInfo;
//_("Browse") <- dummy string for wxDirPickerCtrl to be recognized by automatic text extraction!
@@ -27,19 +27,19 @@ wxString DECIMAL_POINT = wxT(".");
}
-wxString FreeFileSync::getThousandsSeparator()
+wxString ffs3::getThousandsSeparator()
{
return THOUSANDS_SEPARATOR;
}
-wxString FreeFileSync::getDecimalPoint()
+wxString ffs3::getDecimalPoint()
{
return DECIMAL_POINT;
}
-const std::vector<FreeFileSync::LocInfoLine>& LocalizationInfo::getMapping()
+const std::vector<ffs3::LocInfoLine>& LocalizationInfo::getMapping()
{
static LocalizationInfo instance;
return instance.locMapping;
@@ -50,7 +50,7 @@ namespace
{
struct CompareByName
{
- bool operator()(const FreeFileSync::LocInfoLine& lhs, const FreeFileSync::LocInfoLine& rhs) const
+ bool operator()(const ffs3::LocInfoLine& lhs, const ffs3::LocInfoLine& rhs) const
{
return lhs.languageName < rhs.languageName;
}
@@ -60,7 +60,7 @@ struct CompareByName
LocalizationInfo::LocalizationInfo()
{
- FreeFileSync::LocInfoLine newEntry;
+ ffs3::LocInfoLine newEntry;
newEntry.languageID = wxLANGUAGE_CZECH;
newEntry.languageName = wxT("Čeština");
@@ -501,8 +501,8 @@ void CustomLocale::setLanguage(const int language)
translationDB->clear();
if (!languageFile.empty())
{
- UnicodeFileReader langFile(FreeFileSync::getResourceDir() + wxT("Languages") +
- zToWx(globalFunctions::FILE_NAME_SEPARATOR) + languageFile);
+ UnicodeFileReader langFile(ffs3::getResourceDir() + wxT("Languages") +
+ zToWx(common::FILE_NAME_SEPARATOR) + languageFile);
if (langFile.isOkay())
{
int rowNumber = 0;
diff --git a/shared/localization.h b/shared/localization.h
index 1e4cb6ed..1c1773e9 100644
--- a/shared/localization.h
+++ b/shared/localization.h
@@ -14,7 +14,7 @@
class Translation;
-namespace FreeFileSync
+namespace ffs3
{
//language independent global variables: just use operating system's default setting!
wxString getThousandsSeparator();
diff --git a/shared/lock.cpp b/shared/lock.cpp
index e8e027c2..6b3dbcbb 100644
--- a/shared/lock.cpp
+++ b/shared/lock.cpp
@@ -5,18 +5,18 @@
// **************************************************************************
//
#include "lock.h"
-#include "fileHandling.h"
+#include "file_handling.h"
//
//
-//Utility::LockDirectory::LockDirectory(const Zstring& dirname)
+//util::LockDirectory::LockDirectory(const Zstring& dirname)
//{
//
//}
//
//
-//Utility::LockDirectory::~LockDirectory()
+//util::LockDirectory::~LockDirectory()
//{
//}
//
//
-//bool Utility::LockDirectoryisLocked(const Zstring& dirname);
+//bool util::LockDirectoryisLocked(const Zstring& dirname);
diff --git a/shared/longPathPrefix.cpp b/shared/long_path_prefix.cpp
index e8b14b90..bc784f70 100644
--- a/shared/longPathPrefix.cpp
+++ b/shared/long_path_prefix.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "longPathPrefix.h"
+#include "long_path_prefix.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
@@ -30,20 +30,20 @@ Zstring applyLongPathPrefixImpl(const Zstring& path)
}
-Zstring FreeFileSync::applyLongPathPrefix(const Zstring& path)
+Zstring ffs3::applyLongPathPrefix(const Zstring& path)
{
return applyLongPathPrefixImpl<MAX_PATH>(path);
}
-Zstring FreeFileSync::applyLongPathPrefixCreateDir(const Zstring& path) //throw()
+Zstring ffs3::applyLongPathPrefixCreateDir(const Zstring& path) //throw()
{
//special rule for ::CreateDirectoryEx(): MAX_PATH - 12(=^ 8.3 filename) is threshold
return applyLongPathPrefixImpl<MAX_PATH - 12>(path);
}
-Zstring FreeFileSync::removeLongPathPrefix(const Zstring& path) //throw()
+Zstring ffs3::removeLongPathPrefix(const Zstring& path) //throw()
{
if (path.StartsWith(LONG_PATH_PREFIX))
{
diff --git a/shared/longPathPrefix.h b/shared/long_path_prefix.h
index 4ebe7a9d..b14a17dc 100644
--- a/shared/longPathPrefix.h
+++ b/shared/long_path_prefix.h
@@ -13,7 +13,7 @@ use in windows build only!
#include "zstring.h"
-namespace FreeFileSync
+namespace ffs3
{
//handle filenames longer-equal 260 (== MAX_PATH) characters by applying \\?\-prefix (Reference: http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath)
/*
diff --git a/shared/parallelCall.cpp b/shared/parallelCall.cpp
deleted file mode 100644
index ce0a3633..00000000
--- a/shared/parallelCall.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
-// **************************************************************************
-//
-#include "parallelCall.h"
-#include <wx/thread.h>
-#include <stdexcept>
-#include <wx/string.h>
-#include <wx/msgdlg.h>
-
-namespace
-{
-class WorkerThread : public wxThread
-{
-public:
- WorkerThread(const Async::AsyncProcess& proc,
- const boost::shared_ptr<wxMutex>& mainIsListening,
- const boost::shared_ptr<wxCondition>& procHasFinished) :
- wxThread(wxTHREAD_DETACHED),
- proc_(proc), //copy input data by value
- mainIsListening_(mainIsListening), //
- procHasFinished_(procHasFinished) //
- {
- if (Create() != wxTHREAD_NO_ERROR)
- throw std::runtime_error("Error creating async worker thread!");
-
- if (Run() != wxTHREAD_NO_ERROR)
- throw std::runtime_error("Error starting async worker thread!");
- }
-
- ExitCode Entry()
- {
- try
- {
- proc_->doWork();
-
- //notify that work is done
- wxMutexLocker dummy(*mainIsListening_);
- procHasFinished_->Signal();
- }
- catch (const std::exception& e) //exceptions must be catched per thread
- {
- wxMessageBox(wxString::FromAscii(e.what()), _("An exception occured!"), wxOK | wxICON_ERROR);
- }
- catch (...) //exceptions must be catched per thread
- {
- wxMessageBox(wxT("Unknown exception in worker thread"), _("An exception occured!"), wxOK | wxICON_ERROR);
- }
-
- return 0;
- }
-
-private:
- Async::AsyncProcess proc_;
- boost::shared_ptr<wxMutex> mainIsListening_; //shared pointer is safe to use in MT context (same guarantee like builtin types!)
- boost::shared_ptr<wxCondition> procHasFinished_; //http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm#ThreadSafety
-};
-}
-
-
-Async::Result Async::execute(AsyncProcess proc, size_t maxWait) //maxWait = max. wait time in milliseconds
-{
- boost::shared_ptr<wxMutex> mainIsListening(new wxMutex);
- boost::shared_ptr<wxCondition> procHasFinished(new wxCondition(*mainIsListening));
- wxMutexLocker dummy(*mainIsListening); //the mutex should be initially locked (= "main not listening")
-
- new WorkerThread(proc, mainIsListening, procHasFinished);
-
- return procHasFinished->WaitTimeout(static_cast<unsigned long>(maxWait)) == wxCOND_NO_ERROR ? WORK_DONE : TIMEOUT;
-}
-
-
-// ------------------------------------------------------
-// |Pattern: workload queue and multiple worker threads |
-// ------------------------------------------------------
-//typedef std::vector<DirectoryDescrType*> Workload;
-//
-//class ThreadSorting : public wxThread
-//{
-//public:
-// ThreadSorting(wxCriticalSection& syncWorkload, Workload& workload) :
-// wxThread(wxTHREAD_JOINABLE),
-// syncWorkload_(syncWorkload),
-// workload_(workload)
-// {
-// if (Create() != wxTHREAD_NO_ERROR)
-// throw RuntimeException(wxString(wxT("Error creating thread for sorting!")));
-// }
-//
-// ~ThreadSorting() {}
-//
-//
-// ExitCode Entry()
-// {
-// while (true)
-// {
-// DirectoryDescrType* descr = NULL;
-// { //see if there is work to do...
-// wxCriticalSectionLocker dummy(syncWorkload_);
-// if (workload_.empty())
-// return 0;
-// else
-// {
-// descr = workload_.back();
-// workload_.pop_back();
-// }
-// }
-// //do work
-// std::sort(descr->begin(), descr->end());
-// }
-// }
-//
-//private:
-// wxCriticalSection& syncWorkload_;
-// Workload& workload_;
-//};
-//
-//
-//void DirectoryDescrBuffer::preFillBuffers(const std::vector<FolderPairCfg>& fpConfigFormatted)
-//{
-// //assemble workload
-// ...
-//
-// //we use binary search when comparing the directory structures: so sort() first
-// const int CPUCount = wxThread::GetCPUCount();
-// if (CPUCount >= 2) //do it the multithreaded way:
-// {
-// wxCriticalSection syncWorkload;
-//
-// typedef std::vector<boost::shared_ptr<ThreadSorting> > ThreadContainer;
-// ThreadContainer sortThreads;
-// sortThreads.reserve(CPUCount);
-//
-// //start CPUCount worker threads
-// for (size_t i = 0; i < std::min(static_cast<size_t>(CPUCount), workload.size()); ++i)
-// {
-// boost::shared_ptr<ThreadSorting> newWorker(new ThreadSorting(syncWorkload, workload));
-//
-// if (newWorker->Run() != wxTHREAD_NO_ERROR)
-// throw RuntimeException(wxString(wxT("Error starting thread for sorting!")));
-//
-// sortThreads.push_back(newWorker);
-// }
-//
-// //wait until all worker are finished
-// for (ThreadContainer::iterator i = sortThreads.begin(); i != sortThreads.end(); ++i)
-// {
-// if ((*i)->Wait() != 0)
-// throw RuntimeException(wxString(wxT("Error waiting for thread (sorting)!")));
-// }
-// }
-// else //single threaded
-// {
-// for (Workload::iterator i = workload.begin(); i != workload.end(); ++i)
-// std::sort((*i)->begin(), (*i)->end());
-// }
-//}
diff --git a/shared/parallelCall.h b/shared/parallelCall.h
deleted file mode 100644
index b6e6b6ca..00000000
--- a/shared/parallelCall.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
-// **************************************************************************
-//
-#ifndef MULTITHREADING_H_INCLUDED
-#define MULTITHREADING_H_INCLUDED
-
-#include <boost/shared_ptr.hpp>
-
-
-namespace Async
-{
-class Procedure
-{
-public:
- virtual ~Procedure() {}
- virtual void doWork() = 0;
-};
-
-enum Result
-{
- TIMEOUT,
- WORK_DONE
-};
-
-typedef boost::shared_ptr<Procedure> AsyncProcess;
-
-//wait for Procedure to finish in separate thread; shared data (Procedure*) may be accessed after WORK_DONE only! => Beware shared data if TIMEOUT (e.g. ref-counting!)
-Result execute(AsyncProcess proc, size_t maxWait); //maxWait = max. wait time in milliseconds
-}
-
-#endif // MULTITHREADING_H_INCLUDED
diff --git a/shared/perf.h b/shared/perf.h
new file mode 100644
index 00000000..62473259
--- /dev/null
+++ b/shared/perf.h
@@ -0,0 +1,42 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#include <windows.h>
+#include <sstream>
+
+class Performance
+{
+public:
+ Performance() : resultWasShown(false), startTime(::GetTickCount()) {}
+
+ ~Performance()
+ {
+ if (!resultWasShown)
+ showResult();
+ }
+
+ void showResult()
+ {
+ resultWasShown = true;
+
+ const DWORD currentTime = ::GetTickCount();
+ const DWORD delta = currentTime - startTime;
+ startTime = currentTime;
+
+ std::ostringstream ss;
+ ss << delta << " ms";
+
+ ::MessageBoxA(NULL, ss.str().c_str(), "Timer", 0);
+ }
+
+private:
+ bool resultWasShown;
+ DWORD startTime;
+};
+
+//two macros for quick performance measurements
+#define PERF_START Performance a;
+#define PERF_STOP a.showResult();
diff --git a/shared/recycler.cpp b/shared/recycler.cpp
index b9f666f8..1a73e105 100644
--- a/shared/recycler.cpp
+++ b/shared/recycler.cpp
@@ -5,21 +5,21 @@
// **************************************************************************
//
#include "recycler.h"
-#include "stringConv.h"
+#include "string_conv.h"
#include <wx/intl.h>
#include <stdexcept>
#include <iterator>
#ifdef FFS_WIN
-#include "dllLoader.h"
+#include "dll_loader.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include "buildInfo.h"
-#include "staticAssert.h"
+#include "build_info.h"
+#include "assert_static.h"
#include <algorithm>
#include <functional>
#include <vector>
-#include "longPathPrefix.h"
-#include "IFileOperation/fileOp.h"
+#include "long_path_prefix.h"
+#include "IFileOperation/file_op.h"
#elif defined FFS_LINUX
#include <sys/stat.h>
@@ -33,11 +33,11 @@ namespace
const std::wstring& getRecyclerDllName()
{
static const std::wstring filename(
- Utility::is64BitBuild ?
+ util::is64BitBuild ?
L"FileOperation_x64.dll":
L"FileOperation_Win32.dll");
- assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
+ assert_static(util::is32BitBuild || util::is64BitBuild);
return filename;
}
@@ -73,7 +73,7 @@ Nevertheless, let's use IFileOperation for better error reporting!
void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (FileError)
{
- using FreeFileSync::FileError;
+ using ffs3::FileError;
if (filesToDelete.empty())
return;
@@ -82,25 +82,26 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (
if (useIFileOperation) //new recycle bin usage: available since Vista
{
+ std::vector<const wchar_t*> fileNames;
+ std::transform(filesToDelete.begin(), filesToDelete.end(),
+ std::back_inserter(fileNames), std::mem_fun_ref(&Zstring::c_str));
+
using namespace FileOp;
static const MoveToRecycleBinFct moveToRecycler =
- Utility::loadDllFunction<MoveToRecycleBinFct>(getRecyclerDllName().c_str(), moveToRecycleBinFctName);
+ util::loadDllFunction<MoveToRecycleBinFct>(getRecyclerDllName().c_str(), moveToRecycleBinFctName);
static const GetLastErrorFct getLastError =
- Utility::loadDllFunction<GetLastErrorFct>(getRecyclerDllName().c_str(), getLastErrorFctName);
+ util::loadDllFunction<GetLastErrorFct>(getRecyclerDllName().c_str(), getLastErrorFctName);
if (moveToRecycler == NULL || getLastError == NULL)
- throw FileError(wxString(_("Could not load a required DLL:")) + wxT(" \"") + getRecyclerDllName().c_str() + wxT("\""));
+ throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + fileNames[0] + wxT("\"\n\n") + //report first file only... better than nothing
+ wxString(_("Could not load a required DLL:")) + wxT(" \"") + getRecyclerDllName().c_str() + wxT("\""));
//#warning moving long file paths to recycler does not work! clarify!
// std::vector<Zstring> temp;
// std::transform(filesToDelete.begin(), filesToDelete.end(),
-// std::back_inserter(temp), std::ptr_fun(FreeFileSync::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix!
-
- std::vector<const wchar_t*> fileNames;
- std::transform(filesToDelete.begin(), filesToDelete.end(),
- std::back_inserter(fileNames), std::mem_fun_ref(&Zstring::c_str));
+// std::back_inserter(temp), std::ptr_fun(ffs3::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix!
if (!(*moveToRecycler)(&fileNames[0], //array must not be empty
fileNames.size()))
@@ -143,7 +144,7 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw (
}
-void FreeFileSync::moveToRecycleBin(const Zstring& fileToDelete) //throw (FileError)
+void ffs3::moveToRecycleBin(const Zstring& fileToDelete) //throw (FileError)
{
#ifdef FFS_WIN
const Zstring filenameFmt = applyLongPathPrefix(fileToDelete);
@@ -165,7 +166,8 @@ void FreeFileSync::moveToRecycleBin(const Zstring& fileToDelete) //throw (FileE
try
{
if (!fileObj->trash())
- throw std::runtime_error("Recycle Bin failed but did not provide error information!");
+ throw FileError(wxString(_("Error moving to Recycle Bin:")) + wxT("\n\"") + zToWx(fileToDelete) + wxT("\"\n\n") +
+ wxT("(") + wxT("unknown error") + wxT(")"));
}
catch (const Glib::Error& errorObj)
{
@@ -180,7 +182,7 @@ void FreeFileSync::moveToRecycleBin(const Zstring& fileToDelete) //throw (FileE
}
-bool FreeFileSync::recycleBinExists()
+bool ffs3::recycleBinExists()
{
#ifdef FFS_WIN
return true;
diff --git a/shared/recycler.h b/shared/recycler.h
index 828e26af..7537e875 100644
--- a/shared/recycler.h
+++ b/shared/recycler.h
@@ -7,10 +7,10 @@
#ifndef RECYCLER_H_INCLUDED
#define RECYCLER_H_INCLUDED
-#include "fileError.h"
+#include "file_error.h"
#include "zstring.h"
-namespace FreeFileSync
+namespace ffs3
{
/*
--------------------
diff --git a/shared/serialize.cpp b/shared/serialize.cpp
index 63e2037f..cf6d96b1 100644
--- a/shared/serialize.cpp
+++ b/shared/serialize.cpp
@@ -7,12 +7,12 @@
#include "serialize.h"
#include <wx/intl.h>
-using namespace Utility;
+using namespace util;
void ReadInputStream::throwReadError() const //throw FileError()
{
- throw FreeFileSync::FileError(wxString(_("Error reading from synchronization database:")) + wxT(" \n") +
+ throw ffs3::FileError(wxString(_("Error reading from synchronization database:")) + wxT(" \n") +
wxT("\"") + errorObjName_ + wxT("\""));
}
@@ -35,7 +35,7 @@ ReadInputStream::CharArray ReadInputStream::readArrayC() const
//--------------------------------------------------------------------------------------------------------
void WriteOutputStream::throwWriteError() const //throw FileError()
{
- throw FreeFileSync::FileError(wxString(_("Error writing to synchronization database:")) + wxT(" \n") +
+ throw ffs3::FileError(wxString(_("Error writing to synchronization database:")) + wxT(" \n") +
wxT("\"") + errorObjName_ + wxT("\""));
}
diff --git a/shared/serialize.h b/shared/serialize.h
index 88e6054c..99dd83d5 100644
--- a/shared/serialize.h
+++ b/shared/serialize.h
@@ -9,11 +9,11 @@
#include "zstring.h"
#include <wx/stream.h>
-#include "fileError.h"
+#include "file_error.h"
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
-namespace Utility
+namespace util
{
template <class T>
T readNumber(wxInputStream& stream);
diff --git a/shared/shadow.cpp b/shared/shadow.cpp
index 3909c37b..b38103de 100644
--- a/shared/shadow.cpp
+++ b/shared/shadow.cpp
@@ -7,16 +7,21 @@
#include "shadow.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include <wx/intl.h>
-#include "systemConstants.h"
-#include "dllLoader.h"
+#include "system_constants.h"
+#include "dll_loader.h"
#include <stdexcept>
-#include "staticAssert.h"
-#include "buildInfo.h"
+#include "assert_static.h"
+#include "build_info.h"
#include "ShadowCopy\shadow.h"
+#include "string_conv.h"
-using FreeFileSync::ShadowCopy;
+using shadow::ShadowCopy;
+using shadow::WaitingForShadow;
+using ffs3::FileError;
+namespace
+{
bool newerThanXP()
{
OSVERSIONINFO osvi;
@@ -41,7 +46,7 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
PBOOL Wow64Process);
static const IsWow64ProcessFunc isWow64Process =
- Utility::loadDllFunction<IsWow64ProcessFunc>(L"kernel32.dll", "IsWow64Process");
+ util::loadDllFunction<IsWow64ProcessFunc>(L"kernel32.dll", "IsWow64Process");
if (isWow64Process)
{
@@ -54,148 +59,145 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
}
-const wxString& getShadowDllName()
+const std::wstring& getShadowDllName()
{
/*
distinguish a bunch of VSS builds: we use XP and Server 2003 implementations...
VSS version and compatibility overview: http://msdn.microsoft.com/en-us/library/aa384627(VS.85).aspx
*/
- static const wxString filename(
+ assert_static(util::is32BitBuild || util::is64BitBuild);
+
+ static const std::wstring filename(
newerThanXP() ?
- (Utility::is64BitBuild ?
- wxT("Shadow_Server2003_x64.dll") :
- wxT("Shadow_Server2003_Win32.dll")) :
+ (util::is64BitBuild ?
+ L"Shadow_Server2003_x64.dll" :
+ L"Shadow_Server2003_Win32.dll") :
- (Utility::is64BitBuild ?
- wxT("Shadow_XP_x64.dll") :
- wxT("Shadow_XP_Win32.dll")));
+ (util::is64BitBuild ?
+ L"Shadow_XP_x64.dll" :
+ L"Shadow_XP_Win32.dll"));
- assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
return filename;
}
-
+}
//#############################################################################################################
-ShadowCopy::ShadowCopy() :
- backupHandle(NULL) {}
+ShadowCopy::ShadowCopy(WaitingForShadow* callback) : callback_(callback) {}
+ShadowCopy::~ShadowCopy() {} //std::auto_ptr: keep non-inline
+//#############################################################################################################
-ShadowCopy::~ShadowCopy()
+class ShadowCopy::ShadowVolume
{
- if (backupHandle != NULL)
+public:
+ ShadowVolume(const Zstring& volumeNameFormatted) : //throw(FileError)
+ realVol(volumeNameFormatted),
+ backupHandle(NULL)
{
- using namespace Shadow;
+ using namespace shadow;
- static const ReleaseShadowCopyFct releaseShadowCopy =
- Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), releaseShadowCopyFctName);
+ if (!createShadowCopy)
+ createShadowCopy = util::loadDllFunction<CreateShadowCopyFct>(getShadowDllName(), createShadowCopyFctName);
- if (releaseShadowCopy == NULL)
- throw std::logic_error("Could not load \"releaseShadowCopy\"!"); //shouldn't arrive here!
+ if (!releaseShadowCopy)
+ releaseShadowCopy = util::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName(), releaseShadowCopyFctName);
- releaseShadowCopy(backupHandle);
- }
-}
+ //check if shadow copy dll was loaded correctly
+ if ( createShadowCopy == NULL ||
+ releaseShadowCopy == NULL)
+ throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
+ _("Could not load a required DLL:") + wxT(" \"") + getShadowDllName().c_str() + wxT("\""));
+ //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)
+ static const bool wow64Active = runningWOW64();
+ if (wow64Active)
+ throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
+ _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
-Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
-{
- using namespace Shadow;
+//---------------------------------------------------------------------------------------------------------
+ //start shadow volume copy service:
+ wchar_t shadowVolName[1000];
+ wchar_t errorMessage[1000];
+
+ if (!createShadowCopy(
+ volumeNameFormatted.c_str(),
+ shadowVolName,
+ 1000,
+ &backupHandle,
+ errorMessage,
+ 1000))
+ throw FileError(wxString(_("Error starting Volume Shadow Copy Service!")) + wxT("\n") +
+ wxT("(") + errorMessage + wxT(" Volume: \"") + volumeNameFormatted.c_str() + wxT("\")"));
- static const CreateShadowCopyFct createShadowCopy =
- Utility::loadDllFunction<CreateShadowCopyFct>(getShadowDllName().c_str(), createShadowCopyFctName);
+ shadowVol = Zstring(shadowVolName) + common::FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash
+ }
- static const ReleaseShadowCopyFct releaseShadowCopy =
- Utility::loadDllFunction<ReleaseShadowCopyFct>(getShadowDllName().c_str(), releaseShadowCopyFctName);
+ ~ShadowVolume()
+ {
+ releaseShadowCopy(backupHandle);
+ }
- //check if shadow copy dll was loaded correctly
- if ( createShadowCopy == NULL ||
- releaseShadowCopy == NULL)
+ Zstring getShadowVolume() const //trailing path separator
{
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\""));
- throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") +
- _("Could not load a required DLL:") + wxT(" \"") + getShadowDllName() + wxT("\""));
+ return shadowVol;
}
- //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)
- static const bool wow64Active = runningWOW64();
- if (wow64Active)
+ Zstring getRealVolume() const //trailing path separator
{
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\""));
- throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") +
- _("Making shadow copies on WOW64 is not supported. Please use FreeFileSync 64-bit version."));
+ return realVol;
}
+private:
+ ShadowVolume(const ShadowVolume&);
+ ShadowVolume& operator=(const ShadowVolume&);
+
+ static shadow::CreateShadowCopyFct createShadowCopy;
+ static shadow::ReleaseShadowCopyFct releaseShadowCopy;
+
+ Zstring shadowVol;
+ const Zstring realVol;
+
+ void* backupHandle;
+};
+
+
+shadow::CreateShadowCopyFct ShadowCopy::ShadowVolume::createShadowCopy;
+shadow::ReleaseShadowCopyFct ShadowCopy::ShadowVolume::releaseShadowCopy;
+//#############################################################################################################
+
+
+Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile)
+{
+ using namespace ffs3;
-//---------------------------------------------------------------------------------------------------------
wchar_t volumeNameRaw[1000];
if (!::GetVolumePathName(inputFile.c_str(), //__in LPCTSTR lpszFileName,
volumeNameRaw, //__out LPTSTR lpszVolumePathName,
1000)) //__in DWORD cchBufferLength
- {
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\""));
- throw FileError(errorMsg + wxT("\n\n") + _("Could not determine volume name for file:") + wxT("\n\"") + inputFile.c_str() + wxT("\""));
- }
+ throw FileError(wxString(_("Could not determine volume name for file:")) + wxT("\n\"") + zToWx(inputFile) + wxT("\""));
Zstring volumeNameFormatted = volumeNameRaw;
- if (!volumeNameFormatted.EndsWith(globalFunctions::FILE_NAME_SEPARATOR))
- volumeNameFormatted += globalFunctions::FILE_NAME_SEPARATOR;
-
- if (volumeNameFormatted != realVolumeLast)
- {
- //release old shadow copy
- if (backupHandle != NULL)
- {
- releaseShadowCopy(backupHandle);
- backupHandle = NULL;
- }
- realVolumeLast.clear(); //...if next call fails...
- shadowVolumeLast.clear(); //...if next call fails...
-
- //start shadow volume copy service:
- wchar_t shadowVolName[1000];
- void* backupHandleTmp = NULL;
- wchar_t errorMessage[1000];
-
- if (!createShadowCopy(
- volumeNameFormatted.c_str(),
- shadowVolName,
- 1000,
- &backupHandleTmp,
- errorMessage,
- 1000))
- {
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), Zstring(wxT("\"")) + inputFile + wxT("\""));
- throw FileError(errorMsg + wxT("\n\n") + _("Error starting Volume Shadow Copy Service!") + wxT("\n") +
- wxT("(") + errorMessage + wxT(" Volume: \"") + volumeNameFormatted.c_str() + wxT("\")"));
- }
-
- realVolumeLast = volumeNameFormatted;
- shadowVolumeLast = Zstring(shadowVolName) + globalFunctions::FILE_NAME_SEPARATOR; //shadowVolName NEVER has a trailing backslash
- backupHandle = backupHandleTmp;
- }
+ if (!volumeNameFormatted.EndsWith(common::FILE_NAME_SEPARATOR))
+ volumeNameFormatted += common::FILE_NAME_SEPARATOR;
//input file is always absolute! directory formatting takes care of this! Therefore volume name can always be found.
const size_t pos = inputFile.find(volumeNameFormatted); //inputFile needs NOT to begin with volumeNameFormatted: consider for example \\?\ prefix!
if (pos == Zstring::npos)
{
- wxString errorMsg = _("Error copying locked file %x!");
- errorMsg.Replace(wxT("%x"), Zstring(wxT("\"")) + inputFile + wxT("\""));
-
wxString msg = _("Volume name %x not part of filename %y!");
- msg.Replace(wxT("%x"), wxString(wxT("\"")) + volumeNameFormatted.c_str() + wxT("\""), false);
- msg.Replace(wxT("%y"), wxString(wxT("\"")) + inputFile.c_str() + wxT("\""), false);
- throw FileError(errorMsg + wxT("\n\n") + msg);
+ msg.Replace(wxT("%x"), wxString(wxT("\"")) + zToWx(volumeNameFormatted) + wxT("\""), false);
+ msg.Replace(wxT("%y"), wxString(wxT("\"")) + zToWx(inputFile) + wxT("\""), false);
+ throw FileError(msg);
}
+
+ if (!shadowVol.get() || shadowVol->getRealVolume() != volumeNameFormatted)
+ shadowVol.reset(new ShadowVolume(volumeNameFormatted)); //throw (FileError)
+
//return filename alias on shadow copy volume
- return shadowVolumeLast + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
+ return shadowVol->getShadowVolume() + Zstring(inputFile.c_str() + pos + volumeNameFormatted.length());
}
-
diff --git a/shared/shadow.h b/shared/shadow.h
index ca373e40..60d30bbd 100644
--- a/shared/shadow.h
+++ b/shared/shadow.h
@@ -12,15 +12,24 @@ use in windows build only!
#endif
#include "zstring.h"
-#include "fileError.h"
+#include "file_error.h"
+#include <memory>
-namespace FreeFileSync
+namespace shadow
{
+struct WaitingForShadow
+{
+ virtual ~WaitingForShadow() {}
+ virtual void requestUiRefresh() = 0; //allowed to throw exceptions
+ virtual void updateStatusText(const Zstring& text) = 0;
+};
+
+
class ShadowCopy //buffer access to Windows Volume Shadow Copy Service
{
public:
- ShadowCopy();
+ ShadowCopy(WaitingForShadow* callback);
~ShadowCopy();
Zstring makeShadowCopy(const Zstring& inputFile); //throw(FileError); returns filename on shadow copy
@@ -29,9 +38,10 @@ private:
ShadowCopy(const ShadowCopy&);
ShadowCopy& operator=(const ShadowCopy&);
- Zstring realVolumeLast; //buffer last volume name
- Zstring shadowVolumeLast; //buffer last created shadow volume
- void* backupHandle;
+ WaitingForShadow* callback_;
+
+ class ShadowVolume;
+ std::auto_ptr<ShadowVolume> shadowVol;
};
}
diff --git a/shared/signal_processing.h b/shared/signal_processing.h
new file mode 100644
index 00000000..857d0b12
--- /dev/null
+++ b/shared/signal_processing.h
@@ -0,0 +1,166 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// **************************************************************************
+//
+#include <algorithm>
+#include <limits>
+#include <numeric>
+
+
+namespace util
+{
+template <class T>
+T abs(T value);
+
+int round(double d); //little rounding function
+
+template <class T>
+bool isNull(T number);
+
+//----------------------------------------------------------------------------------
+// smoothen data ranges through a window around each data point |
+//----------------------------------------------------------------------------------
+template <class InputIterator, class OutputIterator>
+void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize); //default implementation: averaging
+
+template <class InputIterator, class OutputIterator, class DataProcessor>
+void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize, DataProcessor proc);
+/*
+DataProcessor is an abstraction for data evaluation. A valid implementation needs to support three properties:
+- add data entry at window front: operator+=(ValueType value)
+- remove data entry at window back: operator-=(ValueType value)
+- evaluate smoothed middle value: ValueType operator()(size_t windowSize)
+*/
+//----------------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//################# inline implementation #########################
+template <class T>
+inline
+T abs(T value)
+{
+ return value < 0 ? -value : value;
+}
+
+
+template <class T>
+inline
+bool isNull(T value)
+{
+ return abs(number) <= std::numeric_limits<T>::epsilon(); //epsilon == 0 for integer types, therefore less-equal(!)
+}
+
+
+inline
+int round(double d)
+{
+ return static_cast<int>(d < 0 ? d - .5 : d + .5);
+}
+
+
+template <class InputIterator, class OutputIterator, class DataProcessor>
+inline
+void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize, DataProcessor proc)
+{
+ windowSize = std::min(windowSize, static_cast<size_t>(last - first)); //std::distance() not used to enforce random access iterator requirement
+
+ if (windowSize <= 1)
+ {
+ std::copy(first, last, result);
+ return;
+ }
+
+ const size_t firstHalf = windowSize / 2;
+ const size_t secondHalf = windowSize - firstHalf;
+
+ //preparation
+ for (InputIterator i = first; i != first + secondHalf; ++i)
+ proc += *i;
+
+ //beginning
+ for (InputIterator i = first; i != first + firstHalf; ++i)
+ {
+ *result++ = proc(i - first + secondHalf);
+ proc += *(i + secondHalf);
+ }
+
+ //main
+ for (InputIterator i = first + firstHalf; i != last - secondHalf; ++i)
+ {
+ *result++ = proc(windowSize);
+ proc += *(i + secondHalf);
+ proc -= *(i - firstHalf);
+ }
+
+ //ending
+ for (InputIterator i = last - secondHalf; i != last; ++i)
+ {
+ *result++ = proc(windowSize - (i - last + secondHalf));
+ proc -= *(i - firstHalf);
+ }
+}
+
+
+template <class ValueType>
+class ProcessorAverage
+{
+public:
+ ProcessorAverage() : valueAcc() {}
+
+ //add front data entry
+ ProcessorAverage& operator+=(ValueType value)
+ {
+ valueAcc += value;
+ return *this;
+ }
+
+ //remove rear data entry
+ ProcessorAverage& operator-=(ValueType value)
+ {
+ valueAcc -= value;
+ return *this;
+ }
+
+ //evaluate smoothed value
+ ValueType operator()(size_t windowSize) const
+ {
+ return valueAcc / windowSize;
+ }
+
+private:
+ ValueType valueAcc; //accumulated values
+};
+
+
+
+template <class InputIterator, class OutputIterator>
+inline
+void smoothen(InputIterator first, InputIterator last, OutputIterator result, size_t windowSize)
+{
+ typedef typename std::iterator_traits<InputIterator>::value_type ValueType;
+ smoothen(first, last, result, windowSize, ProcessorAverage<ValueType>());
+}
+
+} \ No newline at end of file
diff --git a/shared/standardPaths.cpp b/shared/standard_paths.cpp
index e442c865..2bebe056 100644
--- a/shared/standardPaths.cpp
+++ b/shared/standard_paths.cpp
@@ -4,33 +4,33 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "standardPaths.h"
+#include "standard_paths.h"
#include <wx/stdpaths.h>
#include <wx/filename.h>
-#include "systemConstants.h"
-#include "stringConv.h"
+#include "system_constants.h"
+#include "string_conv.h"
-using namespace FreeFileSync;
+using namespace ffs3;
-bool FreeFileSync::isPortableVersion()
+bool ffs3::isPortableVersion()
{
#ifdef FFS_WIN
- static const bool isPortable = !wxFileExists(FreeFileSync::getBinaryDir() + wxT("uninstall.exe")); //this check is a bit lame...
+ static const bool isPortable = !wxFileExists(ffs3::getBinaryDir() + wxT("uninstall.exe")); //this check is a bit lame...
#elif defined FFS_LINUX
- static const bool isPortable = !FreeFileSync::getBinaryDir().EndsWith(wxT("/bin/")); //this check is a bit lame...
+ static const bool isPortable = !ffs3::getBinaryDir().EndsWith(wxT("/bin/")); //this check is a bit lame...
#endif
return isPortable;
}
-const wxString& FreeFileSync::getBinaryDir()
+const wxString& ffs3::getBinaryDir()
{
- static wxString instance = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() + zToWx(globalFunctions::FILE_NAME_SEPARATOR);
+ static wxString instance = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath() + zToWx(common::FILE_NAME_SEPARATOR);
return instance;
}
-const wxString& FreeFileSync::getResourceDir()
+const wxString& ffs3::getResourceDir()
{
#ifdef FFS_WIN
return getBinaryDir();
@@ -48,8 +48,8 @@ const wxString& FreeFileSync::getResourceDir()
{
resourceDir = wxStandardPathsBase::Get().GetResourcesDir();
- if (!resourceDir.EndsWith(zToWx(globalFunctions::FILE_NAME_SEPARATOR)))
- resourceDir += zToWx(globalFunctions::FILE_NAME_SEPARATOR);
+ if (!resourceDir.EndsWith(zToWx(common::FILE_NAME_SEPARATOR)))
+ resourceDir += zToWx(common::FILE_NAME_SEPARATOR);
}
}
@@ -58,7 +58,7 @@ const wxString& FreeFileSync::getResourceDir()
}
-const wxString& FreeFileSync::getConfigDir()
+const wxString& ffs3::getConfigDir()
{
static wxString userDirectory;
@@ -68,7 +68,7 @@ const wxString& FreeFileSync::getConfigDir()
isInitalized = true;
if (isPortableVersion())
- //userDirectory = wxString(wxT(".")) + zToWx(globalFunctions::FILE_NAME_SEPARATOR); //use current working directory
+ //userDirectory = wxString(wxT(".")) + zToWx(common::FILE_NAME_SEPARATOR); //use current working directory
userDirectory = getBinaryDir(); //avoid surprises with GlobalSettings.xml being newly created in each working directory
else //use OS' standard paths
{
@@ -77,8 +77,8 @@ const wxString& FreeFileSync::getConfigDir()
if (!wxDirExists(userDirectory))
::wxMkdir(userDirectory); //only top directory needs to be created: no recursion necessary
- if (!userDirectory.EndsWith(zToWx(globalFunctions::FILE_NAME_SEPARATOR)))
- userDirectory += zToWx(globalFunctions::FILE_NAME_SEPARATOR);
+ if (!userDirectory.EndsWith(zToWx(common::FILE_NAME_SEPARATOR)))
+ userDirectory += zToWx(common::FILE_NAME_SEPARATOR);
}
}
diff --git a/shared/standardPaths.h b/shared/standard_paths.h
index 0ebeebd2..956cf81c 100644
--- a/shared/standardPaths.h
+++ b/shared/standard_paths.h
@@ -10,7 +10,7 @@
#include <wx/string.h>
-namespace FreeFileSync
+namespace ffs3
{
//------------------------------------------------------------------------------
//global program directories
diff --git a/shared/staticAssert.h b/shared/staticAssert.h
deleted file mode 100644
index 14f52221..00000000
--- a/shared/staticAssert.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// **************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
-// **************************************************************************
-//
-#ifndef STATICASSERT_H_INCLUDED
-#define STATICASSERT_H_INCLUDED
-
-//Reference: Compile-Time Assertions, C/C++ Users Journal November, 2004 (http://pera-software.com/articles/compile-time-assertions.pdf)
-
-#ifdef NDEBUG
-//If not debugging, assert does nothing.
-#define assert_static(x) ((void)0)
-
-#else /* debugging enabled */
-
-#define assert_static(e) \
-do { \
-enum { assert_static__ = 1/(static_cast<int>(e)) }; \
-} while (0)
-#endif
-
-#endif // STATICASSERT_H_INCLUDED
diff --git a/shared/stringConv.h b/shared/string_conv.h
index 454a65f7..bbaef713 100644
--- a/shared/stringConv.h
+++ b/shared/string_conv.h
@@ -10,7 +10,7 @@
#include <wx/string.h>
#include "zstring.h"
-namespace FreeFileSync
+namespace ffs3
{
//conversion from Zstring to wxString
wxString zToWx(const Zstring& str);
diff --git a/shared/systemConstants.h b/shared/system_constants.h
index d686ac50..6877f5c7 100644
--- a/shared/systemConstants.h
+++ b/shared/system_constants.h
@@ -10,7 +10,7 @@
#include "zstring.h"
#include <wx/string.h>
-namespace globalFunctions
+namespace common
{
//------------------------------------------------
// GLOBALS
diff --git a/shared/systemFunctions.cpp b/shared/system_func.cpp
index 41ce9377..71335d71 100644
--- a/shared/systemFunctions.cpp
+++ b/shared/system_func.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "systemFunctions.h"
+#include "system_func.h"
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
@@ -17,7 +17,7 @@
#ifdef FFS_WIN
-wxString FreeFileSync::getLastErrorFormatted(unsigned long lastError) //try to get additional Windows error information
+wxString ffs3::getLastErrorFormatted(unsigned long lastError) //try to get additional Windows error information
{
//determine error code if none was specified
if (lastError == 0)
@@ -28,11 +28,13 @@ wxString FreeFileSync::getLastErrorFormatted(unsigned long lastError) //try to g
WCHAR buffer[1001];
if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0, lastError, 0, buffer, 1001, NULL) != 0)
output += wxString(wxT(": ")) + buffer;
+
+ ::SetLastError(lastError); //restore last error
return output;
}
#elif defined FFS_LINUX
-wxString FreeFileSync::getLastErrorFormatted(int lastError) //try to get additional Linux error information
+wxString ffs3::getLastErrorFormatted(int lastError) //try to get additional Linux error information
{
//determine error code if none was specified
if (lastError == 0)
@@ -40,6 +42,8 @@ wxString FreeFileSync::getLastErrorFormatted(int lastError) //try to get additio
wxString output = wxString(wxT("Linux Error Code ")) + wxString::Format(wxT("%i"), lastError);
output += wxString(wxT(": ")) + wxString::FromUTF8(::strerror(lastError));
+
+ errno = lastError; //restore errno
return output;
}
#endif
diff --git a/shared/systemFunctions.h b/shared/system_func.h
index d197ceb6..b15f4c0c 100644
--- a/shared/systemFunctions.h
+++ b/shared/system_func.h
@@ -10,7 +10,7 @@
#include <wx/string.h>
-namespace FreeFileSync
+namespace ffs3
{
//evaluate GetLastError()/errno and assemble specific error message
#ifdef FFS_WIN
diff --git a/shared/taskbar.cpp b/shared/taskbar.cpp
index 47681958..61a1841b 100644
--- a/shared/taskbar.cpp
+++ b/shared/taskbar.cpp
@@ -6,12 +6,12 @@
//
#include "taskbar.h"
#include "Taskbar_Seven/taskbar.h"
-#include "dllLoader.h"
-#include "buildInfo.h"
-#include "staticAssert.h"
+#include "dll_loader.h"
+#include "build_info.h"
+#include "assert_static.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
-using namespace Utility;
+using namespace util;
namespace
@@ -33,14 +33,14 @@ bool windows7TaskbarAvailable()
}
-const wxString& getTaskBarDllName()
+const std::wstring& getTaskBarDllName()
{
- static const wxString filename(
- Utility::is64BitBuild ?
- wxT("Taskbar7_x64.dll") :
- wxT("Taskbar7_Win32.dll"));
+ assert_static(util::is32BitBuild || util::is64BitBuild);
- assert_static(Utility::is32BitBuild || Utility::is64BitBuild);
+ static const std::wstring filename(
+ util::is64BitBuild ?
+ L"Taskbar7_x64.dll" :
+ L"Taskbar7_Win32.dll");
return filename;
}
@@ -71,10 +71,10 @@ TaskbarProgress::TaskbarProgress(const wxTopLevelWindow& window) : pimpl_(new Pi
if (!windows7TaskbarAvailable())
throw TaskbarNotAvailable();
- pimpl_->init_ = Utility::loadDllFunction<TaskbarSeven::initFct>( getTaskBarDllName().c_str(), TaskbarSeven::initFctName);
- pimpl_->release_ = Utility::loadDllFunction<TaskbarSeven::releaseFct>( getTaskBarDllName().c_str(), TaskbarSeven::releaseFctName);
- pimpl_->setProgress_ = Utility::loadDllFunction<TaskbarSeven::setProgressFct>(getTaskBarDllName().c_str(), TaskbarSeven::setProgressFctName);
- pimpl_->setStatus_ = Utility::loadDllFunction<TaskbarSeven::setStatusFct>( getTaskBarDllName().c_str(), TaskbarSeven::setStatusFctName);
+ pimpl_->init_ = util::loadDllFunction<TaskbarSeven::initFct>( getTaskBarDllName(), TaskbarSeven::initFctName);
+ pimpl_->release_ = util::loadDllFunction<TaskbarSeven::releaseFct>( getTaskBarDllName(), TaskbarSeven::releaseFctName);
+ pimpl_->setProgress_ = util::loadDllFunction<TaskbarSeven::setProgressFct>(getTaskBarDllName(), TaskbarSeven::setProgressFctName);
+ pimpl_->setStatus_ = util::loadDllFunction<TaskbarSeven::setStatusFct>( getTaskBarDllName(), TaskbarSeven::setStatusFctName);
if ( !pimpl_->init_ ||
!pimpl_->release_ ||
diff --git a/shared/taskbar.h b/shared/taskbar.h
index 278aca0e..02d7324d 100644
--- a/shared/taskbar.h
+++ b/shared/taskbar.h
@@ -15,7 +15,7 @@ use in windows build only!
#include <memory>
-namespace Utility
+namespace util
{
class TaskbarNotAvailable {};
diff --git a/shared/toggleButton.cpp b/shared/toggle_button.cpp
index 6a35a85d..2da64ee4 100644
--- a/shared/toggleButton.cpp
+++ b/shared/toggle_button.cpp
@@ -4,7 +4,7 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "toggleButton.h"
+#include "toggle_button.h"
void ToggleButton::init(const wxBitmap& activeBmp,
const wxString& activeTooltip,
diff --git a/shared/toggleButton.h b/shared/toggle_button.h
index a67d5fff..a67d5fff 100644
--- a/shared/toggleButton.h
+++ b/shared/toggle_button.h
diff --git a/shared/util.cpp b/shared/util.cpp
index f3013e66..9e0cb9d3 100644
--- a/shared/util.cpp
+++ b/shared/util.cpp
@@ -10,30 +10,30 @@
#include <wx/combobox.h>
#include <wx/filepicker.h>
#include "localization.h"
-#include "fileHandling.h"
-#include "stringConv.h"
+#include "file_handling.h"
+#include "string_conv.h"
#include <stdexcept>
-#include "systemFunctions.h"
-#include "checkExist.h"
+#include "system_func.h"
+#include "check_exist.h"
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
#endif
-wxString FreeFileSync::formatFilesizeToShortString(const wxLongLong& filesize)
+wxString ffs3::formatFilesizeToShortString(const wxLongLong& filesize)
{
- return FreeFileSync::formatFilesizeToShortString(filesize.ToDouble());
+ return ffs3::formatFilesizeToShortString(filesize.ToDouble());
}
-wxString FreeFileSync::formatFilesizeToShortString(const wxULongLong& filesize)
+wxString ffs3::formatFilesizeToShortString(const wxULongLong& filesize)
{
- return FreeFileSync::formatFilesizeToShortString(filesize.ToDouble());
+ return ffs3::formatFilesizeToShortString(filesize.ToDouble());
}
-wxString FreeFileSync::formatFilesizeToShortString(double filesize)
+wxString ffs3::formatFilesizeToShortString(double filesize)
{
if (filesize < 0)
return _("Error");
@@ -65,7 +65,7 @@ wxString FreeFileSync::formatFilesizeToShortString(double filesize)
}
}
//print just three significant digits: 0,01 | 0,11 | 1,11 | 11,1 | 111
- const size_t leadDigitCount = globalFunctions::getDigitCount(static_cast<size_t>(filesize)); //number of digits before decimal point
+ const size_t leadDigitCount = common::getDigitCount(static_cast<size_t>(filesize)); //number of digits before decimal point
if (leadDigitCount == 0 || leadDigitCount > 3)
return _("Error");
@@ -73,14 +73,14 @@ wxString FreeFileSync::formatFilesizeToShortString(double filesize)
}
else
{
- output.Replace(wxT("%x"), globalFunctions::numberToString(static_cast<int>(filesize))); //no decimal places in case of bytes
+ output.Replace(wxT("%x"), common::numberToString(static_cast<int>(filesize))); //no decimal places in case of bytes
}
return output;
}
-wxString FreeFileSync::formatPercentage(const wxLongLong& dividend, const wxLongLong& divisor)
+wxString ffs3::formatPercentage(const wxLongLong& dividend, const wxLongLong& divisor)
{
const double ratio = divisor != 0 ? dividend.ToDouble() * 100 / divisor.ToDouble() : 0;
wxString output = _("%x%");
@@ -89,11 +89,11 @@ wxString FreeFileSync::formatPercentage(const wxLongLong& dividend, const wxLong
}
-wxString FreeFileSync_Impl::includeNumberSeparator(const wxString& number)
+wxString ffs_Impl::includeNumberSeparator(const wxString& number)
{
wxString output(number);
for (size_t i = output.size(); i > 3; i -= 3)
- output.insert(i - 3, FreeFileSync::getThousandsSeparator());
+ output.insert(i - 3, ffs3::getThousandsSeparator());
return output;
}
@@ -102,30 +102,30 @@ wxString FreeFileSync_Impl::includeNumberSeparator(const wxString& number)
template <class T>
void setDirectoryNameImpl(const wxString& dirname, T* txtCtrl, wxDirPickerCtrl* dirPicker)
{
- using namespace FreeFileSync;
+ using namespace ffs3;
txtCtrl->SetValue(dirname);
- const Zstring dirFormatted = FreeFileSync::getFormattedDirectoryName(wxToZ(dirname));
+ const Zstring dirFormatted = ffs3::getFormattedDirectoryName(wxToZ(dirname));
- if (Utility::dirExists(dirFormatted, 200) == Utility::EXISTING_TRUE) //potentially slow network access: wait 200ms at most
+ if (util::dirExists(dirFormatted, 200) == util::EXISTING_TRUE) //potentially slow network access: wait 200ms at most
dirPicker->SetPath(zToWx(dirFormatted));
}
-void FreeFileSync::setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker)
+void ffs3::setDirectoryName(const wxString& dirname, wxTextCtrl* txtCtrl, wxDirPickerCtrl* dirPicker)
{
setDirectoryNameImpl(dirname, txtCtrl, dirPicker);
}
-void FreeFileSync::setDirectoryName(const wxString& dirname, wxComboBox* txtCtrl, wxDirPickerCtrl* dirPicker)
+void ffs3::setDirectoryName(const wxString& dirname, wxComboBox* txtCtrl, wxDirPickerCtrl* dirPicker)
{
txtCtrl->SetSelection(wxNOT_FOUND);
setDirectoryNameImpl(dirname, txtCtrl, dirPicker);
}
-void FreeFileSync::scrollToBottom(wxScrolledWindow* scrWindow)
+void ffs3::scrollToBottom(wxScrolledWindow* scrWindow)
{
int height = 0;
scrWindow->GetClientSize(NULL, &height);
@@ -172,7 +172,7 @@ void writeFourDigitNumber(size_t number, wxString& string)
}
}
-wxString FreeFileSync::utcTimeToLocalString(const wxLongLong& utcTime)
+wxString ffs3::utcTimeToLocalString(const wxLongLong& utcTime)
{
#ifdef FFS_WIN
//convert ansi C time to FILETIME
diff --git a/shared/util.h b/shared/util.h
index 25048132..5023c00b 100644
--- a/shared/util.h
+++ b/shared/util.h
@@ -10,7 +10,7 @@
#include "../shared/zstring.h"
#include <wx/string.h>
#include <wx/longlong.h>
-#include "../shared/globalFunctions.h"
+#include "../shared/global_func.h"
class wxComboBox;
class wxTextCtrl;
@@ -18,7 +18,7 @@ class wxDirPickerCtrl;
class wxScrolledWindow;
-namespace FreeFileSync
+namespace ffs3
{
wxString formatFilesizeToShortString(const wxLongLong& filesize);
wxString formatFilesizeToShortString(const wxULongLong& filesize);
@@ -64,20 +64,20 @@ wxString utcTimeToLocalString(const wxLongLong& utcTime); //throw std::runtime_e
//--------------- inline impelementation -------------------------------------------
//helper function! not to be used directly
-namespace FreeFileSync_Impl
+namespace ffs_Impl
{
wxString includeNumberSeparator(const wxString& number);
}
-namespace FreeFileSync
+namespace ffs3
{
//wxULongLongNative doesn't support operator<<(std::ostream&, wxULongLongNative)
template <>
inline
wxString numberToStringSep(wxULongLongNative number)
{
- return FreeFileSync_Impl::includeNumberSeparator(number.ToString());
+ return ffs_Impl::includeNumberSeparator(number.ToString());
}
@@ -85,7 +85,7 @@ template <class NumberType>
inline
wxString numberToStringSep(NumberType number)
{
- return FreeFileSync_Impl::includeNumberSeparator(globalFunctions::numberToString(number));
+ return ffs_Impl::includeNumberSeparator(common::numberToString(number));
}
}
diff --git a/shared/xmlBase.cpp b/shared/xml_base.cpp
index 42e33016..3213786d 100644
--- a/shared/xmlBase.cpp
+++ b/shared/xml_base.cpp
@@ -4,15 +4,15 @@
// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
-#include "xmlBase.h"
+#include "xml_base.h"
#include <wx/intl.h>
-#include "fileIO.h"
-#include "stringConv.h"
-#include "systemConstants.h"
+#include "file_io.h"
+#include "string_conv.h"
+#include "system_constants.h"
#include <boost/scoped_array.hpp>
-#include "fileHandling.h"
+#include "file_handling.h"
-using namespace FreeFileSync;
+using namespace ffs3;
std::string getTypeName(xmlAccess::XmlType type)
@@ -79,7 +79,7 @@ void loadRawXmlDocument(const wxString& filename, TiXmlDocument& document) //thr
}
catch (const FileError& error) //more detailed error messages than with wxWidgets
{
- throw XmlError(error.show());
+ throw XmlError(error.msg());
}
//convert (0xD, 0xA) and (0xD) to (0xA): just like in TiXmlDocument::LoadFile(); not sure if actually needed
@@ -163,7 +163,7 @@ bool saveNecessary(const Zstring& filename, const std::string& dataToWrite) //th
{
try
{
- if (FreeFileSync::getFilesize(filename) != static_cast<unsigned long>(dataToWrite.size())) //throw FileError();
+ if (ffs3::getFilesize(filename) != static_cast<unsigned long>(dataToWrite.size())) //throw FileError();
return true;
boost::scoped_array<char> inputBuffer(new char[dataToWrite.size() + 1]); //+ 1 in order to test for end of file!
@@ -190,7 +190,7 @@ void xmlAccess::saveXmlDocument(const wxString& filename, const TiXmlDocument& d
//convert XML into continuous byte sequence
TiXmlPrinter printer;
- printer.SetLineBreak(wxString(globalFunctions::LINE_BREAK).ToUTF8());
+ printer.SetLineBreak(wxString(common::LINE_BREAK).ToUTF8());
document.Accept(&printer);
const std::string buffer = printer.Str();
@@ -203,7 +203,7 @@ void xmlAccess::saveXmlDocument(const wxString& filename, const TiXmlDocument& d
}
catch (const FileError& error) //more detailed error messages than with wxWidgets
{
- throw XmlError(error.show());
+ throw XmlError(error.msg());
}
}
}
@@ -384,7 +384,7 @@ void XmlParser::logError(const std::string& nodeName)
}
-bool XmlParser::errorsOccured() const
+bool XmlParser::errorsOccurred() const
{
return !failedNodes.empty();
}
diff --git a/shared/xmlBase.h b/shared/xml_base.h
index 8f7c4aa7..6d342b48 100644
--- a/shared/xmlBase.h
+++ b/shared/xml_base.h
@@ -8,11 +8,11 @@
#define XMLBASE_H_INCLUDED
#include "tinyxml/tinyxml.h"
-#include "globalFunctions.h"
+#include "global_func.h"
#include <string>
#include <vector>
#include <wx/string.h>
-#include "xmlError.h"
+#include "xml_error.h"
namespace xmlAccess
@@ -72,7 +72,7 @@ public:
XmlParser(const TiXmlElement* rootElement) : root(rootElement) {}
void logError(const std::string& nodeName);
- bool errorsOccured() const;
+ bool errorsOccurred() const;
const wxString getErrorMessageFormatted() const;
protected:
@@ -172,7 +172,7 @@ bool xmlAccess::readXmlElement(const std::string& name, const TiXmlElement* pare
if (!readXmlElement(name, parent, temp))
return false;
- output = globalFunctions::stringToNumber<T>(temp);
+ output = common::stringToNumber<T>(temp);
return true;
}
@@ -181,7 +181,7 @@ template <class T>
inline
void xmlAccess::addXmlElement(const std::string& name, T value, TiXmlElement* parent)
{
- addXmlElement(name, globalFunctions::numberToString<std::string::value_type>(value), parent);
+ addXmlElement(name, common::numberToString<std::string::value_type>(value), parent);
}
@@ -192,7 +192,7 @@ bool xmlAccess::readXmlAttribute(const std::string& name, const TiXmlElement* no
std::string dummy;
if (readXmlAttribute(name, node, dummy))
{
- output = globalFunctions::stringToNumber<T>(dummy);
+ output = common::stringToNumber<T>(dummy);
return true;
}
else
@@ -204,7 +204,7 @@ template <class T>
inline
void xmlAccess::addXmlAttribute(const std::string& name, T value, TiXmlElement* node)
{
- addXmlAttribute(name, globalFunctions::numberToString<std::string::value_type>(value), node);
+ addXmlAttribute(name, common::numberToString<std::string::value_type>(value), node);
}
#endif // XMLBASE_H_INCLUDED
diff --git a/shared/xmlError.h b/shared/xml_error.h
index f5f02c6a..bd5153cb 100644
--- a/shared/xmlError.h
+++ b/shared/xml_error.h
@@ -24,7 +24,7 @@ public:
XmlError(const wxString& message, Severity sev = FATAL) : errorMessage(message), m_severity(sev) {}
- const wxString& show() const
+ const wxString& msg() const
{
return errorMessage;
}
diff --git a/shared/zstring.cpp b/shared/zstring.cpp
index 6bd0e824..39f1898d 100644
--- a/shared/zstring.cpp
+++ b/shared/zstring.cpp
@@ -9,16 +9,16 @@
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include "dllLoader.h"
+#include "dll_loader.h"
#include <boost/scoped_array.hpp>
#endif //FFS_WIN
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
#include <wx/string.h>
#endif
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
AllocationCount::~AllocationCount()
{
if (activeStrings.size() > 0)
@@ -50,7 +50,7 @@ AllocationCount& AllocationCount::getInstance()
static AllocationCount global;
return global;
}
-#endif
+#endif //NDEBUG
#ifdef FFS_WIN
namespace
@@ -91,7 +91,7 @@ int compareFilenamesWin32(const wchar_t* a, const wchar_t* b, size_t sizeA, size
LPCWSTR lpString2,
int cchCount2,
BOOL bIgnoreCase);
- static const CompareStringOrdinalFunc ordinalCompare = Utility::loadDllFunction<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal");
+ static const CompareStringOrdinalFunc ordinalCompare = util::loadDllFunction<CompareStringOrdinalFunc>(L"kernel32.dll", "CompareStringOrdinal");
if (ordinalCompare != NULL) //this additional test has no noticeable performance impact
{
@@ -173,22 +173,32 @@ int compareFilenamesWin32(const wchar_t* a, const wchar_t* b, size_t sizeA, size
#endif
-int Zstring::cmpFileName(const Zstring& other) const
+int cmpFileName(const Zstring& lhs, const Zstring& rhs)
+{
+#ifdef FFS_WIN
+ return ::compareFilenamesWin32(lhs.c_str(), rhs.c_str(), lhs.length(), rhs.length()); //way faster than wxString::CmpNoCase()
+#elif defined FFS_LINUX
+ return ::strcmp(lhs.c_str(), rhs.c_str());
+#endif
+}
+
+
+int cmpFileName(const Zstring& lhs, const DefaultChar* rhs)
{
#ifdef FFS_WIN
- return ::compareFilenamesWin32(c_str(), other.c_str(), length(), other.length()); //way faster than wxString::CmpNoCase()
+ return ::compareFilenamesWin32(lhs.c_str(), rhs, lhs.length(), ::wcslen(rhs)); //way faster than wxString::CmpNoCase()
#elif defined FFS_LINUX
- return defaultCompare(c_str(), other.c_str());
+return ::strcmp(lhs.c_str(), rhs);
#endif
}
-int Zstring::cmpFileName(const DefaultChar* other) const
+int cmpFileName(const DefaultChar* lhs, const DefaultChar* rhs)
{
#ifdef FFS_WIN
- return ::compareFilenamesWin32(c_str(), other, length(), ::wcslen(other)); //way faster than wxString::CmpNoCase()
+ return ::compareFilenamesWin32(lhs, rhs, ::wcslen(lhs), ::wcslen(rhs)); //way faster than wxString::CmpNoCase()
#elif defined FFS_LINUX
- return defaultCompare(c_str(), other);
+ return ::strcmp(lhs, rhs);
#endif
}
@@ -569,7 +579,7 @@ void Zstring::reserve(size_t capacityNeeded) //make unshared and check capacity
//try to resize the current string (allocate anew if necessary)
const size_t newCapacity = getCapacityToAllocate(capacityNeeded);
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
AllocationCount::getInstance().dec(c_str()); //test Zstring for memory leaks
#endif
@@ -577,7 +587,7 @@ void Zstring::reserve(size_t capacityNeeded) //make unshared and check capacity
if (descr == NULL)
throw std::bad_alloc();
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
AllocationCount::getInstance().inc(c_str()); //test Zstring for memory leaks
#endif
diff --git a/shared/zstring.h b/shared/zstring.h
index d59126df..7b993fd0 100644
--- a/shared/zstring.h
+++ b/shared/zstring.h
@@ -13,8 +13,9 @@
#include <vector>
#include <sstream>
#include <algorithm> //specialize std::swap
+#include <functional>
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
#include <set>
#include <wx/thread.h>
#endif
@@ -40,10 +41,6 @@ public:
operator const DefaultChar*() const; //implicit conversion to C string
- //Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES
- int cmpFileName(const Zstring& other) const;
- int cmpFileName(const DefaultChar* other) const;
-
//wxWidgets-like functions
bool StartsWith(const DefaultChar* begin) const;
bool StartsWith(DefaultChar begin) const;
@@ -146,6 +143,17 @@ const Zstring operator+(const Zstring& lhs, DefaultChar rhs);
template <class T>
Zstring numberToZstring(const T& number); //convert number to Zstring
+//Compare filenames: Windows does NOT distinguish between upper/lower-case, while Linux DOES
+int cmpFileName(const Zstring& lhs, const Zstring& rhs);
+int cmpFileName(const Zstring& lhs, const DefaultChar* rhs);
+int cmpFileName(const DefaultChar* lhs, const Zstring& rhs);
+int cmpFileName(const DefaultChar* lhs, const DefaultChar* rhs);
+
+struct LessFilename : public std::binary_function<Zstring, Zstring, bool>//case-insensitive on Windows, case-sensitive on Linux
+{
+ bool operator()(const Zstring& a, const Zstring& b) const;
+};
+
namespace std
{
template<>
@@ -174,6 +182,15 @@ void swap(Zstring& rhs, Zstring& lhs)
+
+
+
+
+
+
+
+
+
//#######################################################################################
//begin of implementation
@@ -255,8 +272,7 @@ const DefaultChar* Zstring::defaultStrFind(const DefaultChar* str1, const Defaul
}
//--------------------------------------------------------------------------------------------------
-
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
class AllocationCount //small test for memory leaks in Zstring
{
public:
@@ -282,7 +298,7 @@ private:
wxCriticalSection lockActStrings;
std::set<const DefaultChar*> activeStrings;
};
-#endif
+#endif //NDEBUG
inline
@@ -307,7 +323,7 @@ Zstring::StringDescriptor* Zstring::allocate(const size_t newLength)
newDescr->length = newLength;
newDescr->capacity = newCapacity;
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
AllocationCount::getInstance().inc(reinterpret_cast<DefaultChar*>(newDescr + 1)); //test Zstring for memory leaks
#endif
return newDescr;
@@ -383,7 +399,7 @@ void Zstring::decRef()
assert(descr && descr->refCount >= 1); //descr points to the begin of the allocated memory block
if (--descr->refCount == 0)
{
-#ifdef __WXDEBUG__
+#ifndef NDEBUG
AllocationCount::getInstance().dec(c_str()); //test Zstring for memory leaks
#endif
::free(descr); //beginning of whole memory block
@@ -765,4 +781,23 @@ Zstring numberToZstring(const T& number) //convert number to string the C++ way
return Zstring(ss.str().c_str());
}
+
+inline
+int cmpFileName(const DefaultChar* lhs, const Zstring& rhs)
+{
+ return cmpFileName(rhs, lhs);
+}
+
+
+inline
+bool LessFilename::operator()(const Zstring& a, const Zstring& b) const
+{
+// //quick check based on string length
+// const size_t aLength = a.data.shortName.length();
+// const size_t bLength = b.data.shortName.length();
+// if (aLength != bLength)
+// return aLength < bLength;
+ return cmpFileName(a, b) < 0;
+}
+
#endif // ZSTRING_H_INCLUDED
bgstack15