annotate 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
rev   line source
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
1 #include "installwrapper.h"
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
2
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
3 #include <QFileInfo>
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
4 #include <QTemporaryFile>
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
5 #include <QApplication>
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
6 #include <QDir>
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
7 #include <QDebug>
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
8
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
9 #include "logging.h"
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
10
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
11 #define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
12
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
13 InstallWrapper::InstallWrapper(QObject* parent,
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
14 const QString& path, const QStringList& instructions):
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
15 QThread(parent),
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
16 mCertListFile(path),
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
17 mInstructions(instructions)
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
18 {
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
19 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
20
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
21 QFileInfo getCinstProcInfo() {
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
22 QFileInfo fi(QCoreApplication::applicationFilePath());
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
23 QDir myDir = fi.absoluteDir();
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
24 QString instProcName = "cinst";
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
25 if (!fi.suffix().isEmpty()) {
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
26 instProcName += "." + fi.suffix();
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
27 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
28 return QFileInfo(myDir.absoluteFilePath(instProcName));
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
29 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
30
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
31 #ifdef WIN32
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
32 void InstallWrapper::run()
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
33 {
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
34 /* TODO: We need errorcodes here so that we can see if a user
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
35 * cancled the UAC elevation */
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
36 QTemporaryFile instructionsFile;
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
37 QFileInfo cinstProcInfo = getCinstProcInfo();
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
38 DWORD retval = 0;
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
39 SHELLEXECUTEINFOW shExecInfo;
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
40 memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
41
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
42 QString cinstFileName = QDir::toNativeSeparators(
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
43 getCinstProcInfo().absoluteFilePath());
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
44
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
45 if (!cinstProcInfo.isExecutable()) {
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
46 emit error(tr("Could not find certificate installation process."));
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
47 return;
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
48 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
49
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
50 instructionsFile.open();
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
51
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
52 foreach (const QString &b64data, mInstructions) {
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
53 instructionsFile.write(b64data.toLatin1());
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
54 instructionsFile.write("\n");
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
55 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
56
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
57 instructionsFile.close();
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
58
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
59 QString parameters = "\"list=" + mCertListFile +
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
60 "\" \"instructions=" +instructionsFile.fileName() + "\"";
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
61
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
62 shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
63 shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
64 shExecInfo.lpVerb = L"runas";
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
65 shExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16());
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
66 shExecInfo.lpParameters = reinterpret_cast<LPCWSTR> (parameters.utf16());
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
67
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
68 qDebug() << "Starting process " << cinstFileName <<" params: " << parameters;
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
69
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
70 if (!ShellExecuteExW(&shExecInfo)) {
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
71 char* errmsg = getLastErrorMsg();
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
72 QString qerrmsg = QString::fromUtf8(errmsg);
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
73 free(errmsg);
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
74 emit error(tr("Error executing process: %1").arg(qerrmsg));
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
75 return;
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
76 }
285
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
77
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
78 retval = WaitForSingleObject(shExecInfo.hProcess, INSTALL_TIMEOUT);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
79
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
80 if (retval != WAIT_OBJECT_0) {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
81 if (retval == WAIT_FAILED) {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
82 char* errmsg = getLastErrorMsg();
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
83 QString qerrmsg = QString::fromUtf8(errmsg);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
84 free(errmsg);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
85 emit error (tr("Error monitoring process: %1").arg(qerrmsg));
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
86 return;
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
87 } else {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
88 emit error (tr("Certificate installation timed out."));
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
89 return;
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
90 }
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
91 }
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
92
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
93 if (GetExitCodeProcess(shExecInfo.hProcess, &retval)) {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
94 if (retval == STILL_ACTIVE) {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
95 qDebug() << "Process still running, huh..";
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
96 }
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
97 } else {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
98 char* errmsg = getLastErrorMsg();
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
99 QString qerrmsg = QString::fromUtf8(errmsg);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
100 free(errmsg);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
101 emit error (tr("Failed to check process status: %1").arg(qerrmsg));
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
102 }
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
103 CloseHandle(shExecInfo.hProcess);
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
104
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
105 if (retval != 0) {
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
106 /* TODO make this nicer */
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
107 emit error (tr("The process failed with return code. %1").arg(retval));
f23e0ccd5d14 Fix call to windows process.
Andre Heinecke <aheinecke@intevation.de>
parents: 256
diff changeset
108 }
256
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
109 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
110 #else
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
111 void InstallWrapper::run()
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
112 {
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
113 }
84ae353688e0 Add installwrapper class to handle process communication
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
114 #endif

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