summaryrefslogtreecommitdiffstats
path: root/src/libs/kdtools
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@nokia.com>2012-04-25 14:14:56 +0200
committerTim Jenssen <tim.jenssen@nokia.com>2012-04-27 16:23:20 +0200
commit0a8755ace26f1174e9ed99e5060c4d8da0ba010d (patch)
tree7d73b3e0151b06707d8b9df5cef25be7203a420f /src/libs/kdtools
parentff6179ea53debd66e63738382b3af62087b81af7 (diff)
now installer can disallow to install from a remote location
- at the moment the implementation is windows only - in some cases it is problematically to install big installers from a remote location: if the connection is lost -> crash - the installer itself can have the flag DependsOnLocalInstallerBinary in the config.xml file - or a component can request that installer.setDependsOnLocalInstallerBinary() Change-Id: I0c8d70ca89dd55d2d0c52bf3418f11c95b5290a1 Reviewed-by: Oliver Wolff <oliver.wolff@nokia.com> Reviewed-by: Karsten Heimrich <karsten.heimrich@nokia.com>
Diffstat (limited to 'src/libs/kdtools')
-rw-r--r--src/libs/kdtools/kdsysinfo.h3
-rw-r--r--src/libs/kdtools/kdsysinfo_win.cpp123
2 files changed, 124 insertions, 2 deletions
diff --git a/src/libs/kdtools/kdsysinfo.h b/src/libs/kdtools/kdsysinfo.h
index 6c8079fcd..810e3dbc1 100644
--- a/src/libs/kdtools/kdsysinfo.h
+++ b/src/libs/kdtools/kdsysinfo.h
@@ -70,6 +70,9 @@ struct ProcessInfo
quint64 installedMemory();
QList<VolumeInfo> mountedVolumes();
QList<ProcessInfo> runningProcesses();
+#ifdef Q_OS_WIN
+bool pathIsOnLocalDevice(const QString &path);
+#endif
} // namespace KDUpdater
diff --git a/src/libs/kdtools/kdsysinfo_win.cpp b/src/libs/kdtools/kdsysinfo_win.cpp
index 45342aee5..92d87d680 100644
--- a/src/libs/kdtools/kdsysinfo_win.cpp
+++ b/src/libs/kdtools/kdsysinfo_win.cpp
@@ -29,8 +29,9 @@
#include <Winnetwk.h>
#pragma comment(lib, "mpr.lib")
-#include <QtCore/QDir>
-#include <QtCore/QLibrary>
+#include <QDebug>
+#include <QDir>
+#include <QLibrary>
const int KDSYSINFO_PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
@@ -209,4 +210,122 @@ QList<ProcessInfo> runningProcesses()
return param.processes;
}
+// REPARSE_DATA_BUFFER structure from msdn help: http://msdn.microsoft.com/en-us/library/ff552012.aspx
+typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+QString junctionTargetPath(const QString &path)
+{
+ HANDLE fileHandle;
+ fileHandle = CreateFile(path.utf16(), FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_FLAG_OPEN_REPARSE_POINT, NULL);
+ if (fileHandle == INVALID_HANDLE_VALUE) {
+ qDebug() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(path).arg(GetLastError());
+ return path;
+ }
+
+ REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+
+ DWORD bytesReturned;
+ // fill the reparseStructData
+ BOOL isOk = DeviceIoControl(fileHandle, FSCTL_GET_REPARSE_POINT, NULL, 0, reparseStructData,
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, NULL);
+ if (isOk == FALSE) {
+ DWORD deviceIOControlError = GetLastError();
+ if (deviceIOControlError == ERROR_NOT_A_REPARSE_POINT)
+ qDebug() << QString::fromLatin1("Could not reparse information (windows symlink) for %1").arg(path);
+ else {
+ qDebug() << QString::fromLatin1("Get DeviceIoControl for %1 failed with error: %2").arg(
+ path).arg(deviceIOControlError);
+ }
+ CloseHandle(fileHandle);
+ return path;
+ }
+ CloseHandle(fileHandle);
+
+ QString realPath = path;
+ if (IsReparseTagMicrosoft(reparseStructData->ReparseTag)) {
+ size_t realPathLength = 0;
+ WCHAR *realPathWCHAR = 0;
+ if (reparseStructData->ReparseTag == IO_REPARSE_TAG_SYMLINK){
+ realPathLength = reparseStructData->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
+ realPathWCHAR = new WCHAR[realPathLength + 1];
+ wcsncpy_s(realPathWCHAR, realPathLength + 1, &reparseStructData->SymbolicLinkReparseBuffer.PathBuffer[
+ reparseStructData->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], realPathLength);
+ } else if (reparseStructData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+ realPathLength = reparseStructData->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
+ realPathWCHAR = new WCHAR[realPathLength + 1];
+ wcsncpy_s(realPathWCHAR, realPathLength + 1, &reparseStructData->MountPointReparseBuffer.PathBuffer[
+ reparseStructData->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)], realPathLength);
+ } else {
+ qDebug() << QString::fromLatin1("Path %1 is not a symlink and not a mount point.").arg(path);
+ }
+ if (realPathLength != 0) {
+ realPathWCHAR[realPathLength] = 0;
+ realPath = QString::fromStdWString(realPathWCHAR);
+ delete [] realPathWCHAR;
+ }
+
+ } else {
+ qDebug() << QString::fromLatin1("Path %1 is not reparse point.").arg(path);
+ }
+ free(reparseStructData);
+ return realPath;
+}
+
+bool pathIsOnLocalDevice(const QString &path)
+{
+ if (!QFileInfo(path).exists())
+ return false;
+
+ if (path.startsWith(QLatin1String("\\\\")))
+ return false;
+
+ QDir dir(path);
+ do {
+ if (QFileInfo(dir, QString()).isSymLink()) {
+ QString currentPath = QFileInfo(dir, QString()).absoluteFilePath();
+ return pathIsOnLocalDevice(junctionTargetPath(currentPath));
+ }
+ } while (dir.cdUp());
+
+ const UINT DRIVE_REMOTE_TYPE = 4;
+ if (path.contains(QLatin1Char(':'))) {
+ const QLatin1Char nullTermination('\0');
+ // for example "c:\"
+ const QString driveSearchString = path.left(3) + nullTermination;
+ WCHAR wCharDriveSearchArray[4];
+ driveSearchString.toWCharArray(wCharDriveSearchArray);
+ UINT type = GetDriveType(wCharDriveSearchArray);
+ if (type == DRIVE_REMOTE_TYPE)
+ return false;
+ }
+
+ return true;
+}
+
} // namespace KDUpdater