summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD/Changelog.txt6
-rw-r--r--BUILD/FreeFileSync.chmbin672005 -> 670693 bytes
-rw-r--r--BUILD/Help/html/Features.html99
-rw-r--r--BUILD/Languages/chinese_simple.lng22
-rw-r--r--BUILD/Resources.zipbin272977 -> 272855 bytes
-rw-r--r--file_hierarchy.cpp12
-rw-r--r--file_hierarchy.h4
-rw-r--r--lib/custom_grid.cpp6
-rw-r--r--lib/parse_plural.h2
-rw-r--r--ui/main_dlg.cpp10
-rw-r--r--version/version.h2
-rw-r--r--version/version.rc4
-rw-r--r--zen/file_handling.cpp100
-rw-r--r--zen/file_traverser.cpp2
14 files changed, 124 insertions, 145 deletions
diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt
index 7116b447..5e5d9053 100644
--- a/BUILD/Changelog.txt
+++ b/BUILD/Changelog.txt
@@ -2,6 +2,11 @@
|FreeFileSync|
--------------
+Changelog v4.4
+--------------
+Fixed error copying files containing alternate data streams (Windows)
+
+
Changelog v4.3
--------------
Detection of moved and renamed files
@@ -11,6 +16,7 @@ Fixed synchronization result dialog GUI glitch (Windows XP)
Fixed macro %weekday%
RealtimeSync: Fixed support for manual volume unmount (Windows)
Added Croatian language
+Updated translation files
Changelog v4.2
diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm
index cc0d3174..04ae52a9 100644
--- a/BUILD/FreeFileSync.chm
+++ b/BUILD/FreeFileSync.chm
Binary files differ
diff --git a/BUILD/Help/html/Features.html b/BUILD/Help/html/Features.html
index 784598ba..4b404317 100644
--- a/BUILD/Help/html/Features.html
+++ b/BUILD/Help/html/Features.html
@@ -5,7 +5,7 @@
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.2 (Win32)">
<META NAME="CREATED" CONTENT="20091206;16574000">
- <META NAME="CHANGED" CONTENT="20110915;12485300">
+ <META NAME="CHANGED" CONTENT="20111121;19582100">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
@@ -20,68 +20,43 @@
</HEAD>
<BODY LANG="de-DE" DIR="LTR">
<H3 CLASS="western"><FONT FACE="Tahoma, sans-serif">Key Features</FONT></H3>
-<P STYLE="margin-bottom: 0cm"><BR>
-</P>
<OL>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Detection
+ of moved and renamed files</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy
+ locked files using Windows Volume Shadow Copy Service. (Windows
+ only)</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support
+ for multiple folder pairs with distinct configuration</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Compare
files (bytewise or by date) and synchronize them.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">No
- limitations: An arbitrary number of files can be synchronized.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Unicode
- support.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Network
- support.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create
+ Batch Jobs for automated synchronization with or without GUI.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Optimized
+ performance, coded in C++ completely.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Native
+ 32 and 64 bit builds</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Transactional
file copy</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Synchronization
+ database for propagation of deleted files and conflict detection</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Cross-Platform</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full
+ support for Windows/Linux Symbolic Links and Windows Junction
+ Points.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full
+ unicode support.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full
+ network support.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Built-in
support for very long filenames (more than MAX_PATH = 260
characters).</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Synchronization
- database for propagation of deleted files and conflict detection</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy
NTFS alternate data streams, compressed and encrypted file
attributes</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support
- for multiple folder pairs with distinct configuration</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Full
- support for Windows/Linux Symbolic Links and Windows Junction
- Points.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Lean
- &amp; easily accessible UI: Highly optimized for speed and huge sets
- of data.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Algorithms
- coded in C++ completely.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">All
- progress indicators optimized for maximum performance!</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create
- Batch Jobs for automated synchronization with or without GUI.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Focus
- on usability:</FONT></P>
- <OL TYPE=a>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Only
- necessary functionality on UI: no overloaded menus or icon jungle.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Select
- all folders via drag &amp; drop.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Last
- used configuration and screen settings are saved automatically.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Maintain
- and load different configurations by drag &amp; drop, load-button
- or commandline.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Double-click
- to start external application (e.g. show file in Windows Explorer)</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy
- &amp; paste all grid data as text</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Delete
- superfluous/temporary files directly on main grid.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Right-click
- context menu.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Comprehensive
- status information and error reporting</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Sort
- file-lists by name, size or date.</FONT></P>
- </OL>
-</OL>
-<OL START=14>
+ &amp; easily accessible UI: only useful functionality, no feature
+ bloat.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Support
for filesizes larger than 4 GB.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Option
@@ -89,28 +64,20 @@
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Ignore
directories &quot;\RECYCLER&quot; and &quot;\System Volume
Information&quot; with default filter. (Windows only)</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Localized
- versions are available for many languages.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Delete
before copy: Avoid disc space shortages for large sync-jobs.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Filter
- functionality to include/exclude files from synchronization (without
- requiring a re-compare!).</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Include/exclude
- specific files from synchronization temporarily.</FONT></P>
+ functionality to include/exclude files from synchronization.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Automatically
handle daylight saving time changes on FAT/FAT32 volumes.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Portable
version available (selectable via installer).</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Native
- 64-Bit version.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Check
- for updates from within FreeFileSync automatically.</FONT></P>
- <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy
- locked files using Windows Volume Shadow Copy Service. (Windows
- only)</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Opt-in
+ for automatic online update.</FONT></P>
+ <LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Localized
+ versions are available for many languages.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Create
- regular backups with macros %time%, %date% within directory names</FONT></P>
+ recurring backups with macros %time%, %date% within directory names</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Copy
file create/modification times when synchronizing.</FONT></P>
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Advanced
@@ -119,5 +86,7 @@
<LI><P STYLE="margin-bottom: 0cm"><FONT FACE="Tahoma, sans-serif">Case-sensitive
synchronization of file, directory and symlink names</FONT></P>
</OL>
+<P STYLE="margin-bottom: 0cm"><BR>
+</P>
</BODY>
</HTML> \ No newline at end of file
diff --git a/BUILD/Languages/chinese_simple.lng b/BUILD/Languages/chinese_simple.lng
index 65887d4f..e71fbcee 100644
--- a/BUILD/Languages/chinese_simple.lng
+++ b/BUILD/Languages/chinese_simple.lng
@@ -499,10 +499,10 @@ The command line is executed each time:
<target>操作:</target>
<source>Items found:</source>
-<target>已找到的元素:</target>
+<target>已找到的项目:</target>
<source>Items remaining:</source>
-<target>剩余的元素:</target>
+<target>剩余的项目:</target>
<source>Speed:</source>
<target>速度:</target>
@@ -568,7 +568,7 @@ The command line is executed each time:
<target><自动></target>
<source>Identify and propagate changes on both sides using a database. Deletions, renaming and conflicts are detected automatically.</source>
-<target></target>
+<target>使用一个数据库来识别和传播两边的改变. 删除,重命名和冲突会自动检测.</target>
<source>Mirror ->></source>
<target>镜像 ->></target>
@@ -661,7 +661,7 @@ is the same
<target>同步中...</target>
<source>Items processed:</source>
-<target>已处理的元素:</target>
+<target>已处理的项目:</target>
<source>&Pause</source>
<target>暂停(&P)</target>
@@ -790,7 +790,7 @@ Exclude: \stuff\temp\*
<target>事务文件复制</target>
<source>Write to a temporary file (*.ffs_tmp) first then rename it. This guarantees a consistent state even in case of fatal error.</source>
-<target></target>
+<target>首先写入到一个临时文件(*.ffs_tmp)然后再重命名. 这样即使出现致命错误也能保持一致的状态.</target>
<source>Copy locked files</source>
<target>复制被锁定的文件</target>
@@ -877,16 +877,16 @@ Exclude: \stuff\temp\*
<target>自动调整栏宽</target>
<source>Icon size:</source>
-<target></target>
+<target>图标大小:</target>
<source>Small</source>
-<target></target>
+<target>小</target>
<source>Medium</source>
-<target></target>
+<target>中</target>
<source>Large</source>
-<target></target>
+<target>大</target>
<source>Include all rows</source>
<target>包括所有行</target>
@@ -1342,10 +1342,10 @@ Exclude: \stuff\temp\*
<target>删除右侧文件/文件夹</target>
<source>Move file on left</source>
-<target></target>
+<target>移动左侧的文件</target>
<source>Move file on right</source>
-<target></target>
+<target>移动右侧的文件</target>
<source>Overwrite left file/folder with right one</source>
<target>从右侧覆盖左侧的文件/文件夹</target>
diff --git a/BUILD/Resources.zip b/BUILD/Resources.zip
index 9ad96f71..c4749b68 100644
--- a/BUILD/Resources.zip
+++ b/BUILD/Resources.zip
Binary files differ
diff --git a/file_hierarchy.cpp b/file_hierarchy.cpp
index 39b789fd..f5d2d28c 100644
--- a/file_hierarchy.cpp
+++ b/file_hierarchy.cpp
@@ -117,15 +117,15 @@ bool hasDirectChild(const HierarchyObject& hierObj, Predicate p)
}
-SyncOperation FileSystemObject::testSyncOperation(SyncDirection testSyncDir) const
+SyncOperation FileSystemObject::testSyncOperation(SyncDirection testSyncDir, bool enabled) const
{
- return proposedSyncOperation(getCategory(), selectedForSynchronization, testSyncDir, syncDirConflict);
+ return proposedSyncOperation(getCategory(), enabled, testSyncDir, syncDirConflict);
}
SyncOperation FileSystemObject::getSyncOperation() const
{
- return FileSystemObject::testSyncOperation(syncDir);
+ return FileSystemObject::testSyncOperation(syncDir, selectedForSynchronization);
//no *not* make a virtual call to testSyncOperation()! See FileMapping::testSyncOperation()!
}
@@ -205,9 +205,9 @@ SyncOperation DirMapping::getSyncOperation() const
}
-SyncOperation FileMapping::testSyncOperation(SyncDirection testSyncDir) const
+SyncOperation FileMapping::testSyncOperation(SyncDirection testSyncDir, bool enabled) const
{
- SyncOperation op = FileSystemObject::testSyncOperation(testSyncDir);
+ SyncOperation op = FileSystemObject::testSyncOperation(testSyncDir, enabled);
/*
check whether we can optimize "create + delete" via "move":
@@ -236,7 +236,7 @@ SyncOperation FileMapping::testSyncOperation(SyncDirection testSyncDir) const
SyncOperation FileMapping::getSyncOperation() const
{
- return FileMapping::testSyncOperation(getSyncDir());
+ return FileMapping::testSyncOperation(getSyncDir(), isActive());
}
diff --git a/file_hierarchy.h b/file_hierarchy.h
index cfa71ab2..ac7ed87d 100644
--- a/file_hierarchy.h
+++ b/file_hierarchy.h
@@ -348,7 +348,7 @@ public:
virtual CompareFilesResult getCategory() const = 0;
virtual std::wstring getCatConflict() const = 0; //only filled if getCategory() == FILE_CONFLICT
//sync operation
- virtual SyncOperation testSyncOperation(SyncDirection testSyncDir) const;
+ virtual SyncOperation testSyncOperation(SyncDirection testSyncDir, bool enabled) const;
virtual SyncOperation getSyncOperation() const;
std::wstring getSyncOpConflict() const; //return conflict when determining sync direction or during categorization
@@ -491,7 +491,7 @@ public:
virtual CompareFilesResult getCategory() const;
virtual std::wstring getCatConflict() const;
- virtual SyncOperation testSyncOperation(SyncDirection testSyncDir) const;
+ virtual SyncOperation testSyncOperation(SyncDirection testSyncDir, bool enabled) const;
virtual SyncOperation getSyncOperation() const;
template <SelectedSide side> void syncTo(const FileDescriptor& descrTarget, const FileDescriptor* descrSource = NULL); //copy + update file attributes (optional)
diff --git a/lib/custom_grid.cpp b/lib/custom_grid.cpp
index f2892624..736bc49d 100644
--- a/lib/custom_grid.cpp
+++ b/lib/custom_grid.cpp
@@ -2298,13 +2298,13 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
case CustomGridMiddle::BLOCKPOS_CHECK_BOX:
break;
case CustomGridMiddle::BLOCKPOS_LEFT:
- dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_LEFT)), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_LEFT, true)), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
break;
case CustomGridMiddle::BLOCKPOS_MIDDLE:
- dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_NONE)), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_NONE, true)), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case CustomGridMiddle::BLOCKPOS_RIGHT:
- dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_RIGHT)), rectShrinked, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
+ dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_RIGHT, true)), rectShrinked, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
break;
}
else //default
diff --git a/lib/parse_plural.h b/lib/parse_plural.h
index 960172fa..4ac9e47b 100644
--- a/lib/parse_plural.h
+++ b/lib/parse_plural.h
@@ -229,7 +229,7 @@ private:
{
public:
Parser(const Wstring& phrase, //in
- const Expr<int>*& expr, int& n, PluralForm::DumpList& dump) ://out
+ const Expr<int>*& expr, int& n, PluralForm::DumpList& dump) : //out
scn(phrase),
tk(scn.nextToken()),
n_(n),
diff --git a/ui/main_dlg.cpp b/ui/main_dlg.cpp
index 97c3625c..316be694 100644
--- a/ui/main_dlg.cpp
+++ b/ui/main_dlg.cpp
@@ -1256,10 +1256,12 @@ void MainDialog::disableAllElements(bool enableAbort)
void MainDialog::enableAllElements()
{
+ //wxGTK, yet another QOI issue: some stupid bug, keeps moving main dialog to top!!
+
EnableCloseButton(true);
m_panelViewFilter ->Enable();
- m_bpButtonCmpConfig ->Enable(); //wxGTK bug: this line seems to move main dialog to top!!!!!!!
+ m_bpButtonCmpConfig ->Enable();
m_panelFilter ->Enable();
m_panelConfig ->Enable();
m_bpButtonSyncConfig ->Enable();
@@ -1762,21 +1764,21 @@ void MainDialog::OnContextRim(wxGridEvent& event)
//CONTEXT_SYNC_DIR_LEFT
wxMenuItem* menuItemSyncDirLeft = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Set direction:")) +
wxT(" <-") + wxT("\tAlt - Left")); //Linux needs a direction, "<-", because it has no context menu icons!
- menuItemSyncDirLeft->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_LEFT)));
+ menuItemSyncDirLeft->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_LEFT, true)));
contextMenu->Append(menuItemSyncDirLeft);
contextMenu->Connect(menuItemSyncDirLeft->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncDirLeft), NULL, this);
//CONTEXT_SYNC_DIR_NONE
wxMenuItem* menuItemSyncDirNone = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Set direction:")) +
wxT(" -") + wxT("\tAlt - Up"));
- menuItemSyncDirNone->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_NONE)));
+ menuItemSyncDirNone->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_NONE, true)));
contextMenu->Append(menuItemSyncDirNone);
contextMenu->Connect(menuItemSyncDirNone->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncDirNone), NULL, this);
//CONTEXT_SYNC_DIR_RIGHT
wxMenuItem* menuItemSyncDirRight = new wxMenuItem(contextMenu.get(), wxID_ANY, wxString(_("Set direction:")) +
wxT(" ->") + wxT("\tAlt - Right"));
- menuItemSyncDirRight->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_RIGHT)));
+ menuItemSyncDirRight->SetBitmap(getSyncOpImage(fsObj->testSyncOperation(SYNC_DIR_RIGHT, true)));
contextMenu->Append(menuItemSyncDirRight);
contextMenu->Connect(menuItemSyncDirRight->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainDialog::OnContextSyncDirRight), NULL, this);
diff --git a/version/version.h b/version/version.h
index f029c89d..50936457 100644
--- a/version/version.h
+++ b/version/version.h
@@ -3,7 +3,7 @@
namespace zen
{
-const wchar_t currentVersion[] = L"4.3"; //internal linkage!
+const wchar_t currentVersion[] = L"4.4"; //internal linkage!
}
#endif
diff --git a/version/version.rc b/version/version.rc
index 60e22b93..c5f61a95 100644
--- a/version/version.rc
+++ b/version/version.rc
@@ -1,2 +1,2 @@
-#define VER_FREEFILESYNC 4,3,0,0
-#define VER_FREEFILESYNC_STR "4.3\0"
+#define VER_FREEFILESYNC 4,4,0,0
+#define VER_FREEFILESYNC_STR "4.4\0"
diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp
index 8523c633..1e44afb7 100644
--- a/zen/file_handling.cpp
+++ b/zen/file_handling.cpp
@@ -1001,8 +1001,10 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym
//setting privileges requires admin rights!
try
{
- //enable privilege: required to read/write SACL information
+ //enable privilege: required to read/write SACL information (only)
activatePrivilege(SE_SECURITY_NAME); //polling allowed...
+ //Note: trying to copy SACL (SACL_SECURITY_INFORMATION) may return ERROR_PRIVILEGE_NOT_HELD (1314) on Samba shares. This is not due to missing privileges!
+ //However, this is okay, since copying NTFS permissions doesn't make sense in this case anyway
//enable privilege: required to copy owner information
activatePrivilege(SE_RESTORE_NAME);
@@ -1027,7 +1029,7 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym
DWORD bytesNeeded = 0;
if (::GetFileSecurity(applyLongPathPrefix(sourceResolved).c_str(), //__in LPCTSTR lpFileName, -> long path prefix IS needed, although it is NOT mentioned on MSDN!!!
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION RequestedInformation,
+ DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION RequestedInformation,
reinterpret_cast<PSECURITY_DESCRIPTOR>(&buffer[0]), //__out_opt PSECURITY_DESCRIPTOR pSecurityDescriptor,
static_cast<DWORD>(buffer.size()), //__in DWORD nLength,
&bytesNeeded)) //__out LPDWORD lpnLengthNeeded
@@ -1058,7 +1060,7 @@ void copyObjectPermissions(const Zstring& source, const Zstring& target, ProcSym
if (!::SetFileSecurity(applyLongPathPrefix(targetResolved).c_str(), //__in LPCTSTR lpFileName, -> long path prefix IS needed, although it is NOT mentioned on MSDN!!!
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION SecurityInformation,
+ DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, //__in SECURITY_INFORMATION SecurityInformation,
&secDescr)) //__in PSECURITY_DESCRIPTOR pSecurityDescriptor
throw FileError(_("Error copying file permissions:") + L"\n\"" + sourceResolved + L"\" ->\n\"" + targetResolved + L"\"" + L"\n\n" + getLastErrorFormatted() + L" (W)");
@@ -1396,8 +1398,8 @@ public:
const Zstring& targetFile_;
const bool osIsvistaOrLater_;
- //there is some mixed responsibility in this class, pure read-only data and abstraction for error reporting
- //however we need to keep it at one place as ::CopyFileEx() requires!
+ //there is mixed responsibility in this class, pure read-only data and abstraction for error reporting
+ //however we need to keep it together as ::CopyFileEx() requires!
void reportUserException(const UInt64& bytesTransferred)
{
@@ -1438,32 +1440,39 @@ private:
};
-DWORD CALLBACK copyCallbackInternal(
- LARGE_INTEGER totalFileSize,
- LARGE_INTEGER totalBytesTransferred,
- LARGE_INTEGER streamSize,
- LARGE_INTEGER streamBytesTransferred,
- DWORD dwStreamNumber,
- DWORD dwCallbackReason,
- HANDLE hSourceFile,
- HANDLE hDestinationFile,
- LPVOID lpData)
+DWORD CALLBACK copyCallbackInternal(LARGE_INTEGER totalFileSize,
+ LARGE_INTEGER totalBytesTransferred,
+ LARGE_INTEGER streamSize,
+ LARGE_INTEGER streamBytesTransferred,
+ DWORD dwStreamNumber,
+ DWORD dwCallbackReason,
+ HANDLE hSourceFile,
+ HANDLE hDestinationFile,
+ LPVOID lpData)
{
- //this callback is invoked for block sizes managed by Windows, these may vary from e.g. 64 kB up to 1MB. It seems this is dependent from file size amongst others.
+ /*
+ this callback is invoked for block sizes managed by Windows, these may vary from e.g. 64 kB up to 1MB. It seems this depends on file size amongst others.
+
+ symlink handling:
+ if source is a symlink and COPY_FILE_COPY_SYMLINK is specified, this callback is NOT invoked!
+ if source is a symlink and COPY_FILE_COPY_SYMLINK is NOT specified, this callback is called and hSourceFile is a handle to the *target* of the link!
- //symlink handling:
- //if source is a symlink and COPY_FILE_COPY_SYMLINK is specified, this callback is NOT invoked!
- //if source is a symlink and COPY_FILE_COPY_SYMLINK is NOT specified, this callback is called and hSourceFile is a handle to the *target* of the link!
+ file time handling:
+ ::CopyFileEx() will copy file modification time (only) over from source file AFTER the last inocation of this callback
+ => it is possible to adapt file creation time of target in here, but NOT file modification time!
- //file time handling:
- //::CopyFileEx() will copy file modification time (only) over from source file AFTER the last inocation of this callback
- //=> it is possible to adapt file creation time of target in here, but NOT file modification time!
+ alternate data stream handling:
+ CopyFileEx() processes multiple streams one after another, stream 1 is the file data stream and always available!
+ Each stream is initialized with CALLBACK_STREAM_SWITCH and provides *new* hSourceFile, hDestinationFile.
+ Calling GetFileInformationByHandle() on hDestinationFile for stream > 1 results in ERROR_ACCESS_DENIED!
+ */
CallbackData& cbd = *static_cast<CallbackData*>(lpData);
- //#################### return source file attributes ################################
- if (dwCallbackReason == CALLBACK_STREAM_SWITCH) //called up front for every file (even if 0-sized)
+ if (dwCallbackReason == CALLBACK_STREAM_SWITCH && //called up-front for every file (even if 0-sized)
+ dwStreamNumber == 1) //ADS!
{
+ //#################### return source file attributes ################################
BY_HANDLE_FILE_INFORMATION fileInfoSrc = {};
if (!::GetFileInformationByHandle(hSourceFile, &fileInfoSrc))
{
@@ -1480,7 +1489,7 @@ DWORD CALLBACK copyCallbackInternal(
FileAttrib attr;
attr.fileSize = UInt64(fileInfoSrc.nFileSizeLow, fileInfoSrc.nFileSizeHigh);
- attr.modificationTime = toTimeT(fileInfoSrc.ftLastWriteTime);
+ attr.modificationTime = toTimeT(fileInfoSrc.ftLastWriteTime); //no DST hack (yet)
attr.sourceFileId = extractFileID(fileInfoSrc);
attr.targetFileId = extractFileID(fileInfoTrg);
@@ -1498,18 +1507,12 @@ DWORD CALLBACK copyCallbackInternal(
return PROGRESS_CANCEL;
}
- if (!::SetFileTime(hDestinationFile,
- &creationTime,
- NULL,
- NULL))
- {
- cbd.reportError(_("Error changing modification time:") + L"\n\"" + cbd.targetFile_ + L"\"" + L"\n\n" + getLastErrorFormatted());
- return PROGRESS_CANCEL;
- }
+ ::SetFileTime(hDestinationFile, &creationTime, NULL, NULL); //no error handling!
//##############################################################################
}
- //if (totalFileSize.QuadPart == totalBytesTransferred.QuadPart) {} //called after copy operation is finished - note: for 0-sized files this callback is invoked just ONCE!
+ //called after copy operation is finished - note: for 0-sized files this callback is invoked just ONCE!
+ //if (totalFileSize.QuadPart == totalBytesTransferred.QuadPart && dwStreamNumber == 1) {}
if (cbd.userCallback)
{
@@ -1621,8 +1624,13 @@ void rawCopyWinApi_sub(const Zstring& sourceFile,
*newAttrib = cbd.getSrcAttr();
{
+ //DST hack
const Int64 modTime = getFileTime(sourceFile, SYMLINK_FOLLOW); //throw FileError
setFileTime(targetFile, modTime, SYMLINK_FOLLOW); //throw FileError
+
+ if (newAttrib)
+ newAttrib->modificationTime = modTime;
+
//note: this sequence leads to a loss of precision of up to 1 sec!
//perf-loss on USB sticks with many small files of about 30%! damn!
}
@@ -1990,7 +1998,7 @@ void rawCopyStream(const Zstring& sourceFile,
CallbackCopyFile* callback,
FileAttrib* newAttrib) //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
{
- zen::ScopeGuard guardTarget = zen::makeGuard([&]() { removeFile(targetFile); }); //transactional behavior: place guard before lifetime of FileOutput
+ zen::ScopeGuard guardTarget = zen::makeGuard([&] { removeFile(targetFile); }); //transactional behavior: place guard before lifetime of FileOutput
try
{
//open sourceFile for reading
@@ -1999,10 +2007,13 @@ void rawCopyStream(const Zstring& sourceFile,
//create targetFile and open it for writing
FileOutput fileOut(targetFile, FileOutput::ACC_CREATE_NEW); //throw FileError, ErrorTargetPathMissing, ErrorTargetExisting
- static boost::thread_specific_ptr<std::vector<char>> cpyBuf;
+ std::vector<char>& buffer = []() -> std::vector<char>&
+ {
+ static boost::thread_specific_ptr<std::vector<char>> cpyBuf;
if (!cpyBuf.get())
cpyBuf.reset(new std::vector<char>(512 * 1024)); //512 kb seems to be a reasonable buffer size
- std::vector<char>& buffer = *cpyBuf;
+ return *cpyBuf;
+ }();
//copy contents of sourceFile to targetFile
UInt64 totalBytesTransferred;
@@ -2140,21 +2151,12 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath
-> higher performance on non-buffered drives (e.g. usb sticks)
*/
- //set file permissions
+ //file permissions
if (copyFilePermissions)
{
- zen::ScopeGuard guardTargetFile = zen::makeGuard([&]() { removeFile(targetFile);});
- copyObjectPermissions(sourceFile, targetFile, SYMLINK_FOLLOW); //throw FileError
-
+ zen::ScopeGuard guardTargetFile = zen::makeGuard([&] { removeFile(targetFile);});
- /*
- warn_static("fix!!")
- try
- {
- copyObjectPermissions(targetFile, L"kfsdaj", SYMLINK_FOLLOW); //throw FileError
- }
- catch (...) {}
- */
+ copyObjectPermissions(sourceFile, targetFile, SYMLINK_FOLLOW); //throw FileError
guardTargetFile.dismiss(); //target has been created successfully!
}
diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp
index 81e70383..8a8a8b6f 100644
--- a/zen/file_traverser.cpp
+++ b/zen/file_traverser.cpp
@@ -126,7 +126,7 @@ struct X //see "policy based design"
{
typedef ... Handle;
typedef ... FindData;
-static Handle create(const Zstring& directoryPf, FindData& fileInfo); //throw FileError
+static Handle create(const Zstring& directoryPf, FindData& fileInfo); //throw FileError - concession to FindFirstFile(): implement two operations: 1. open handle, 2. retrieve first data set
static void destroy(Handle hnd); //throw()
static bool next(Handle hnd, const Zstring& directory, WIN32_FIND_DATA& fileInfo) //throw FileError
bgstack15