diff ui/installwrapper.cpp @ 310:f758460ca437

Merged
author Sascha Wilde <wilde@intevation.de>
date Fri, 04 Apr 2014 09:54:19 +0200
parents f23e0ccd5d14
children dc4efb0a70cb
line wrap: on
line diff
--- a/ui/installwrapper.cpp	Fri Apr 04 09:53:55 2014 +0200
+++ b/ui/installwrapper.cpp	Fri Apr 04 09:54:19 2014 +0200
@@ -8,6 +8,8 @@
 
 #include "logging.h"
 
+#define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */
+
 InstallWrapper::InstallWrapper(QObject* parent,
         const QString& path, const QStringList& instructions):
     QThread(parent),
@@ -27,32 +29,26 @@
 }
 
 #ifdef WIN32
-extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
-
 void InstallWrapper::run()
 {
+    /* TODO: We need errorcodes here so that we can see if a user
+     * cancled the UAC elevation */
     QTemporaryFile instructionsFile;
     QFileInfo cinstProcInfo = getCinstProcInfo();
+    DWORD retval = 0;
+    SHELLEXECUTEINFOW shExecInfo;
+    memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
 
     QString cinstFileName = QDir::toNativeSeparators(
             getCinstProcInfo().absoluteFilePath());
 
     if (!cinstProcInfo.isExecutable()) {
-        emit error (tr("Could not find certificate installation process."));
+        emit error(tr("Could not find certificate installation process."));
         return;
     }
 
     instructionsFile.open();
 
-    qt_ntfs_permission_lookup++;
-    if (instructionsFile.permissions() ^ (
-                QFileDevice::ReadUser |
-                QFileDevice::WriteUser |
-                QFileDevice::ReadOwner |
-                QFileDevice::WriteOwner)) {
-        emit error (tr("Invalid permissions on temporary file."));
-    }
-
     foreach (const QString &b64data, mInstructions) {
        instructionsFile.write(b64data.toLatin1());
        instructionsFile.write("\n");
@@ -60,25 +56,56 @@
 
     instructionsFile.close();
 
-    QString parameters = "\"" + mCertListFile + "\" \"" +instructionsFile.fileName() + "\"";
+    QString parameters = "\"list=" + mCertListFile + 
+        "\" \"instructions=" +instructionsFile.fileName() + "\"";
 
-    memset (&mExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
-    mExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
-    mExecInfo.fMask = SEE_MASK_FLAG_NO_UI |
-                      SEE_MASK_NOASYNC;
-    mExecInfo.lpVerb = L"runas";
-    mExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16());
-    mExecInfo.lpParameters =  reinterpret_cast<LPCWSTR> (parameters.utf16());
+    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
+    shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+    shExecInfo.lpVerb = L"runas";
+    shExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16());
+    shExecInfo.lpParameters =  reinterpret_cast<LPCWSTR> (parameters.utf16());
 
     qDebug() << "Starting process " << cinstFileName <<" params: " << parameters;
 
-    if (!ShellExecuteExW(&mExecInfo)) {
+    if (!ShellExecuteExW(&shExecInfo)) {
         char* errmsg = getLastErrorMsg();
         QString qerrmsg = QString::fromUtf8(errmsg);
         free(errmsg);
-        emit(tr("Error executing process: %1").arg(qerrmsg));
+        emit error(tr("Error executing process: %1").arg(qerrmsg));
+        return;
     }
-    qt_ntfs_permission_lookup--;
+
+    retval = WaitForSingleObject(shExecInfo.hProcess, INSTALL_TIMEOUT);
+
+    if (retval != WAIT_OBJECT_0) {
+        if (retval == WAIT_FAILED) {
+            char* errmsg = getLastErrorMsg();
+            QString qerrmsg = QString::fromUtf8(errmsg);
+            free(errmsg);
+            emit error (tr("Error monitoring process: %1").arg(qerrmsg));
+            return;
+        } else {
+            emit error (tr("Certificate installation timed out."));
+            return;
+        }
+    }
+
+    if (GetExitCodeProcess(shExecInfo.hProcess, &retval)) {
+        if (retval == STILL_ACTIVE) {
+            qDebug() << "Process still running, huh..";
+        }
+    } else {
+        char* errmsg = getLastErrorMsg();
+        QString qerrmsg = QString::fromUtf8(errmsg);
+        free(errmsg);
+        emit error (tr("Failed to check process status: %1").arg(qerrmsg));
+    }
+    CloseHandle(shExecInfo.hProcess);
+
+    if (retval != 0) {
+        /* TODO make this nicer */
+        emit error (tr("The process failed with return code. %1").arg(retval));
+    }
 }
 #else
 void InstallWrapper::run()

http://wald.intevation.org/projects/trustbridge/