# HG changeset patch # User Andre Heinecke # Date 1396349526 0 # Node ID 84ae353688e0841ddf2f88601ef475cb41c9bf44 # Parent c82dab1824bee14fbb729fe50471e36217e3b973 Add installwrapper class to handle process communication diff -r c82dab1824be -r 84ae353688e0 ui/installwrapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/installwrapper.cpp Tue Apr 01 10:52:06 2014 +0000 @@ -0,0 +1,87 @@ +#include "installwrapper.h" + +#include +#include +#include +#include +#include + +#include "logging.h" + +InstallWrapper::InstallWrapper(QObject* parent, + const QString& path, const QStringList& instructions): + QThread(parent), + mCertListFile(path), + mInstructions(instructions) +{ +} + +QFileInfo getCinstProcInfo() { + QFileInfo fi(QCoreApplication::applicationFilePath()); + QDir myDir = fi.absoluteDir(); + QString instProcName = "cinst"; + if (!fi.suffix().isEmpty()) { + instProcName += "." + fi.suffix(); + } + return QFileInfo(myDir.absoluteFilePath(instProcName)); +} + +#ifdef WIN32 +extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; + +void InstallWrapper::run() +{ + QTemporaryFile instructionsFile; + QFileInfo cinstProcInfo = getCinstProcInfo(); + + QString cinstFileName = QDir::toNativeSeparators( + getCinstProcInfo().absoluteFilePath()); + + if (!cinstProcInfo.isExecutable()) { + 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"); + } + + instructionsFile.close(); + + QString parameters = "\"" + mCertListFile + "\" \"" +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 (cinstFileName.utf16()); + mExecInfo.lpParameters = reinterpret_cast (parameters.utf16()); + + qDebug() << "Starting process " << cinstFileName <<" params: " << parameters; + + if (!ShellExecuteExW(&mExecInfo)) { + char* errmsg = getLastErrorMsg(); + QString qerrmsg = QString::fromUtf8(errmsg); + free(errmsg); + emit(tr("Error executing process: %1").arg(qerrmsg)); + } + qt_ntfs_permission_lookup--; +} +#else +void InstallWrapper::run() +{ +} +#endif diff -r c82dab1824be -r 84ae353688e0 ui/installwrapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/installwrapper.h Tue Apr 01 10:52:06 2014 +0000 @@ -0,0 +1,66 @@ +#ifndef UI_INSTALLWRAPPER_H +#define UI_INSTALLWRAPPER_H + +#include +#include +#include +#include + +#include "certificate.h" +/** @file installwrapper.h + * @brief Wrapper around the call to the updated process */ + + /** @brief wrapper around installer process + * + * This wrapper is mostly needed because QProcess executes + * a process on Windows directly with CreateProcess and + * thus can not be used to elevate the Process. + * + * On Windows this class uses ShellExecuteExW to control + * the child process. On Linux systems QProcess is used. + * + * It subclasses QThread so the installation can be done + * asynchronusly. */ +class InstallWrapper : public QThread +{ + Q_OBJECT + +public: + /** + * @brief Construct an installwrapper for a certificateList + * + * The install wrapper will start the cinst process to execute + * the specified instructions with the provided certificatelist. + * + * The cinst executable is expected to be in the same directory + * as the current application. + * + * @param[in] parent the parent object. + * @param[in] listFileName the absolute path to the certificatelist. + * @param[in] instructions a list of instructions to execute. + */ + InstallWrapper(QObject* parent, const QString& path, + const QStringList& instructions); + +private: + const QString mCertListFile; + const QStringList mInstructions; +#ifdef WIN32 + SHELLEXECUTEINFOW mExecInfo; +#else + QProcess cinstProc; +#endif + +protected: + void run(); + +Q_SIGNALS: + /** + * @brief An error happened + * + * @param[out] message: A localized message to show. Can be empty. + */ + void error(const QString &message); +}; + +#endif // UI_INSTALLWRAPPER_H