Refactor createSymbolicLink() and createNtfsJunction()
Both functions now return a result object. Eliminates the need to pass the errorMessage out-parameter. Adapt auto-tests. Change-Id: I110b68fedc67b01f76796c44fa55383b2cc03460 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
ebacf42561
commit
01f003f0aa
@ -715,12 +715,11 @@ void tst_QFileInfo::canonicalFilePath()
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
{
|
||||
QString errorMessage;
|
||||
const QString linkTarget = QStringLiteral("res");
|
||||
const DWORD dwErr = FileSystem::createSymbolicLink(linkTarget, m_resourcesDir, &errorMessage);
|
||||
if (dwErr == ERROR_PRIVILEGE_NOT_HELD)
|
||||
QSKIP(msgInsufficientPrivileges(errorMessage));
|
||||
QVERIFY2(dwErr == ERROR_SUCCESS, qPrintable(errorMessage));
|
||||
const auto result = FileSystem::createSymbolicLink(linkTarget, m_resourcesDir);
|
||||
if (result.dwErr == ERROR_PRIVILEGE_NOT_HELD)
|
||||
QSKIP(msgInsufficientPrivileges(result.errorMessage));
|
||||
QVERIFY2(result.dwErr == ERROR_SUCCESS, qPrintable(result.errorMessage));
|
||||
QString currentPath = QDir::currentPath();
|
||||
QVERIFY(QDir::setCurrent(linkTarget));
|
||||
const QString actualCanonicalPath = QFileInfo("file1").canonicalFilePath();
|
||||
@ -1359,12 +1358,11 @@ void tst_QFileInfo::isSymbolicLink_data()
|
||||
|
||||
#ifndef Q_NO_SYMLINKS
|
||||
#if defined(Q_OS_WIN)
|
||||
QString errorMessage;
|
||||
const DWORD creationResult = FileSystem::createSymbolicLink("symlink", m_sourceFile, &errorMessage);
|
||||
if (creationResult == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
QWARN(msgInsufficientPrivileges(errorMessage));
|
||||
const auto creationResult = FileSystem::createSymbolicLink("symlink", m_sourceFile);
|
||||
if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
QWARN(msgInsufficientPrivileges(creationResult.errorMessage));
|
||||
} else {
|
||||
QVERIFY2(creationResult == ERROR_SUCCESS, qPrintable(errorMessage));
|
||||
QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
|
||||
QTest::newRow("NTFS-symlink")
|
||||
<< "symlink" << true;
|
||||
}
|
||||
@ -1423,21 +1421,20 @@ void tst_QFileInfo::link_data()
|
||||
|
||||
#ifndef Q_NO_SYMLINKS
|
||||
#if defined(Q_OS_WIN)
|
||||
QString errorMessage;
|
||||
DWORD creationResult = FileSystem::createSymbolicLink("link", m_sourceFile, &errorMessage);
|
||||
if (creationResult == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
QWARN(msgInsufficientPrivileges(errorMessage));
|
||||
auto creationResult = FileSystem::createSymbolicLink("link", m_sourceFile);
|
||||
if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
QWARN(msgInsufficientPrivileges(creationResult.errorMessage));
|
||||
} else {
|
||||
QVERIFY2(creationResult == ERROR_SUCCESS, qPrintable(errorMessage));
|
||||
QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
|
||||
QTest::newRow("link")
|
||||
<< "link" << false << true << QFileInfo(m_sourceFile).absoluteFilePath();
|
||||
}
|
||||
|
||||
creationResult = FileSystem::createSymbolicLink("brokenlink", "dummyfile", &errorMessage);
|
||||
if (creationResult == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
QWARN(msgInsufficientPrivileges(errorMessage));
|
||||
creationResult = FileSystem::createSymbolicLink("brokenlink", "dummyfile");
|
||||
if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD) {
|
||||
QWARN(msgInsufficientPrivileges(creationResult.errorMessage));
|
||||
} else {
|
||||
QVERIFY2(creationResult == ERROR_SUCCESS, qPrintable(errorMessage));
|
||||
QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
|
||||
QTest::newRow("broken link")
|
||||
<< "brokenlink" << false << true << QFileInfo("dummyfile").absoluteFilePath();
|
||||
}
|
||||
@ -1701,7 +1698,6 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
|
||||
{
|
||||
// Symlink to UNC share
|
||||
pwd.mkdir("unc");
|
||||
QString errorMessage;
|
||||
QString uncTarget = QStringLiteral("//") + QtNetworkSettings::winServerName() + "/testshare";
|
||||
QString uncSymlink = QDir::toNativeSeparators(pwd.absolutePath().append("\\unc\\link_to_unc"));
|
||||
QTest::newRow("UNC symlink")
|
||||
@ -1753,24 +1749,23 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks()
|
||||
QFETCH(QString, linkTarget);
|
||||
QFETCH(QString, canonicalFilePath);
|
||||
|
||||
QString errorMessage;
|
||||
DWORD creationResult = ERROR_SUCCESS;
|
||||
FileSystem::Result creationResult;
|
||||
switch (resource.type) {
|
||||
case NtfsTestResource::None:
|
||||
break;
|
||||
case NtfsTestResource::SymLink:
|
||||
creationResult = FileSystem::createSymbolicLink(resource.source, resource.target, &errorMessage);
|
||||
creationResult = FileSystem::createSymbolicLink(resource.source, resource.target);
|
||||
break;
|
||||
case NtfsTestResource::Junction:
|
||||
creationResult = FileSystem::createNtfsJunction(resource.target, resource.source, &errorMessage);
|
||||
if (creationResult == ERROR_NOT_SUPPORTED) // Special value indicating non-NTFS drive
|
||||
QSKIP(qPrintable(errorMessage));
|
||||
creationResult = FileSystem::createNtfsJunction(resource.target, resource.source);
|
||||
if (creationResult.dwErr == ERROR_NOT_SUPPORTED) // Special value indicating non-NTFS drive
|
||||
QSKIP(qPrintable(creationResult.errorMessage));
|
||||
break;
|
||||
}
|
||||
|
||||
if (creationResult == ERROR_PRIVILEGE_NOT_HELD)
|
||||
QSKIP(msgInsufficientPrivileges(errorMessage));
|
||||
QVERIFY2(creationResult == ERROR_SUCCESS, qPrintable(errorMessage));
|
||||
if (creationResult.dwErr == ERROR_PRIVILEGE_NOT_HELD)
|
||||
QSKIP(msgInsufficientPrivileges(creationResult.errorMessage));
|
||||
QVERIFY2(creationResult.dwErr == ERROR_SUCCESS, qPrintable(creationResult.errorMessage));
|
||||
|
||||
QFileInfo fi(path);
|
||||
auto guard = qScopeGuard([&fi, this]() {
|
||||
|
@ -94,9 +94,8 @@ void qfileinfo::symLinkTargetPerformanceMounpoint()
|
||||
QString rootVolume = QString::fromWCharArray(buffer);
|
||||
QString mountpoint = "mountpoint";
|
||||
rootVolume.replace("\\\\?\\","\\??\\");
|
||||
QString errorMessage;
|
||||
QVERIFY2(FileSystem::createNtfsJunction(rootVolume, mountpoint, &errorMessage) == ERROR_SUCCESS,
|
||||
qPrintable(errorMessage));
|
||||
const auto result = FileSystem::createNtfsJunction(rootVolume, mountpoint);
|
||||
QVERIFY2(result.dwErr == ERROR_SUCCESS, qPrintable(result.errorMessage));
|
||||
|
||||
QFileInfo info(mountpoint);
|
||||
info.setCaching(false);
|
||||
|
@ -83,10 +83,16 @@ public:
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
static DWORD createSymbolicLink(const QString &symLinkName, const QString &target,
|
||||
QString *errorMessage)
|
||||
struct Result {
|
||||
DWORD dwErr = ERROR_SUCCESS;
|
||||
QString link;
|
||||
QString target;
|
||||
QString errorMessage;
|
||||
};
|
||||
|
||||
static Result createSymbolicLink(const QString &symLinkName, const QString &target)
|
||||
{
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
Result result;
|
||||
const QString nativeSymLinkName = QDir::toNativeSeparators(symLinkName);
|
||||
const QString nativeTarget = QDir::toNativeSeparators(target);
|
||||
DWORD flags = 0;
|
||||
@ -96,15 +102,18 @@ public:
|
||||
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
|
||||
if (CreateSymbolicLink(reinterpret_cast<const wchar_t*>(nativeSymLinkName.utf16()),
|
||||
reinterpret_cast<const wchar_t*>(nativeTarget.utf16()), flags) == FALSE) {
|
||||
result = GetLastError();
|
||||
QTextStream(errorMessage) << "CreateSymbolicLink(" << nativeSymLinkName << ", "
|
||||
<< nativeTarget << ", 0x" << Qt::hex << flags << Qt::dec << ") failed with error " << result
|
||||
<< ": " << qt_error_string(int(result));
|
||||
result.dwErr = GetLastError();
|
||||
QTextStream(&result.errorMessage) << "CreateSymbolicLink(" << nativeSymLinkName << ", "
|
||||
<< nativeTarget << ", 0x" << Qt::hex << flags << Qt::dec << ") failed with error "
|
||||
<< result.dwErr << ": " << qt_error_string(int(result.dwErr));
|
||||
} else {
|
||||
result.link = nativeSymLinkName;
|
||||
result.target = nativeTarget;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static DWORD createNtfsJunction(QString target, QString linkName, QString *errorMessage)
|
||||
static Result createNtfsJunction(QString target, QString linkName)
|
||||
{
|
||||
typedef struct {
|
||||
DWORD ReparseTag;
|
||||
@ -121,7 +130,7 @@ public:
|
||||
DWORD returnedLength;
|
||||
wchar_t fileSystem[MAX_PATH] = L"";
|
||||
PREPARSE_MOUNTPOINT_DATA_BUFFER reparseInfo = (PREPARSE_MOUNTPOINT_DATA_BUFFER) reparseBuffer;
|
||||
DWORD result = ERROR_SUCCESS;
|
||||
Result result;
|
||||
|
||||
QFileInfo junctionInfo(linkName);
|
||||
linkName = QDir::toNativeSeparators(junctionInfo.absoluteFilePath());
|
||||
@ -129,13 +138,14 @@ public:
|
||||
if (GetVolumeInformationW(reinterpret_cast<const wchar_t *>(drive.utf16()),
|
||||
NULL, 0, NULL, NULL, NULL,
|
||||
fileSystem, sizeof(fileSystem)/sizeof(WCHAR)) == FALSE) {
|
||||
result = GetLastError();
|
||||
*errorMessage = "GetVolumeInformationW() failed: " + qt_error_string(int(result));
|
||||
result.dwErr = GetLastError();
|
||||
result.errorMessage = "GetVolumeInformationW() failed: " + qt_error_string(int(result.dwErr));
|
||||
return result;
|
||||
}
|
||||
if (QString::fromWCharArray(fileSystem) != "NTFS") {
|
||||
*errorMessage = "This seems not to be an NTFS volume. Junctions are not allowed.";
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
result.errorMessage = "This seems not to be an NTFS volume. Junctions are not allowed.";
|
||||
result.dwErr = ERROR_NOT_SUPPORTED;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!target.startsWith("\\??\\") && !target.startsWith("\\\\?\\")) {
|
||||
@ -149,8 +159,8 @@ public:
|
||||
hFile = CreateFileW( (wchar_t*)linkName.utf16(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL );
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
result = GetLastError();
|
||||
*errorMessage = "CreateFileW(" + linkName + ") failed: " + qt_error_string(int(result));
|
||||
result.dwErr = GetLastError();
|
||||
result.errorMessage = "CreateFileW(" + linkName + ") failed: " + qt_error_string(int(result.dwErr));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -165,8 +175,11 @@ public:
|
||||
reparseInfo->ReparseDataLength + REPARSE_MOUNTPOINT_HEADER_SIZE,
|
||||
NULL, 0, &returnedLength, NULL);
|
||||
if (!ioc) {
|
||||
result = GetLastError();
|
||||
*errorMessage = "DeviceIoControl() failed: " + qt_error_string(int(result));
|
||||
result.dwErr = GetLastError();
|
||||
result.errorMessage = "DeviceIoControl() failed: " + qt_error_string(int(result.dwErr));
|
||||
} else {
|
||||
result.link = linkName;
|
||||
result.target = target;
|
||||
}
|
||||
CloseHandle( hFile );
|
||||
return result;
|
||||
|
Loading…
x
Reference in New Issue
Block a user