diff --git a/Application.cpp b/Application.cpp index dc03350..a02dfd1 100644 --- a/Application.cpp +++ b/Application.cpp @@ -37,6 +37,8 @@ #include #include +#include + using namespace Qt::StringLiterals; int main( int argc, char *argv[] ) @@ -53,8 +55,8 @@ Application::Application( int &argc, char **argv ) if( log.exists() && log.open( QFile::WriteOnly|QFile::Append ) ) qInstallMessageHandler( msgHandler ); - QTranslator *qt = new QTranslator( this ); - QTranslator *t = new QTranslator( this ); + auto *qt = new QTranslator(this); + auto *t = new QTranslator(this); QString lang; auto languages = QLocale().uiLanguages().first(); if(languages.contains("et"_L1, Qt::CaseInsensitive)) @@ -83,7 +85,7 @@ Application::~Application() qInstallMessageHandler(nullptr); } -int Application::confTask( const QStringList &args ) const +int Application::confTask(const QStringList &args) { ScheduledUpdateTask task; if(args.contains("-status"_L1)) @@ -106,29 +108,32 @@ bool Application::execute(const QStringList &arguments) QString command = QDir::toNativeSeparators(applicationFilePath()) + ' ' + arguments.join(' '); qDebug() << "command:" << command; - PWTS_SESSION_INFOW sessionInfo = 0; + PWTS_SESSION_INFOW sessionInfo {}; DWORD count = 0; - WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &count); + auto ret = WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &count); + qDebug() << "WTSEnumerateSessionsW" << ret << GetLastError(); + if(!ret) + return false; DWORD sessionId = 0; - for(DWORD i = 0; i < count; ++i) + for(const auto &session: std::span(sessionInfo, count)) { - if(sessionInfo[i].State == WTSActive) + if(session.State == WTSActive) { - sessionId = sessionInfo[i].SessionId; + sessionId = session.SessionId; break; } } WTSFreeMemory(sessionInfo); qDebug() << "Active session ID " << sessionId; - HANDLE currentToken = 0; - BOOL ret = WTSQueryUserToken(sessionId, ¤tToken); + HANDLE currentToken {}; + ret = WTSQueryUserToken(sessionId, ¤tToken); qDebug() << "WTSQueryUserToken" << ret << GetLastError(); if(!ret) return false; - HANDLE primaryToken = 0; + HANDLE primaryToken {}; ret = DuplicateTokenEx(currentToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &primaryToken); CloseHandle(currentToken); @@ -140,7 +145,7 @@ bool Application::execute(const QStringList &arguments) if(!primaryToken) return false; - void *environment = nullptr; + void *environment {}; ret = CreateEnvironmentBlock(&environment, primaryToken, true); qDebug() << "CreateEnvironmentBlock" << environment << ret << GetLastError(); @@ -162,17 +167,17 @@ void Application::messageReceived( const QString &str ) w->checkUpdates(str.contains("-autoupdate"_L1), str.contains("-autoclose"_L1)); } -void Application::msgHandler( QtMsgType type, const QMessageLogContext &, const QString &msg ) +void Application::msgHandler(QtMsgType type, const QMessageLogContext &/* ctx */, const QString &msg) { - QFile *log = &qobject_cast(qApp)->log; - log->write(QDateTime::currentDateTime().toString(u"yyyy-MM-dd hh:mm:ss:zzz "_s).toUtf8()); + QFile &log = qobject_cast(qApp)->log; + log.write(QDateTime::currentDateTime().toString(u"yyyy-MM-dd hh:mm:ss:zzz "_s).toUtf8()); switch( type ) { - case QtDebugMsg: log->write("DBG: %1\n"_L1.arg(msg).toUtf8()); break; - case QtInfoMsg: log->write("INF: %1\n"_L1.arg(msg).toUtf8()); break; - case QtWarningMsg: log->write("WRN: %1\n"_L1.arg(msg).toUtf8()); break; - case QtCriticalMsg: log->write("CRI: %1\n"_L1.arg( msg).toUtf8()); break; - case QtFatalMsg: log->write("FAT: %1\n"_L1.arg(msg).toUtf8()); abort(); + case QtDebugMsg: log.write("DBG: %1\n"_L1.arg(msg).toUtf8()); break; + case QtInfoMsg: log.write("INF: %1\n"_L1.arg(msg).toUtf8()); break; + case QtWarningMsg: log.write("WRN: %1\n"_L1.arg(msg).toUtf8()); break; + case QtCriticalMsg: log.write("CRI: %1\n"_L1.arg( msg).toUtf8()); break; + case QtFatalMsg: log.write("FAT: %1\n"_L1.arg(msg).toUtf8()); abort(); } } diff --git a/Application.h b/Application.h index 01d1dd5..516c8c2 100644 --- a/Application.h +++ b/Application.h @@ -38,8 +38,8 @@ class Application: public QtSingleApplication bool execute(const QStringList &arguments); void messageReceived( const QString &str ); static void msgHandler( QtMsgType type, const QMessageLogContext &ctx, const QString &msg ); - int confTask( const QStringList &args ) const; - void printHelp(); + static int confTask(const QStringList &args); + static void printHelp(); QFile log; QString url; diff --git a/README.md b/README.md index b361dba..2337ec4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Building [![Build Status](https://github.com/open-eid/updater/workflows/CI/badge.svg?branch=master)](https://github.com/open-eid/updater/actions) -### OSX +### Windows 1. Fetch the source @@ -23,6 +23,21 @@ cmake --build build +### OSX + +1. Fetch the source + + git clone https://github.com/open-eid/updater + cd updater + +2. Configure + + cmake -B build -S . + +3. Build + + cmake --build build + 4. Install sudo cmake --build build --target install diff --git a/ScheduledUpdateTask.cpp b/ScheduledUpdateTask.cpp index d91fb7c..5e10957 100644 --- a/ScheduledUpdateTask.cpp +++ b/ScheduledUpdateTask.cpp @@ -34,16 +34,15 @@ template struct CPtr { - T *d{}; - ~CPtr() { if(d) d->Release(); } - inline T* operator->() const { return d; } - inline operator T*() const { return d; } - inline T** operator&() { return &d; } + T *d{}; + ~CPtr() { if(d) d->Release(); } + constexpr T* operator->() const { return d; } + constexpr operator T*() const { return d; } + constexpr T** operator&() { return &d; } }; -class ScheduledUpdateTaskPrivate +struct ScheduledUpdateTask::Private { -public: CPtr service; CPtr folder; }; @@ -51,7 +50,7 @@ class ScheduledUpdateTaskPrivate ScheduledUpdateTask::ScheduledUpdateTask() - : d(new ScheduledUpdateTaskPrivate) + : d(std::make_unique()) { CoInitialize(nullptr); CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, @@ -64,7 +63,7 @@ ScheduledUpdateTask::ScheduledUpdateTask() ScheduledUpdateTask::~ScheduledUpdateTask() { - delete d; + d.reset(); CoUninitialize(); } @@ -84,6 +83,7 @@ bool ScheduledUpdateTask::configure(ScheduledUpdateTask::Interval interval) settings->put_RunOnlyIfNetworkAvailable(VARIANT_TRUE); settings->put_DisallowStartIfOnBatteries(VARIANT_FALSE); settings->put_StopIfGoingOnBatteries(VARIANT_FALSE); + settings->put_MultipleInstances(TASK_INSTANCES_STOP_EXISTING); } CPtr triggerCollection; @@ -139,7 +139,7 @@ bool ScheduledUpdateTask::configure(ScheduledUpdateTask::Interval interval) } } - QString command = QDir::toNativeSeparators(qApp->applicationFilePath()); + QString command = QDir::toNativeSeparators(QCoreApplication::applicationFilePath()); CPtr actionCollection; CPtr action; CPtr execAction; diff --git a/ScheduledUpdateTask.h b/ScheduledUpdateTask.h index cccfd07..1485e6c 100644 --- a/ScheduledUpdateTask.h +++ b/ScheduledUpdateTask.h @@ -19,9 +19,8 @@ #pragma once -#include +#include -class ScheduledUpdateTaskPrivate; class ScheduledUpdateTask { public: @@ -39,5 +38,6 @@ class ScheduledUpdateTask bool remove(); private: - ScheduledUpdateTaskPrivate *d; + struct Private; + std::unique_ptr d; }; diff --git a/common b/common index 1ab87b3..f748156 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 1ab87b394ecbd6c7618c96f8c8dda9122fc1cd57 +Subproject commit f74815645e904557a09ae055885a658006811e89 diff --git a/idupdater.cpp b/idupdater.cpp index abbb74d..a9a34ae 100644 --- a/idupdater.cpp +++ b/idupdater.cpp @@ -43,7 +43,6 @@ using namespace Qt::StringLiterals; idupdaterui::idupdaterui( const QString &version, idupdater *parent ) -: QWidget() { setupUi( this ); m_message->hide(); @@ -152,7 +151,7 @@ void idupdater::finished(bool /*changed*/, const QString &err) QJsonObject obj = conf->object(); trusted.clear(); - for(const auto array = conf->object().value("CERT-BUNDLE"_L1).toArray(); const auto &c: array) + for(const auto array = conf->rawObject().value("CERT-BUNDLE"_L1).toArray(); const auto &c: array) trusted.append(QSslCertificate(QByteArray::fromBase64(c.toString().toLatin1()), QSsl::Der)); if(obj.contains("UPDATER-MESSAGE-URL"_L1)) { @@ -196,7 +195,7 @@ void idupdater::finished(bool /*changed*/, const QString &err) if(w) w->setInfo(version, available); } -QString idupdater::installedVersion(const QString &upgradeCode) const +QString idupdater::installedVersion(const QString &upgradeCode) { QString code = upgradeCode.toUpper(); QSettings s(u"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"_s, QSettings::Registry32Format); @@ -212,7 +211,7 @@ QString idupdater::installedVersion(const QString &upgradeCode) const return {}; DWORD size = 0; - MsiGetProductInfo(prodCode, INSTALLPROPERTY_VERSIONSTRING, 0, &size); + MsiGetProductInfo(prodCode, INSTALLPROPERTY_VERSIONSTRING, nullptr, &size); QString version(size, '\0'); size += 1; MsiGetProductInfo(prodCode, INSTALLPROPERTY_VERSIONSTRING, LPWSTR(version.data()), &size); @@ -299,16 +298,20 @@ bool idupdater::verifyPackage(const QString &filePath) const if(!trusted.contains(cert)) return false; - WINTRUST_FILE_INFO FileData { sizeof(WINTRUST_FILE_INFO) }; - FileData.pcwszFilePath = LPCWSTR(path.utf16()); + WINTRUST_FILE_INFO FileData { + .cbStruct = sizeof(WINTRUST_FILE_INFO), + .pcwszFilePath = LPCWSTR(path.utf16()), + }; - WINTRUST_DATA WinTrustData { sizeof(WinTrustData) }; - WinTrustData.dwUIChoice = m_autoupdate ? WTD_UI_NONE : WTD_UI_ALL; - WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE; - WinTrustData.dwUnionChoice = WTD_CHOICE_FILE; - WinTrustData.dwProvFlags = WTD_SAFER_FLAG; - WinTrustData.pFile = &FileData; + WINTRUST_DATA WinTrustData { + .cbStruct = sizeof(WinTrustData), + .dwUIChoice = DWORD(m_autoupdate ? WTD_UI_NONE : WTD_UI_ALL), + .fdwRevocationChecks = WTD_REVOKE_NONE, + .dwUnionChoice = WTD_CHOICE_FILE, + .pFile = &FileData, + .dwProvFlags = WTD_SAFER_FLAG, + }; GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2; - return WinVerifyTrust(0, &WVTPolicyGUID, &WinTrustData) == ERROR_SUCCESS; + return WinVerifyTrust(nullptr, &WVTPolicyGUID, &WinTrustData) == ERROR_SUCCESS; } diff --git a/idupdater.h b/idupdater.h index f1e1097..21288f1 100644 --- a/idupdater.h +++ b/idupdater.h @@ -58,7 +58,7 @@ class idupdater : public QNetworkAccessManager private: void finished(bool changed, const QString &error); - QString installedVersion(const QString &upgradeCode) const; + static QString installedVersion(const QString &upgradeCode); bool verifyPackage(const QString &filePath) const; bool m_autoupdate = false, m_autoclose = false;