From 128d818286a6676f5bfa0bbbeeec4c8d77bec1d3 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Fri, 7 Jan 2022 13:08:53 +0300 Subject: [PATCH] UI: ServicesPage: Show only `svchost.exe` services --- src/ui/serviceinfo/serviceinfomanager.cpp | 26 +++++++++++++++++------ src/ui/util/regkey.cpp | 25 ++++++++++++++++++++++ src/ui/util/regkey.h | 1 + 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/ui/serviceinfo/serviceinfomanager.cpp b/src/ui/serviceinfo/serviceinfomanager.cpp index 76205601..437481cb 100644 --- a/src/ui/serviceinfo/serviceinfomanager.cpp +++ b/src/ui/serviceinfo/serviceinfomanager.cpp @@ -5,6 +5,8 @@ #define WIN32_LEAN_AND_MEAN #include +#include + namespace { const QLoggingCategory LC("serviceInfo.serviceInfoManager"); @@ -13,6 +15,8 @@ QVector getServiceInfoList(SC_HANDLE mngr, DWORD state = SERVICE_ST { QVector infoList; + const RegKey servicesReg(RegKey::HKLM, R"(SYSTEM\CurrentControlSet\Services)"); + constexpr DWORD bufferMaxSize = 32 * 1024; ENUM_SERVICE_STATUS_PROCESSW buffer[bufferMaxSize / sizeof(ENUM_SERVICE_STATUS_PROCESSW)]; DWORD bytesRemaining = 0; @@ -23,16 +27,26 @@ QVector getServiceInfoList(SC_HANDLE mngr, DWORD state = SERVICE_ST sizeof(buffer), &bytesRemaining, &serviceCount, &resumePoint, nullptr) || GetLastError() == ERROR_MORE_DATA) { - int infoIndex = infoList.size(); - infoList.resize(infoIndex + serviceCount); - const ENUM_SERVICE_STATUS_PROCESSW *service = &buffer[0]; - for (; serviceCount > 0; --serviceCount, ++service, ++infoIndex) { - ServiceInfo &info = infoList[infoIndex]; + for (int infoIndex = infoList.size(); serviceCount > 0; + --serviceCount, ++service, ++infoIndex) { + const auto serviceName = QString::fromUtf16((const char16_t *) service->lpServiceName); + + const RegKey svcReg(servicesReg, serviceName); + if (!svcReg.contains("ServiceSidType")) + continue; + + const auto imagePath = svcReg.value("ImagePath").toString(); + if (!imagePath.contains(R"(\system32\svchost.exe)", Qt::CaseInsensitive)) + continue; + + ServiceInfo info; info.processId = service->ServiceStatusProcess.dwProcessId; - info.serviceName = QString::fromUtf16((const char16_t *) service->lpServiceName); + info.serviceName = serviceName; info.displayName = QString::fromUtf16((const char16_t *) service->lpDisplayName); + + infoList.append(info); } if (bytesRemaining == 0) diff --git a/src/ui/util/regkey.cpp b/src/ui/util/regkey.cpp index ef0b5e17..a0c010cc 100644 --- a/src/ui/util/regkey.cpp +++ b/src/ui/util/regkey.cpp @@ -95,6 +95,31 @@ bool RegKey::setValue(const QString &name, const QVariant &value) return !RegSetValueEx((HKEY) handle(), (LPCWSTR) name.utf16(), 0, type, data, size); } +QVariant RegKey::value(const QString &name, bool *expand) const +{ + char data[16 * 1024]; + DWORD len = sizeof(data); + DWORD type; + + if (!RegQueryValueEx((HKEY) handle(), (LPCWSTR) name.utf16(), 0, &type, (LPBYTE) data, &len)) { + switch (type) { + case REG_EXPAND_SZ: + if (expand) { + *expand = true; + } + Q_FALLTHROUGH(); + case REG_SZ: + return QString::fromWCharArray((LPCWSTR) data, len); + case REG_DWORD: + return *((qint32 *) data); + case REG_QWORD: + return *((qint64 *) data); + } + } + + return QVariant(); +} + bool RegKey::contains(const QString &name) const { return !RegQueryValueEx((HKEY) handle(), (LPCWSTR) name.utf16(), 0, nullptr, nullptr, nullptr); diff --git a/src/ui/util/regkey.h b/src/ui/util/regkey.h index a6b8ca0b..954794b0 100644 --- a/src/ui/util/regkey.h +++ b/src/ui/util/regkey.h @@ -41,6 +41,7 @@ public: bool removeValue(const QString &name); bool setValue(const QString &name, const QVariant &value); bool setDefaultValue(const QVariant &value) { return setValue(QString(), value); } + QVariant value(const QString &name, bool *expand = nullptr) const; bool contains(const QString &name) const; private: