From 1845c028b8cb8496d1d78f0da738120e1c31401a Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 2 Oct 2015 14:52:04 +0200 Subject: 6.8 --- zen/recycler.cpp | 72 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'zen/recycler.cpp') diff --git a/zen/recycler.cpp b/zen/recycler.cpp index 0e4e4be0..41ea6002 100644 --- a/zen/recycler.cpp +++ b/zen/recycler.cpp @@ -5,7 +5,7 @@ // ************************************************************************** #include "recycler.h" -#include +#include "file_handling.h" #ifdef ZEN_WIN #include "thread.h" @@ -16,9 +16,9 @@ #include "IFileOperation/file_op.h" #elif defined ZEN_LINUX -#include #include #include +#include "scope_guard.h" #elif defined ZEN_MAC #include @@ -54,14 +54,14 @@ struct CallbackData }; -bool onRecyclerCallback(const wchar_t* filename, void* sink) +bool onRecyclerCallback(const wchar_t* itempath, void* sink) { CallbackData& cbd = *static_cast(sink); //sink is NOT optional here if (cbd.notifyDeletionStatus_) try { - cbd.notifyDeletionStatus_(filename); //throw ? + cbd.notifyDeletionStatus_(itempath); //throw ? } catch (...) { @@ -73,11 +73,11 @@ bool onRecyclerCallback(const wchar_t* filename, void* sink) } -void zen::recycleOrDelete(const std::vector& filenames, const std::function& notifyDeletionStatus) +void zen::recycleOrDelete(const std::vector& itempaths, const std::function& notifyDeletionStatus) { - if (filenames.empty()) + if (itempaths.empty()) return; - //::SetFileAttributes(applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_NORMAL); + //::SetFileAttributes(applyLongPathPrefix(itempath).c_str(), FILE_ATTRIBUTE_NORMAL); //warning: moving long file paths to recycler does not work! //both ::SHFileOperation() and ::IFileOperation() cannot delete a folder named "System Volume Information" with normal attributes but shamelessly report success //both ::SHFileOperation() and ::IFileOperation() can't handle \\?\-prefix! @@ -89,11 +89,11 @@ void zen::recycleOrDelete(const std::vector& filenames, const std::func const DllFun getLastErrorMessage(getDllName(), funName_getLastErrorMessage); if (!moveToRecycler || !getLastErrorMessage) - throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0])), + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempaths[0])), replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName()))); std::vector cNames; - for (auto it = filenames.begin(); it != filenames.end(); ++it) //CAUTION: do not create temporary strings here!! + for (auto it = itempaths.begin(); it != itempaths.end(); ++it) //CAUTION: do not create temporary strings here!! cNames.push_back(it->c_str()); CallbackData cbd(notifyDeletionStatus); @@ -106,26 +106,26 @@ void zen::recycleOrDelete(const std::vector& filenames, const std::func assert(false); } - std::wstring filenameFmt = fmtFileName(filenames[0]); //probably not the correct file name for file lists larger than 1! - if (filenames.size() > 1) - filenameFmt += L", ..."; //give at least some hint that there are multiple files, and the error need not be related to the first one + std::wstring itempathFmt = fmtFileName(itempaths[0]); //probably not the correct file name for file lists larger than 1! + if (itempaths.size() > 1) + itempathFmt += L", ..."; //give at least some hint that there are multiple files, and the error need not be related to the first one - throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", filenameFmt), getLastErrorMessage()); //already includes details about locking errors! + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", itempathFmt), getLastErrorMessage()); //already includes details about locking errors! } } else //regular recycle bin usage: available since XP { - Zstring filenamesDoubleNull; - for (const Zstring& filename : filenames) + Zstring itempathsDoubleNull; + for (const Zstring& itempath : itempaths) { - filenamesDoubleNull += filename; - filenamesDoubleNull += L'\0'; + itempathsDoubleNull += itempath; + itempathsDoubleNull += L'\0'; } SHFILEOPSTRUCT fileOp = {}; fileOp.hwnd = nullptr; fileOp.wFunc = FO_DELETE; - fileOp.pFrom = filenamesDoubleNull.c_str(); + fileOp.pFrom = itempathsDoubleNull.c_str(); fileOp.pTo = nullptr; fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI; fileOp.fAnyOperationsAborted = false; @@ -135,25 +135,25 @@ void zen::recycleOrDelete(const std::vector& filenames, const std::func //"You should use fully-qualified path names with this function. Using it with relative path names is not thread safe." if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) { - throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0]))); //probably not the correct file name for file list larger than 1! + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempaths[0]))); //probably not the correct file name for file list larger than 1! } } } #endif -bool zen::recycleOrDelete(const Zstring& filename) //throw FileError +bool zen::recycleOrDelete(const Zstring& itempath) //throw FileError { - if (!somethingExists(filename)) //[!] do not optimize away, OS X needs this for reliable detection of "recycle bin missing" + if (!somethingExists(itempath)) //[!] do not optimize away, OS X needs this for reliable detection of "recycle bin missing" return false; //neither file nor any other object with that name existing: no error situation, manual deletion relies on it! #ifdef ZEN_WIN - std::vector filenames; - filenames.push_back(filename); - recycleOrDelete(filenames, nullptr); //throw FileError + std::vector itempaths; + itempaths.push_back(itempath); + recycleOrDelete(itempaths, nullptr); //throw FileError #elif defined ZEN_LINUX - GFile* file = ::g_file_new_for_path(filename.c_str()); //never fails according to docu + GFile* file = ::g_file_new_for_path(itempath.c_str()); //never fails according to docu ZEN_ON_SCOPE_EXIT(g_object_unref(file);) GError* error = nullptr; @@ -161,7 +161,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError if (!::g_file_trash(file, nullptr, &error)) { - const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename)); + const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempath)); if (!error) throw FileError(errorMsg, L"Unknown error."); //user should never see this @@ -170,13 +170,13 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError if (error->code == G_IO_ERROR_NOT_SUPPORTED) { struct ::stat fileInfo = {}; - if (::lstat(filename.c_str(), &fileInfo) != 0) + if (::lstat(itempath.c_str(), &fileInfo) != 0) return false; if (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode)) - removeFile(filename); //throw FileError + removeFile(itempath); //throw FileError else if (S_ISDIR(fileInfo.st_mode)) - removeDirectory(filename); //throw FileError + removeDirectory(itempath); //throw FileError return true; } @@ -188,11 +188,11 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError //we cannot use FSPathMoveObjectToTrashSync directly since it follows symlinks! assert_static(sizeof(Zchar) == sizeof(char)); - const UInt8* filenameUtf8 = reinterpret_cast(filename.c_str()); + const UInt8* itempathUtf8 = reinterpret_cast(itempath.c_str()); auto throwFileError = [&](OSStatus oss) { - const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename)); + const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(itempath)); std::wstring errorDescr = L"OSStatus Code " + numberTo(oss); if (const char* description = ::GetMacOSStatusCommentString(oss)) //found no documentation for proper use of GetMacOSStatusCommentString @@ -201,7 +201,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError }; FSRef objectRef = {}; //= POD structure not a pointer type! - OSStatus rv = ::FSPathMakeRefWithOptions(filenameUtf8, //const UInt8 *path, + OSStatus rv = ::FSPathMakeRefWithOptions(itempathUtf8, //const UInt8 *path, kFSPathMakeRefDoNotFollowLeafSymlink, //OptionBits options, &objectRef, //FSRef *ref, nullptr); //Boolean *isDirectory @@ -218,13 +218,13 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError if (rv2 == -120) //=="Directory not found or incomplete pathname." but should really be "recycle bin directory not found"! { struct ::stat fileInfo = {}; - if (::lstat(filename.c_str(), &fileInfo) != 0) + if (::lstat(itempath.c_str(), &fileInfo) != 0) return false; if (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode)) - removeFile(filename); //throw FileError + removeFile(itempath); //throw FileError else if (S_ISDIR(fileInfo.st_mode)) - removeDirectory(filename); //throw FileError + removeDirectory(itempath); //throw FileError return true; } @@ -352,7 +352,7 @@ We really need access to a similar function to check whether a directory support The following function looks perfect, alas it is restricted to local files and to the implementation of GIO only: - gboolean _g_local_file_has_trash_dir(const char* dirname, dev_t dir_dev); + gboolean _g_local_file_has_trash_dir(const char* dirpath, dev_t dir_dev); See: http://www.netmite.com/android/mydroid/2.0/external/bluetooth/glib/gio/glocalfileinfo.h Just checking for "G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH" is not correct, since we find in -- cgit