diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:19:14 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:19:14 +0200 |
commit | 01eb8253196672c969a39587e90b49321a182428 (patch) | |
tree | 4a3b71d7913de519744466c9227fda6461c4f0b5 /lib/recycler.cpp | |
parent | 5.0 (diff) | |
download | FreeFileSync-01eb8253196672c969a39587e90b49321a182428.tar.gz FreeFileSync-01eb8253196672c969a39587e90b49321a182428.tar.bz2 FreeFileSync-01eb8253196672c969a39587e90b49321a182428.zip |
5.1
Diffstat (limited to 'lib/recycler.cpp')
-rw-r--r-- | lib/recycler.cpp | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/lib/recycler.cpp b/lib/recycler.cpp index 11ed77f7..1c743a0c 100644 --- a/lib/recycler.cpp +++ b/lib/recycler.cpp @@ -22,8 +22,9 @@ #include "IFileOperation/file_op.h" #elif defined FFS_LINUX +#include <zen/scope_guard.h> #include <sys/stat.h> -#include <giomm/file.h> +#include <gio/gio.h> #endif using namespace zen; @@ -52,7 +53,7 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F static bool useIFileOperation = false; static boost::once_flag once = BOOST_ONCE_INIT; //caveat: function scope static initialization is not thread-safe in VS 2010! - boost::call_once(once, []() { useIFileOperation = vistaOrLater(); }); + boost::call_once(once, [] { useIFileOperation = vistaOrLater(); }); if (useIFileOperation) //new recycle bin usage: available since Vista { @@ -65,8 +66,8 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F const DllFun<GetLastErrorFct> getLastError (getDllName(), getLastErrorFctName); if (!moveToRecycler || !getLastError) - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + fileNames[0] + L"\"" + //report first file only... better than nothing - L"\n\n" + _("Could not load a required DLL:") + L" \"" + getDllName() + L"\""); + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", std::wstring(L"\"") + fileNames[0] + L"\"") + L"\n\n" + //report first file only... better than nothing + replaceCpy(_("Cannot load file %x."), L"%x", std::wstring(L"\"") + getDllName() + L"\"")); //#warning moving long file paths to recycler does not work! clarify! // std::vector<Zstring> temp; @@ -76,10 +77,11 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F if (!moveToRecycler(&fileNames[0], //array must not be empty fileNames.size())) { - wchar_t errorMessage[2000]; - getLastError(errorMessage, 2000); - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + fileNames[0] + L"\"" + //report first file only... better than nothing - L"\n\n" + L"(" + errorMessage + L")"); + std::vector<wchar_t> msgBuffer(2000); + getLastError(&msgBuffer[0], msgBuffer.size()); + + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", std::wstring(L"\"") + fileNames[0] + L"\"") + L"\n\n" + //report first file only... better than nothing + &msgBuffer[0]); } } else //regular recycle bin usage: available since XP @@ -95,18 +97,18 @@ void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw F } SHFILEOPSTRUCT fileOp = {}; - fileOp.hwnd = NULL; + fileOp.hwnd = nullptr; fileOp.wFunc = FO_DELETE; fileOp.pFrom = filenameDoubleNull.c_str(); - fileOp.pTo = NULL; + fileOp.pTo = nullptr; fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; fileOp.fAnyOperationsAborted = false; - fileOp.hNameMappings = NULL; - fileOp.lpszProgressTitle = NULL; + fileOp.hNameMappings = nullptr; + fileOp.lpszProgressTitle = nullptr; if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) { - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filenameDoubleNull + L"\""); //report first file only... better than nothing + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", std::wstring(L"\"") + filenameDoubleNull.c_str() + L"\"")); //report first file only... better than nothing } } } @@ -128,17 +130,20 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError ::moveToWindowsRecycler(fileNames); //throw FileError #elif defined FFS_LINUX - Glib::RefPtr<Gio::File> fileObj = Gio::File::create_for_path(filename.c_str()); //never fails - try - { - if (!fileObj->trash()) - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filename + L"\"" + - L"\n\n" + L"(unknown error)"); - } - catch (const Glib::Error& errorObj) + GFile* file = g_file_new_for_path(filename.c_str()); //never fails according to docu + ZEN_ON_SCOPE_EXIT(g_object_unref(file);) + + GError* error = nullptr; + ZEN_ON_SCOPE_EXIT(if (error) g_error_free(error);); + + if (!g_file_trash(file, nullptr, &error)) { + if (!error) + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", L"\"" + filename + L"\"") + L"\n\n" + + L"Unknown error."); + //implement same behavior as in Windows: if recycler is not existing, delete permanently - if (errorObj.code() == G_IO_ERROR_NOT_SUPPORTED) + if (error->code == G_IO_ERROR_NOT_SUPPORTED) { struct stat fileInfo = {}; if (::lstat(filename.c_str(), &fileInfo) != 0) @@ -152,11 +157,11 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError } //assemble error message - const std::wstring errorMessage = L"Glib Error Code " + toString<std::wstring>(errorObj.code()) + /* L", " + - g_quark_to_string(errorObj.domain()) + */ L": " + utf8CvrtTo<std::wstring>(errorObj.what()); + const std::wstring errorMessage = L"Glib Error Code " + numberTo<std::wstring>(error->code) + /* L", " + + g_quark_to_string(error->domain) + */ L": " + utf8CvrtTo<std::wstring>(error->message); - throw FileError(_("Error moving to Recycle Bin:") + L"\n\"" + filename + L"\"" + - L"\n\n" + L"(" + errorMessage + L")"); + throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin!"), L"%x", L"\"" + filename + L"\"") + L"\n\n" + + errorMessage); } #endif return true; @@ -166,10 +171,11 @@ bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError #ifdef FFS_WIN zen::StatusRecycler zen::recycleBinStatus(const Zstring& pathName) { - std::vector<wchar_t> buffer(MAX_PATH + 1); - if (::GetVolumePathName(applyLongPathPrefix(pathName).c_str(), //__in LPCTSTR lpszFileName, - &buffer[0], //__out LPTSTR lpszVolumePathName, - static_cast<DWORD>(buffer.size()))) //__in DWORD cchBufferLength + const DWORD bufferSize = MAX_PATH + 1; + std::vector<wchar_t> buffer(bufferSize); + if (::GetVolumePathName(pathName.c_str(), //__in LPCTSTR lpszFileName, + &buffer[0], //__out LPTSTR lpszVolumePathName, + bufferSize)) //__in DWORD cchBufferLength { Zstring rootPath = &buffer[0]; if (!endsWith(rootPath, FILE_NAME_SEPARATOR)) //a trailing backslash is required |