summaryrefslogtreecommitdiff
path: root/shared/fileHandling.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:03:20 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:03:20 +0200
commit528635604eea1d8c679a3d038e2f00030ef72444 (patch)
tree9c3cbec29aa7d3e209939662e040b9342c9e7400 /shared/fileHandling.cpp
parent3.1 (diff)
downloadFreeFileSync-528635604eea1d8c679a3d038e2f00030ef72444.tar.gz
FreeFileSync-528635604eea1d8c679a3d038e2f00030ef72444.tar.bz2
FreeFileSync-528635604eea1d8c679a3d038e2f00030ef72444.zip
3.2
Diffstat (limited to 'shared/fileHandling.cpp')
-rw-r--r--shared/fileHandling.cpp172
1 files changed, 113 insertions, 59 deletions
diff --git a/shared/fileHandling.cpp b/shared/fileHandling.cpp
index 495e3d49..4b9901e0 100644
--- a/shared/fileHandling.cpp
+++ b/shared/fileHandling.cpp
@@ -11,8 +11,10 @@
#include <wx/log.h>
#include <wx/datetime.h>
#include "stringConv.h"
+#include <wx/utils.h>
#ifdef FFS_WIN
+#include "dllLoader.h"
#include <wx/msw/wrapwin.h> //includes "windows.h"
#include "shadow.h"
@@ -30,10 +32,70 @@
using FreeFileSync::FileError;
+bool replaceMacro(wxString& macro) //macro without %-characters, return true if replaced successfully
+{
+ if (macro.IsEmpty())
+ return false;
+
+ //there are equally named environment variables %TIME%, %DATE% existing, so replace these first!
+ if (macro.CmpNoCase(wxT("time")) == 0)
+ {
+ macro = wxDateTime::Now().FormatISOTime();
+ macro.Replace(wxT(":"), wxT("-"));
+ return true;
+ }
+
+ if (macro.CmpNoCase(wxT("date")) == 0)
+ {
+ macro = wxDateTime::Now().FormatISODate();
+ return true;
+ }
+
+ //try to apply environment variables
+ wxString envValue;
+ if (wxGetEnv(macro, &envValue))
+ {
+ macro = envValue;
+ return true;
+ }
+
+ return false;
+}
+
+
+void expandMacros(wxString& text)
+{
+ const wxChar SEPARATOR = '%';
+
+ if (text.Find(SEPARATOR) != wxNOT_FOUND)
+ {
+ wxString prefix = text.BeforeFirst(SEPARATOR);
+ wxString postfix = text.AfterFirst(SEPARATOR);
+ if (postfix.Find(SEPARATOR) != wxNOT_FOUND)
+ {
+ wxString potentialMacro = postfix.BeforeFirst(SEPARATOR);
+ wxString rest = postfix.AfterFirst(SEPARATOR); //text == prefix + SEPARATOR + potentialMacro + SEPARATOR + rest
+
+ if (replaceMacro(potentialMacro))
+ {
+ expandMacros(rest);
+ text = prefix + potentialMacro + rest;
+ }
+ else
+ {
+ rest = wxString() + SEPARATOR + rest;
+ expandMacros(rest);
+ text = prefix + SEPARATOR + potentialMacro + rest;
+ }
+ }
+ }
+}
+
+
Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname)
{
//Formatting is needed since functions expect the directory to end with '\' to be able to split the relative names.
- //Also improves usability.
+ //note: don't do directory formatting with wxFileName, as it doesn't respect //?/ - prefix!
wxString dirnameTmp = zToWx(dirname);
dirnameTmp.Trim(true); //remove whitespace characters from right
@@ -46,14 +108,8 @@ Zstring FreeFileSync::getFormattedDirectoryName(const Zstring& dirname)
dirnameTmp += zToWx(globalFunctions::FILE_NAME_SEPARATOR);
//replace macros
- wxString timeNow = wxDateTime::Now().FormatISOTime();
- timeNow.Replace(wxT(":"), wxT("-"));
- dirnameTmp.Replace(wxT("%time%"), timeNow.c_str());
-
- const wxString dateToday = wxDateTime::Now().FormatISODate();
- dirnameTmp.Replace(wxT("%date%"), dateToday.c_str());
+ expandMacros(dirnameTmp);
- //don't do directory formatting with wxFileName, as it doesn't respect //?/ - prefix
return wxToZ(dirnameTmp);
}
@@ -717,57 +773,16 @@ void FreeFileSync::copyFileTimes(const Zstring& sourceDir, const Zstring& target
#ifdef FFS_WIN
-class KernelDllHandler //dynamically load windows API functions
-{
- typedef DWORD (WINAPI *GetFinalPath)(
- HANDLE hFile,
- LPTSTR lpszFilePath,
- DWORD cchFilePath,
- DWORD dwFlags);
-
-public:
- static const KernelDllHandler& getInstance() //lazy creation of KernelDllHandler
- {
- static KernelDllHandler instance;
-
- if (instance.getFinalPathNameByHandle == NULL)
- throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\""));
-
- return instance;
- }
-
- GetFinalPath getFinalPathNameByHandle;
-
-private:
- KernelDllHandler() :
- getFinalPathNameByHandle(NULL),
- hKernel(NULL)
- {
- //get a handle to the DLL module containing required functionality
- hKernel = ::LoadLibrary(wxT("kernel32.dll"));
- if (hKernel)
- getFinalPathNameByHandle = reinterpret_cast<GetFinalPath>(::GetProcAddress(hKernel, "GetFinalPathNameByHandleW")); //load unicode version!
- }
-
- ~KernelDllHandler()
- {
- if (hKernel) ::FreeLibrary(hKernel);
- }
-
- HINSTANCE hKernel;
-};
-
-
Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target path of symbolic link to a directory
{
//open handle to target of symbolic link
- HANDLE hDir = CreateFile(dirLinkName.c_str(),
- 0,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
+ HANDLE hDir = ::CreateFile(dirLinkName.c_str(),
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
if (hDir == INVALID_HANDLE_VALUE)
return Zstring();
@@ -776,7 +791,20 @@ Zstring resolveDirectorySymlink(const Zstring& dirLinkName) //get full target pa
const unsigned int BUFFER_SIZE = 10000;
TCHAR targetPath[BUFFER_SIZE];
- const DWORD rv = KernelDllHandler::getInstance().getFinalPathNameByHandle(
+
+ //dynamically load windows API function
+ typedef DWORD (WINAPI *GetFinalPathNameByHandleWFunc)(
+ HANDLE hFile,
+ LPTSTR lpszFilePath,
+ DWORD cchFilePath,
+ DWORD dwFlags);
+ static const GetFinalPathNameByHandleWFunc getFinalPathNameByHandle =
+ Utility::loadDllFunKernel<GetFinalPathNameByHandleWFunc>("GetFinalPathNameByHandleW");
+
+ if (getFinalPathNameByHandle == NULL)
+ throw FileError(wxString(_("Error loading library function:")) + wxT("\n\"") + wxT("GetFinalPathNameByHandleW") + wxT("\""));
+
+ const DWORD rv = (*getFinalPathNameByHandle)(
hDir,
targetPath,
BUFFER_SIZE,
@@ -987,7 +1015,7 @@ void FreeFileSync::createDirectory(const Zstring& directory, const Zstring& temp
Zstring createTempName(const Zstring& filename)
{
- Zstring output = filename + DefaultStr(".tmp");
+ Zstring output = filename + DefaultStr(".ffs_tmp");
//ensure uniqueness
if (FreeFileSync::fileExists(output))
@@ -1007,7 +1035,7 @@ Zstring createTempName(const Zstring& filename)
#ifdef FFS_WIN
#ifndef COPY_FILE_COPY_SYMLINK
-const DWORD COPY_FILE_COPY_SYMLINK = 0x00000800;
+#define COPY_FILE_COPY_SYMLINK 0x00000800
#endif
DWORD CALLBACK copyCallbackInternal(
@@ -1063,7 +1091,26 @@ bool supportForSymbolicLinks()
//symbolic links are supported starting with Vista
if (GetVersionEx(&osvi))
return osvi.dwMajorVersion > 5; //XP has majorVersion == 5, minorVersion == 1, Vista majorVersion == 6
+ //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
+ return false;
+}
+
+#ifndef COPY_FILE_ALLOW_DECRYPTED_DESTINATION
+#define COPY_FILE_ALLOW_DECRYPTED_DESTINATION 0x00000008
+#endif
+
+
+bool supportForNonEncryptedDestination()
+{
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ //symbolic links are supported starting with Vista
+ if (GetVersionEx(&osvi))
+ return osvi.dwMajorVersion >= 5 && osvi.dwMinorVersion >= 1; //XP has majorVersion == 5, minorVersion == 1, Vista majorVersion == 6
+ //overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
return false;
}
@@ -1081,6 +1128,12 @@ void FreeFileSync::copyFile(const Zstring& sourceFile,
if (copyFileSymLinks && symlinksSupported)
copyFlags |= COPY_FILE_COPY_SYMLINK;
+ //allow copying from encrypted to non-encrytped location
+ static const bool nonEncSupported = supportForNonEncryptedDestination();
+ if (nonEncSupported)
+ copyFlags |= COPY_FILE_ALLOW_DECRYPTED_DESTINATION;
+
+
const Zstring temporary = createTempName(targetFile); //use temporary file until a correct date has been set
if (!::CopyFileEx( //same performance as CopyFile()
sourceFile.c_str(),
@@ -1312,3 +1365,4 @@ bool FreeFileSync::isFatDrive(const Zstring& directoryName)
}
#endif //FFS_WIN
*/
+
bgstack15