GH-228 do not recurse into reparse points when deleting instances

This commit is contained in:
Petr Mrázek 2015-04-07 22:24:15 +02:00
parent 0220fe4f9d
commit c7398dfdc5
4 changed files with 69 additions and 2 deletions

View File

@ -51,8 +51,16 @@ LIBUTIL_EXPORT bool ensureFilePathExists(QString filenamepath);
*/ */
LIBUTIL_EXPORT bool ensureFolderPathExists(QString filenamepath); LIBUTIL_EXPORT bool ensureFolderPathExists(QString filenamepath);
/**
* Copy a folder recursively
*/
LIBUTIL_EXPORT bool copyPath(QString src, QString dst, bool follow_symlinks = true); 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. /// Opens the given file in the default application.
LIBUTIL_EXPORT void openFileInDefaultProgram(QString filename); LIBUTIL_EXPORT void openFileInDefaultProgram(QString filename);

View File

@ -152,6 +152,65 @@ bool copyPath(QString src, QString dst, bool follow_symlinks)
} }
return OK; 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) void openDirInDefaultProgram(QString path, bool ensureExists)
{ {

View File

@ -61,7 +61,7 @@ void BaseInstance::iconUpdated(QString key)
void BaseInstance::nuke() void BaseInstance::nuke()
{ {
QDir(instanceRoot()).removeRecursively(); deletePath(instanceRoot());
emit nuked(this); emit nuked(this);
} }

View File

@ -503,7 +503,7 @@ InstanceList::copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance, c
qDebug() << instDir.toUtf8(); qDebug() << instDir.toUtf8();
if (!copyPath(oldInstance->instanceRoot(), instDir, false)) if (!copyPath(oldInstance->instanceRoot(), instDir, false))
{ {
rootDir.removeRecursively(); deletePath(instDir);
return InstanceList::CantCreateDir; return InstanceList::CantCreateDir;
} }