summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2015-04-07 22:24:15 +0200
committerPetr Mrázek <peterix@gmail.com>2015-04-13 00:06:31 +0200
commitc7398dfdc581fbf36205fa826ad2aeadcd9b0122 (patch)
tree4aa331c389c2aa4c0148354d600b556b5073ffca
parent0220fe4f9d7f07fa137a11597b3465c76cfbcae3 (diff)
downloadMultiMC-c7398dfdc581fbf36205fa826ad2aeadcd9b0122.tar
MultiMC-c7398dfdc581fbf36205fa826ad2aeadcd9b0122.tar.gz
MultiMC-c7398dfdc581fbf36205fa826ad2aeadcd9b0122.tar.lz
MultiMC-c7398dfdc581fbf36205fa826ad2aeadcd9b0122.tar.xz
MultiMC-c7398dfdc581fbf36205fa826ad2aeadcd9b0122.zip
GH-228 do not recurse into reparse points when deleting instances
-rw-r--r--depends/util/include/pathutils.h8
-rw-r--r--depends/util/src/pathutils.cpp59
-rw-r--r--logic/BaseInstance.cpp2
-rw-r--r--logic/InstanceList.cpp2
4 files changed, 69 insertions, 2 deletions
diff --git a/depends/util/include/pathutils.h b/depends/util/include/pathutils.h
index a506280e..f31b96d1 100644
--- a/depends/util/include/pathutils.h
+++ b/depends/util/include/pathutils.h
@@ -51,8 +51,16 @@ LIBUTIL_EXPORT bool ensureFilePathExists(QString filenamepath);
*/
LIBUTIL_EXPORT bool ensureFolderPathExists(QString filenamepath);
+/**
+ * Copy a folder recursively
+ */
LIBUTIL_EXPORT bool copyPath(QString src, QString dst, bool follow_symlinks = true);
+/**
+ * Delete a folder recursively
+ */
+LIBUTIL_EXPORT bool deletePath(QString path);
+
/// Opens the given file in the default application.
LIBUTIL_EXPORT void openFileInDefaultProgram(QString filename);
diff --git a/depends/util/src/pathutils.cpp b/depends/util/src/pathutils.cpp
index 1cbb2cb2..ce9138be 100644
--- a/depends/util/src/pathutils.cpp
+++ b/depends/util/src/pathutils.cpp
@@ -152,6 +152,65 @@ bool copyPath(QString src, QString dst, bool follow_symlinks)
}
return OK;
}
+#if defined Q_OS_WIN32
+#include <windows.h>
+#include <string>
+#endif
+bool deletePath(QString path)
+{
+ bool OK = true;
+ QDir dir(path);
+
+ if (!dir.exists())
+ {
+ return OK;
+ }
+ auto allEntries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
+ QDir::AllDirs | QDir::Files,
+ QDir::DirsFirst);
+
+ for(QFileInfo info: allEntries)
+ {
+#if defined Q_OS_WIN32
+ QString nativePath = QDir::toNativeSeparators(info.absoluteFilePath());
+ auto wString = nativePath.toStdWString();
+ DWORD dwAttrs = GetFileAttributesW(wString.c_str());
+ // Windows: check for junctions, reparse points and other nasty things of that sort
+ if(dwAttrs & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ if (info.isFile())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+ else if (info.isDir())
+ {
+ OK &= dir.rmdir(info.absoluteFilePath());
+ }
+ }
+#else
+ // We do not trust Qt with reparse points, but do trust it with unix symlinks.
+ if(info.isSymLink())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+#endif
+ else if (info.isDir())
+ {
+ OK &= deletePath(info.absoluteFilePath());
+ }
+ else if (info.isFile())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+ else
+ {
+ OK = false;
+ qCritical() << "Delete ERROR: Unknown filesystem object:" << info.absoluteFilePath();
+ }
+ }
+ OK &= dir.rmdir(dir.absolutePath());
+ return OK;
+}
void openDirInDefaultProgram(QString path, bool ensureExists)
{
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp
index 69bc7597..1c6d3e4b 100644
--- a/logic/BaseInstance.cpp
+++ b/logic/BaseInstance.cpp
@@ -61,7 +61,7 @@ void BaseInstance::iconUpdated(QString key)
void BaseInstance::nuke()
{
- QDir(instanceRoot()).removeRecursively();
+ deletePath(instanceRoot());
emit nuked(this);
}
diff --git a/logic/InstanceList.cpp b/logic/InstanceList.cpp
index 4e295e7f..3bdceb51 100644
--- a/logic/InstanceList.cpp
+++ b/logic/InstanceList.cpp
@@ -503,7 +503,7 @@ InstanceList::copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance, c
qDebug() << instDir.toUtf8();
if (!copyPath(oldInstance->instanceRoot(), instDir, false))
{
- rootDir.removeRecursively();
+ deletePath(instDir);
return InstanceList::CantCreateDir;
}