comparison ui/installwrapper.cpp @ 285:f23e0ccd5d14

Fix call to windows process. This now uses the correct parameters, emits the signals correctly as errors and waits for the process to finish instead of relying on NOASYNC which did not work for runas and also made it impossible to get the return code
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 02 Apr 2014 13:45:57 +0000
parents 84ae353688e0
children dc4efb0a70cb
comparison
equal deleted inserted replaced
284:a0c5eba8eb41 285:f23e0ccd5d14
5 #include <QApplication> 5 #include <QApplication>
6 #include <QDir> 6 #include <QDir>
7 #include <QDebug> 7 #include <QDebug>
8 8
9 #include "logging.h" 9 #include "logging.h"
10
11 #define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */
10 12
11 InstallWrapper::InstallWrapper(QObject* parent, 13 InstallWrapper::InstallWrapper(QObject* parent,
12 const QString& path, const QStringList& instructions): 14 const QString& path, const QStringList& instructions):
13 QThread(parent), 15 QThread(parent),
14 mCertListFile(path), 16 mCertListFile(path),
25 } 27 }
26 return QFileInfo(myDir.absoluteFilePath(instProcName)); 28 return QFileInfo(myDir.absoluteFilePath(instProcName));
27 } 29 }
28 30
29 #ifdef WIN32 31 #ifdef WIN32
30 extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
31
32 void InstallWrapper::run() 32 void InstallWrapper::run()
33 { 33 {
34 /* TODO: We need errorcodes here so that we can see if a user
35 * cancled the UAC elevation */
34 QTemporaryFile instructionsFile; 36 QTemporaryFile instructionsFile;
35 QFileInfo cinstProcInfo = getCinstProcInfo(); 37 QFileInfo cinstProcInfo = getCinstProcInfo();
38 DWORD retval = 0;
39 SHELLEXECUTEINFOW shExecInfo;
40 memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
36 41
37 QString cinstFileName = QDir::toNativeSeparators( 42 QString cinstFileName = QDir::toNativeSeparators(
38 getCinstProcInfo().absoluteFilePath()); 43 getCinstProcInfo().absoluteFilePath());
39 44
40 if (!cinstProcInfo.isExecutable()) { 45 if (!cinstProcInfo.isExecutable()) {
41 emit error (tr("Could not find certificate installation process.")); 46 emit error(tr("Could not find certificate installation process."));
42 return; 47 return;
43 } 48 }
44 49
45 instructionsFile.open(); 50 instructionsFile.open();
46
47 qt_ntfs_permission_lookup++;
48 if (instructionsFile.permissions() ^ (
49 QFileDevice::ReadUser |
50 QFileDevice::WriteUser |
51 QFileDevice::ReadOwner |
52 QFileDevice::WriteOwner)) {
53 emit error (tr("Invalid permissions on temporary file."));
54 }
55 51
56 foreach (const QString &b64data, mInstructions) { 52 foreach (const QString &b64data, mInstructions) {
57 instructionsFile.write(b64data.toLatin1()); 53 instructionsFile.write(b64data.toLatin1());
58 instructionsFile.write("\n"); 54 instructionsFile.write("\n");
59 } 55 }
60 56
61 instructionsFile.close(); 57 instructionsFile.close();
62 58
63 QString parameters = "\"" + mCertListFile + "\" \"" +instructionsFile.fileName() + "\""; 59 QString parameters = "\"list=" + mCertListFile +
60 "\" \"instructions=" +instructionsFile.fileName() + "\"";
64 61
65 memset (&mExecInfo, 0, sizeof(SHELLEXECUTEINFOW)); 62 shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
66 mExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW); 63 shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
67 mExecInfo.fMask = SEE_MASK_FLAG_NO_UI | 64 shExecInfo.lpVerb = L"runas";
68 SEE_MASK_NOASYNC; 65 shExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16());
69 mExecInfo.lpVerb = L"runas"; 66 shExecInfo.lpParameters = reinterpret_cast<LPCWSTR> (parameters.utf16());
70 mExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16());
71 mExecInfo.lpParameters = reinterpret_cast<LPCWSTR> (parameters.utf16());
72 67
73 qDebug() << "Starting process " << cinstFileName <<" params: " << parameters; 68 qDebug() << "Starting process " << cinstFileName <<" params: " << parameters;
74 69
75 if (!ShellExecuteExW(&mExecInfo)) { 70 if (!ShellExecuteExW(&shExecInfo)) {
76 char* errmsg = getLastErrorMsg(); 71 char* errmsg = getLastErrorMsg();
77 QString qerrmsg = QString::fromUtf8(errmsg); 72 QString qerrmsg = QString::fromUtf8(errmsg);
78 free(errmsg); 73 free(errmsg);
79 emit(tr("Error executing process: %1").arg(qerrmsg)); 74 emit error(tr("Error executing process: %1").arg(qerrmsg));
75 return;
80 } 76 }
81 qt_ntfs_permission_lookup--; 77
78 retval = WaitForSingleObject(shExecInfo.hProcess, INSTALL_TIMEOUT);
79
80 if (retval != WAIT_OBJECT_0) {
81 if (retval == WAIT_FAILED) {
82 char* errmsg = getLastErrorMsg();
83 QString qerrmsg = QString::fromUtf8(errmsg);
84 free(errmsg);
85 emit error (tr("Error monitoring process: %1").arg(qerrmsg));
86 return;
87 } else {
88 emit error (tr("Certificate installation timed out."));
89 return;
90 }
91 }
92
93 if (GetExitCodeProcess(shExecInfo.hProcess, &retval)) {
94 if (retval == STILL_ACTIVE) {
95 qDebug() << "Process still running, huh..";
96 }
97 } else {
98 char* errmsg = getLastErrorMsg();
99 QString qerrmsg = QString::fromUtf8(errmsg);
100 free(errmsg);
101 emit error (tr("Failed to check process status: %1").arg(qerrmsg));
102 }
103 CloseHandle(shExecInfo.hProcess);
104
105 if (retval != 0) {
106 /* TODO make this nicer */
107 emit error (tr("The process failed with return code. %1").arg(retval));
108 }
82 } 109 }
83 #else 110 #else
84 void InstallWrapper::run() 111 void InstallWrapper::run()
85 { 112 {
86 } 113 }

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