summaryrefslogtreecommitdiff
path: root/shared/recycler.cpp
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:16 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:16 +0200
commitbd6336c629841c6db3a6ca53a936d629d34db53b (patch)
tree3721ef997864108df175ce677a8a7d4342a6f1d2 /shared/recycler.cpp
parent4.0 (diff)
downloadFreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.tar.gz
FreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.tar.bz2
FreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.zip
4.1
Diffstat (limited to 'shared/recycler.cpp')
-rw-r--r--shared/recycler.cpp218
1 files changed, 0 insertions, 218 deletions
diff --git a/shared/recycler.cpp b/shared/recycler.cpp
deleted file mode 100644
index 8c4a9da1..00000000
--- a/shared/recycler.cpp
+++ /dev/null
@@ -1,218 +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-2011 ZenJu (zhnmju123 AT gmx.de) *
-// **************************************************************************
-
-#include "recycler.h"
-#include <stdexcept>
-#include <iterator>
-#include "i18n.h"
-#include "file_handling.h"
-
-#ifdef FFS_WIN
-#include <boost/thread/once.hpp>
-#include "dll_loader.h"
-#include <wx/msw/wrapwin.h> //includes "windows.h"
-#include "assert_static.h"
-#include <algorithm>
-#include <functional>
-#include <vector>
-#include "long_path_prefix.h"
-#include "IFileOperation/file_op.h"
-
-#elif defined FFS_LINUX
-#include <sys/stat.h>
-#include <giomm/file.h>
-#endif
-
-using namespace zen;
-
-
-namespace
-{
-#ifdef FFS_WIN
-bool vistaOrLater()
-{
- OSVERSIONINFO osvi = {};
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- //IFileOperation is supported with Vista and later
- if (GetVersionEx(&osvi))
- return osvi.dwMajorVersion > 5;
- //XP has majorVersion == 5, minorVersion == 1
- //Vista has majorVersion == 6, minorVersion == 0
- //version overview: http://msdn.microsoft.com/en-us/library/ms724834(VS.85).aspx
- return false;
-}
-
-/*
-Performance test: delete 1000 files
-------------------------------------
-SHFileOperation - single file 33s
-SHFileOperation - multiple files 2,1s
-IFileOperation - single file 33s
-IFileOperation - multiple files 2,1s
-
-=> SHFileOperation and IFileOperation have nearly IDENTICAL performance characteristics!
-
-Nevertheless, let's use IFileOperation for better error reporting!
-*/
-
-void moveToWindowsRecycler(const std::vector<Zstring>& filesToDelete) //throw FileError
-{
- if (filesToDelete.empty())
- return;
-
- 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(); });
-
- 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;
- const util::DllFun<MoveToRecycleBinFct> moveToRecycler(getDllName(), moveToRecycleBinFctName);
- const util::DllFun<GetLastErrorFct> getLastError (getDllName(), getLastErrorFctName);
-
- if (!moveToRecycler || !getLastError)
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + fileNames[0] + "\"" + //report first file only... better than nothing
- "\n\n" + _("Could not load a required DLL:") + " \"" + getDllName() + "\"");
-
- //#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(zen::removeLongPathPrefix)); //::IFileOperation() can't handle \\?\-prefix!
-
- 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:") + "\n\"" + fileNames[0] + "\"" + //report first file only... better than nothing
- "\n\n" + "(" + errorMessage + ")");
- }
- }
- else //regular recycle bin usage: available since XP
- {
- Zstring filenameDoubleNull;
- for (std::vector<Zstring>::const_iterator i = filesToDelete.begin(); i != filesToDelete.end(); ++i)
- {
- //#warning moving long file paths to recycler does not work! clarify!
- //filenameDoubleNull += removeLongPathPrefix(*i); //::SHFileOperation() can't handle \\?\-prefix!
- //You should use fully-qualified path names with this function. Using it with relative path names is not thread safe.
- filenameDoubleNull += *i; //::SHFileOperation() can't handle \\?\-prefix!
- filenameDoubleNull += L'\0';
- }
-
- SHFILEOPSTRUCT fileOp = {};
- fileOp.hwnd = NULL;
- fileOp.wFunc = FO_DELETE;
- fileOp.pFrom = filenameDoubleNull.c_str();
- fileOp.pTo = NULL;
- fileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NOERRORUI;
- fileOp.fAnyOperationsAborted = false;
- fileOp.hNameMappings = NULL;
- fileOp.lpszProgressTitle = NULL;
-
- if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted)
- {
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filenameDoubleNull + "\""); //report first file only... better than nothing
- }
- }
-}
-#endif
-}
-
-
-bool zen::moveToRecycleBin(const Zstring& filename) //throw FileError
-{
- if (!somethingExists(filename))
- return false; //neither file nor any other object with that name existing: no error situation, manual deletion relies on it!
-
-#ifdef FFS_WIN
- //::SetFileAttributes(applyLongPathPrefix(filename).c_str(), FILE_ATTRIBUTE_NORMAL);
- //both SHFileOperation and IFileOperation are not able to delete a folder named "System Volume Information" with normal attributes but shamelessly report success
-
- std::vector<Zstring> fileNames;
- fileNames.push_back(filename);
- ::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:") + "\n\"" + filename + "\"" +
- "\n\n" + "(unknown error)");
- }
- catch (const Glib::Error& errorObj)
- {
- //implement same behavior as in Windows: if recycler is not existing, delete permanently
- if (errorObj.code() == G_IO_ERROR_NOT_SUPPORTED)
- {
- struct stat fileInfo = {};
- if (::lstat(filename.c_str(), &fileInfo) != 0)
- return false;
-
- if (S_ISLNK(fileInfo.st_mode) || S_ISREG(fileInfo.st_mode))
- removeFile(filename); //throw FileError
- else if (S_ISDIR(fileInfo.st_mode))
- removeDirectory(filename); //throw FileError
- return true;
- }
-
- //assemble error message
- const std::wstring errorMessage = L"Glib Error Code " + toString<std::wstring>(errorObj.code()) + /* ", " +
- g_quark_to_string(errorObj.domain()) + */ ": " + errorObj.what();
-
- throw FileError(_("Error moving to Recycle Bin:") + "\n\"" + filename + "\"" +
- "\n\n" + "(" + errorMessage + ")");
- }
-#endif
- return true;
-}
-
-
-#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
- {
- Zstring rootPath = &buffer[0];
- if (!endsWith(rootPath, FILE_NAME_SEPARATOR)) //a trailing backslash is required
- rootPath += FILE_NAME_SEPARATOR;
-
- SHQUERYRBINFO recInfo = {};
- recInfo.cbSize = sizeof(recInfo);
- HRESULT rv = ::SHQueryRecycleBin(rootPath.c_str(), //__in_opt LPCTSTR pszRootPath,
- &recInfo); //__inout LPSHQUERYRBINFO pSHQueryRBInfo
- return rv == S_OK ? STATUS_REC_EXISTS : STATUS_REC_MISSING;
- }
- return STATUS_REC_UNKNOWN;
-}
-#elif defined FFS_LINUX
-/*
-We really need access to a similar function to check whether a directory supports trashing and emit a warning if it does not!
-
-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);
- 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
- http://www.netmite.com/android/mydroid/2.0/external/bluetooth/glib/gio/glocalfileinfo.c
-
- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH,
- writable && parent_info->has_trash_dir);
-
- => We're NOT interested in whether the specified folder can be trashed, but whether it supports thrashing its child elements! (Only support, not actual write access!)
- This renders G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH useless for this purpose.
-*/
-#endif
bgstack15