mirror of
https://github.com/tnodir/fort
synced 2024-11-15 07:38:16 +00:00
UI: Prepare services monitoring
This commit is contained in:
parent
a57aee92cc
commit
23695146eb
@ -182,7 +182,9 @@ SOURCES += \
|
||||
util/processinfo.cpp \
|
||||
util/regkey.cpp \
|
||||
util/service/serviceinfo.cpp \
|
||||
util/service/servicelistmonitor.cpp \
|
||||
util/service/servicemanageriface.cpp \
|
||||
util/service/servicemonitor.cpp \
|
||||
util/service/serviceworker.cpp \
|
||||
util/startuputil.cpp \
|
||||
util/stringutil.cpp \
|
||||
@ -375,7 +377,9 @@ HEADERS += \
|
||||
util/processinfo.h \
|
||||
util/regkey.h \
|
||||
util/service/serviceinfo.h \
|
||||
util/service/servicelistmonitor.h \
|
||||
util/service/servicemanageriface.h \
|
||||
util/service/servicemonitor.h \
|
||||
util/service/serviceworker.h \
|
||||
util/startuputil.h \
|
||||
util/stringutil.h \
|
||||
|
@ -1153,17 +1153,22 @@ bool ConfManager::validateDriver()
|
||||
|
||||
void ConfManager::updateDriverServices()
|
||||
{
|
||||
auto serviceInfoManager = IoC<ServiceInfoManager>();
|
||||
|
||||
int runningServicesCount;
|
||||
const QVector<ServiceInfo> services =
|
||||
serviceInfoManager->loadServiceInfoList(ServiceInfo::TypeWin32, ServiceInfo::StateAll,
|
||||
/*displayName=*/false, &runningServicesCount);
|
||||
|
||||
serviceInfoManager->monitorServices(services);
|
||||
|
||||
if (runningServicesCount == 0)
|
||||
return;
|
||||
|
||||
ConfUtil confUtil;
|
||||
QByteArray buf;
|
||||
|
||||
auto serviceInfoManager = IoC<ServiceInfoManager>();
|
||||
const QVector<ServiceInfo> services = serviceInfoManager->loadServiceInfoList(
|
||||
ServiceInfo::TypeWin32, ServiceInfo::StateActive, /*displayName=*/false);
|
||||
|
||||
if (services.isEmpty())
|
||||
return;
|
||||
|
||||
const int outSize = confUtil.writeServices(services, buf);
|
||||
const int outSize = confUtil.writeServices(services, runningServicesCount, buf);
|
||||
|
||||
auto driverManager = IoC<DriverManager>();
|
||||
driverManager->writeServices(buf, outSize);
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include <util/fileutil.h>
|
||||
#include <util/regkey.h>
|
||||
#include <util/service/servicelistmonitor.h>
|
||||
#include <util/service/servicemonitor.h>
|
||||
|
||||
namespace {
|
||||
|
||||
@ -64,7 +66,8 @@ bool checkIsSvcHostService(const RegKey &svcReg)
|
||||
}
|
||||
|
||||
QVector<ServiceInfo> getServiceInfoList(SC_HANDLE mngr, DWORD serviceType = SERVICE_WIN32,
|
||||
DWORD state = SERVICE_STATE_ALL, bool displayName = true)
|
||||
DWORD state = SERVICE_STATE_ALL, bool displayName = true,
|
||||
int *runningServicesCount = nullptr)
|
||||
{
|
||||
QVector<ServiceInfo> infoList;
|
||||
|
||||
@ -76,6 +79,8 @@ QVector<ServiceInfo> getServiceInfoList(SC_HANDLE mngr, DWORD serviceType = SERV
|
||||
DWORD serviceCount = 0;
|
||||
DWORD resumePoint = 0;
|
||||
|
||||
int runningCount = 0;
|
||||
|
||||
while (EnumServicesStatusExW(mngr, SC_ENUM_PROCESS_INFO, serviceType, state, (LPBYTE) buffer,
|
||||
sizeof(buffer), &bytesRemaining, &serviceCount, &resumePoint, nullptr)
|
||||
|| GetLastError() == ERROR_MORE_DATA) {
|
||||
@ -97,6 +102,7 @@ QVector<ServiceInfo> getServiceInfoList(SC_HANDLE mngr, DWORD serviceType = SERV
|
||||
const quint32 trackFlags = svcReg.value(serviceTrackFlagsKey).toUInt();
|
||||
|
||||
ServiceInfo info;
|
||||
info.isRunning = (service->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING);
|
||||
info.trackFlags = trackFlags;
|
||||
info.processId = service->ServiceStatusProcess.dwProcessId;
|
||||
info.serviceName = serviceName;
|
||||
@ -105,6 +111,10 @@ QVector<ServiceInfo> getServiceInfoList(SC_HANDLE mngr, DWORD serviceType = SERV
|
||||
info.displayName = QString::fromUtf16((const char16_t *) service->lpDisplayName);
|
||||
}
|
||||
|
||||
if (info.isRunning) {
|
||||
++runningCount;
|
||||
}
|
||||
|
||||
infoList.append(info);
|
||||
}
|
||||
|
||||
@ -112,6 +122,10 @@ QVector<ServiceInfo> getServiceInfoList(SC_HANDLE mngr, DWORD serviceType = SERV
|
||||
break;
|
||||
}
|
||||
|
||||
if (runningServicesCount) {
|
||||
*runningServicesCount = runningCount;
|
||||
}
|
||||
|
||||
return infoList;
|
||||
}
|
||||
|
||||
@ -119,14 +133,19 @@ QVector<ServiceInfo> getServiceInfoList(SC_HANDLE mngr, DWORD serviceType = SERV
|
||||
|
||||
ServiceInfoManager::ServiceInfoManager(QObject *parent) : QObject(parent) { }
|
||||
|
||||
QVector<ServiceInfo> ServiceInfoManager::loadServiceInfoList(
|
||||
ServiceInfo::Type serviceType, ServiceInfo::State state, bool displayName)
|
||||
void ServiceInfoManager::setUp()
|
||||
{
|
||||
setupServiceListMonitor();
|
||||
}
|
||||
|
||||
QVector<ServiceInfo> ServiceInfoManager::loadServiceInfoList(ServiceInfo::Type serviceType,
|
||||
ServiceInfo::State state, bool displayName, int *runningServicesCount)
|
||||
{
|
||||
QVector<ServiceInfo> list;
|
||||
const SC_HANDLE mngr =
|
||||
OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
|
||||
if (mngr) {
|
||||
list = getServiceInfoList(mngr, serviceType, state, displayName);
|
||||
list = getServiceInfoList(mngr, serviceType, state, displayName, runningServicesCount);
|
||||
CloseServiceHandle(mngr);
|
||||
}
|
||||
return list;
|
||||
@ -180,3 +199,73 @@ void ServiceInfoManager::revertService(const QString &serviceName)
|
||||
|
||||
svcReg.removeValue(serviceTrackFlagsKey);
|
||||
}
|
||||
|
||||
void ServiceInfoManager::monitorServices(const QVector<ServiceInfo> &serviceInfoList)
|
||||
{
|
||||
for (const ServiceInfo &serviceInfo : serviceInfoList) {
|
||||
setupServiceMonitor(serviceInfo.serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceInfoManager::setupServiceListMonitor()
|
||||
{
|
||||
m_serviceListMonitor = new ServiceListMonitor(this);
|
||||
|
||||
connect(m_serviceListMonitor, &ServiceListMonitor::servicesCreated, this,
|
||||
&ServiceInfoManager::onServicesCreated);
|
||||
|
||||
m_serviceListMonitor->startMonitor();
|
||||
}
|
||||
|
||||
void ServiceInfoManager::setupServiceMonitor(const QString &serviceName)
|
||||
{
|
||||
if (isServiceMonitoring(serviceName))
|
||||
return;
|
||||
|
||||
auto serviceMonitor = new ServiceMonitor(serviceName, m_serviceListMonitor);
|
||||
|
||||
connect(serviceMonitor, &ServiceMonitor::stateChanged, this,
|
||||
[=] { onServiceStateChanged(serviceMonitor); });
|
||||
|
||||
startServiceMonitor(serviceMonitor);
|
||||
}
|
||||
|
||||
bool ServiceInfoManager::isServiceMonitoring(const QString &serviceName) const
|
||||
{
|
||||
return m_serviceMonitors.contains(serviceName);
|
||||
}
|
||||
|
||||
void ServiceInfoManager::startServiceMonitor(ServiceMonitor *serviceMonitor)
|
||||
{
|
||||
m_serviceMonitors.insert(serviceMonitor->serviceName(), serviceMonitor);
|
||||
|
||||
serviceMonitor->startMonitor(m_serviceListMonitor->managerHandle());
|
||||
}
|
||||
|
||||
void ServiceInfoManager::stopServiceMonitor(ServiceMonitor *serviceMonitor)
|
||||
{
|
||||
m_serviceMonitors.remove(serviceMonitor->serviceName());
|
||||
|
||||
delete serviceMonitor;
|
||||
}
|
||||
|
||||
void ServiceInfoManager::onServicesCreated(const QStringList &serviceNames)
|
||||
{
|
||||
for (const QString &serviceName : serviceNames) {
|
||||
setupServiceMonitor(serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceInfoManager::onServiceStateChanged(ServiceMonitor *serviceMonitor)
|
||||
{
|
||||
switch (serviceMonitor->state()) {
|
||||
case ServiceMonitor::ServiceStateUnknown: {
|
||||
} break;
|
||||
case ServiceMonitor::ServiceRunning: {
|
||||
emit serviceStarted(serviceMonitor->serviceName(), serviceMonitor->processId());
|
||||
} break;
|
||||
case ServiceMonitor::ServiceDeleting: {
|
||||
stopServiceMonitor(serviceMonitor);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
#ifndef SERVICEINFOMANAGER_H
|
||||
#define SERVICEINFOMANAGER_H
|
||||
|
||||
#include <QHash>
|
||||
|
||||
#include <util/ioc/iocservice.h>
|
||||
#include <util/service/serviceinfo.h>
|
||||
|
||||
class ServiceListMonitor;
|
||||
class ServiceMonitor;
|
||||
|
||||
class ServiceInfoManager : public QObject, public IocService
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -11,15 +16,39 @@ class ServiceInfoManager : public QObject, public IocService
|
||||
public:
|
||||
explicit ServiceInfoManager(QObject *parent = nullptr);
|
||||
|
||||
void setUp() override;
|
||||
|
||||
static QVector<ServiceInfo> loadServiceInfoList(
|
||||
ServiceInfo::Type serviceType = ServiceInfo::TypeWin32,
|
||||
ServiceInfo::State state = ServiceInfo::StateAll, bool displayName = true);
|
||||
ServiceInfo::State state = ServiceInfo::StateAll, bool displayName = true,
|
||||
int *runningServicesCount = nullptr);
|
||||
|
||||
static QString getSvcHostServiceDll(const QString &serviceName);
|
||||
|
||||
signals:
|
||||
void serviceStarted(const QString &serviceName, qint32 processId);
|
||||
|
||||
public slots:
|
||||
virtual void trackService(const QString &serviceName);
|
||||
virtual void revertService(const QString &serviceName);
|
||||
|
||||
void monitorServices(const QVector<ServiceInfo> &serviceInfoList);
|
||||
|
||||
protected:
|
||||
virtual void setupServiceListMonitor();
|
||||
void setupServiceMonitor(const QString &serviceName);
|
||||
|
||||
bool isServiceMonitoring(const QString &serviceName) const;
|
||||
void startServiceMonitor(ServiceMonitor *serviceMonitor);
|
||||
void stopServiceMonitor(ServiceMonitor *serviceMonitor);
|
||||
|
||||
private:
|
||||
void onServicesCreated(const QStringList &serviceNames);
|
||||
void onServiceStateChanged(ServiceMonitor *serviceMonitor);
|
||||
|
||||
private:
|
||||
ServiceListMonitor *m_serviceListMonitor = nullptr;
|
||||
QHash<QString, ServiceMonitor *> m_serviceMonitors;
|
||||
};
|
||||
|
||||
#endif // SERVICEINFOMANAGER_H
|
||||
|
@ -13,6 +13,9 @@ public:
|
||||
public slots:
|
||||
void trackService(const QString &serviceName) override;
|
||||
void revertService(const QString &serviceName) override;
|
||||
|
||||
protected:
|
||||
void setupServiceListMonitor() override { }
|
||||
};
|
||||
|
||||
#endif // SERVICEINFOMANAGERRPC_H
|
||||
|
@ -108,13 +108,17 @@ int ConfUtil::writeVersion(QByteArray &buf)
|
||||
return verSize;
|
||||
}
|
||||
|
||||
int ConfUtil::writeServices(const QVector<ServiceInfo> &services, QByteArray &buf)
|
||||
int ConfUtil::writeServices(
|
||||
const QVector<ServiceInfo> &services, int runningServicesCount, QByteArray &buf)
|
||||
{
|
||||
buf.reserve(FORT_SERVICE_INFO_LIST_MIN_SIZE);
|
||||
|
||||
int outSize = writeServicesHeader(buf.data(), services.size());
|
||||
int outSize = writeServicesHeader(buf.data(), runningServicesCount);
|
||||
|
||||
for (const ServiceInfo &info : services) {
|
||||
if (!info.isRunning)
|
||||
continue;
|
||||
|
||||
buf.reserve(outSize + FORT_SERVICE_INFO_MAX_SIZE);
|
||||
|
||||
outSize += writeServiceInfo(buf.data() + outSize, info);
|
||||
|
@ -44,7 +44,8 @@ signals:
|
||||
|
||||
public slots:
|
||||
int writeVersion(QByteArray &buf);
|
||||
int writeServices(const QVector<ServiceInfo> &services, QByteArray &buf);
|
||||
int writeServices(
|
||||
const QVector<ServiceInfo> &services, int runningServicesCount, QByteArray &buf);
|
||||
int write(const FirewallConf &conf, ConfAppsWalker *confAppsWalker, EnvManager &envManager,
|
||||
QByteArray &buf);
|
||||
int writeFlags(const FirewallConf &conf, QByteArray &buf);
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
|
||||
bool isTracked() const { return trackFlags != 0; }
|
||||
|
||||
bool isRunning = 0;
|
||||
quint32 trackFlags = 0;
|
||||
quint32 processId = 0;
|
||||
QString serviceName;
|
||||
|
108
src/ui/util/service/servicelistmonitor.cpp
Normal file
108
src/ui/util/service/servicelistmonitor.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
#include "servicelistmonitor.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <qt_windows.h>
|
||||
|
||||
namespace {
|
||||
|
||||
inline void startManagerMonitor(const ServiceListMonitor &monitor, PSERVICE_NOTIFYW notifyBuffer)
|
||||
{
|
||||
const auto managerHandle = SC_HANDLE(monitor.managerHandle());
|
||||
|
||||
constexpr DWORD notifyMask = SERVICE_NOTIFY_CREATED;
|
||||
|
||||
NotifyServiceStatusChangeW(managerHandle, notifyMask, notifyBuffer);
|
||||
}
|
||||
|
||||
void parseServiceNames(
|
||||
PCWSTR names, QStringList &createdServiceNames, QStringList &deletedServiceNames)
|
||||
{
|
||||
while (names[0] != L'\0') {
|
||||
const bool isCreated = (names[0] == L'/');
|
||||
if (isCreated) {
|
||||
++names;
|
||||
}
|
||||
|
||||
const auto name = QString::fromWCharArray(names);
|
||||
|
||||
if (isCreated) {
|
||||
createdServiceNames.append(name);
|
||||
} else {
|
||||
deletedServiceNames.append(name);
|
||||
}
|
||||
|
||||
names += name.size() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void CALLBACK managerNotifyCallback(PVOID param)
|
||||
{
|
||||
auto notifyBuffer = PSERVICE_NOTIFYW(param);
|
||||
auto monitor = static_cast<ServiceListMonitor *>(notifyBuffer->pContext);
|
||||
|
||||
QStringList createdServiceNames;
|
||||
QStringList deletedServiceNames;
|
||||
|
||||
if (notifyBuffer->dwNotificationStatus == ERROR_SUCCESS) {
|
||||
PWSTR names = notifyBuffer->pszServiceNames;
|
||||
if (names) {
|
||||
parseServiceNames(names, createdServiceNames, deletedServiceNames);
|
||||
|
||||
LocalFree(names);
|
||||
notifyBuffer->pszServiceNames = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
monitor, [=] { monitor->onManagerNotify(createdServiceNames); }, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ServiceListMonitor::ServiceListMonitor(QObject *parent) : QObject(parent) { }
|
||||
|
||||
ServiceListMonitor::~ServiceListMonitor()
|
||||
{
|
||||
stopMonitor();
|
||||
}
|
||||
|
||||
void ServiceListMonitor::startMonitor()
|
||||
{
|
||||
m_managerHandle =
|
||||
OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
|
||||
if (!m_managerHandle)
|
||||
return;
|
||||
|
||||
m_buffer.resize(sizeof(SERVICE_NOTIFYW));
|
||||
|
||||
auto notifyBuffer = PSERVICE_NOTIFYW(m_buffer.data());
|
||||
RtlZeroMemory(notifyBuffer, sizeof(SERVICE_NOTIFYW));
|
||||
notifyBuffer->dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
|
||||
notifyBuffer->pfnNotifyCallback = &managerNotifyCallback;
|
||||
notifyBuffer->pContext = this;
|
||||
|
||||
startManagerMonitor(*this, notifyBuffer);
|
||||
}
|
||||
|
||||
void ServiceListMonitor::stopMonitor()
|
||||
{
|
||||
if (!m_managerHandle)
|
||||
return;
|
||||
|
||||
CloseServiceHandle(SC_HANDLE(m_managerHandle));
|
||||
m_managerHandle = nullptr;
|
||||
}
|
||||
|
||||
void ServiceListMonitor::onManagerNotify(const QStringList &createdServiceNames)
|
||||
{
|
||||
if (!m_managerHandle)
|
||||
return;
|
||||
|
||||
auto notifyBuffer = PSERVICE_NOTIFYW(m_buffer.data());
|
||||
|
||||
startManagerMonitor(*this, notifyBuffer);
|
||||
|
||||
if (!createdServiceNames.isEmpty()) {
|
||||
emit servicesCreated(createdServiceNames);
|
||||
}
|
||||
}
|
31
src/ui/util/service/servicelistmonitor.h
Normal file
31
src/ui/util/service/servicelistmonitor.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef SERVICELISTMONITOR_H
|
||||
#define SERVICELISTMONITOR_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QObject>
|
||||
|
||||
class ServiceListMonitor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ServiceListMonitor(QObject *parent = nullptr);
|
||||
~ServiceListMonitor() override;
|
||||
|
||||
void *managerHandle() const { return m_managerHandle; }
|
||||
|
||||
void startMonitor();
|
||||
void stopMonitor();
|
||||
|
||||
void onManagerNotify(const QStringList &createdServiceNames);
|
||||
|
||||
signals:
|
||||
void servicesCreated(const QStringList &serviceNames);
|
||||
|
||||
private:
|
||||
void *m_managerHandle = nullptr;
|
||||
|
||||
QByteArray m_buffer;
|
||||
};
|
||||
|
||||
#endif // SERVICELISTMONITOR_H
|
97
src/ui/util/service/servicemonitor.cpp
Normal file
97
src/ui/util/service/servicemonitor.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include "servicemonitor.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <qt_windows.h>
|
||||
|
||||
namespace {
|
||||
|
||||
inline void startServiceMonitor(const ServiceMonitor &monitor, PSERVICE_NOTIFYW notifyBuffer)
|
||||
{
|
||||
const auto serviceHandle = SC_HANDLE(monitor.serviceHandle());
|
||||
|
||||
constexpr DWORD notifyMask = SERVICE_NOTIFY_RUNNING | SERVICE_NOTIFY_DELETE_PENDING;
|
||||
|
||||
NotifyServiceStatusChangeW(serviceHandle, notifyMask, notifyBuffer);
|
||||
}
|
||||
|
||||
void CALLBACK serviceNotifyCallback(PVOID param)
|
||||
{
|
||||
auto notifyBuffer = PSERVICE_NOTIFYW(param);
|
||||
auto monitor = static_cast<ServiceMonitor *>(notifyBuffer->pContext);
|
||||
|
||||
DWORD notificationTriggered = 0;
|
||||
DWORD processId = 0;
|
||||
|
||||
if (notifyBuffer->dwNotificationStatus == ERROR_SUCCESS) {
|
||||
notificationTriggered = notifyBuffer->dwNotificationTriggered;
|
||||
processId = notifyBuffer->ServiceStatus.dwProcessId;
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
monitor, [=] { monitor->onServiceNotify(notificationTriggered, processId); },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ServiceMonitor::ServiceMonitor(const QString &serviceName, QObject *parent) :
|
||||
QObject(parent), m_serviceName(serviceName)
|
||||
{
|
||||
}
|
||||
|
||||
ServiceMonitor::~ServiceMonitor()
|
||||
{
|
||||
stopMonitor();
|
||||
}
|
||||
|
||||
void ServiceMonitor::startMonitor(void *managerHandle)
|
||||
{
|
||||
m_serviceHandle = OpenServiceW(SC_HANDLE(managerHandle), PCWSTR(serviceName().utf16()),
|
||||
SERVICE_QUERY_STATUS | SERVICE_INTERROGATE);
|
||||
if (!m_serviceHandle)
|
||||
return;
|
||||
|
||||
m_buffer.resize(sizeof(SERVICE_NOTIFYW));
|
||||
|
||||
auto notifyBuffer = PSERVICE_NOTIFYW(m_buffer.data());
|
||||
RtlZeroMemory(notifyBuffer, sizeof(SERVICE_NOTIFYW));
|
||||
notifyBuffer->dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
|
||||
notifyBuffer->pfnNotifyCallback = &serviceNotifyCallback;
|
||||
notifyBuffer->pContext = this;
|
||||
|
||||
startServiceMonitor(*this, notifyBuffer);
|
||||
}
|
||||
|
||||
void ServiceMonitor::stopMonitor()
|
||||
{
|
||||
if (!m_serviceHandle)
|
||||
return;
|
||||
|
||||
CloseServiceHandle(SC_HANDLE(m_serviceHandle));
|
||||
m_serviceHandle = nullptr;
|
||||
}
|
||||
|
||||
void ServiceMonitor::onServiceNotify(quint32 notificationTriggered, qint32 processId)
|
||||
{
|
||||
if (!m_serviceHandle)
|
||||
return;
|
||||
|
||||
auto notifyBuffer = PSERVICE_NOTIFYW(m_buffer.data());
|
||||
|
||||
startServiceMonitor(*this, notifyBuffer);
|
||||
|
||||
m_processId = processId;
|
||||
|
||||
switch (notificationTriggered) {
|
||||
case SERVICE_NOTIFY_RUNNING: {
|
||||
m_state = ServiceRunning;
|
||||
} break;
|
||||
case SERVICE_NOTIFY_DELETE_PENDING: {
|
||||
m_state = ServiceDeleting;
|
||||
} break;
|
||||
}
|
||||
|
||||
emit stateChanged();
|
||||
}
|
46
src/ui/util/service/servicemonitor.h
Normal file
46
src/ui/util/service/servicemonitor.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef SERVICEMONITOR_H
|
||||
#define SERVICEMONITOR_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QObject>
|
||||
|
||||
class ServiceMonitor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ServiceState : qint8 {
|
||||
ServiceStateUnknown = 0,
|
||||
ServiceRunning,
|
||||
ServiceDeleting,
|
||||
};
|
||||
Q_ENUM(ServiceState)
|
||||
|
||||
explicit ServiceMonitor(const QString &serviceName, QObject *parent = nullptr);
|
||||
~ServiceMonitor() override;
|
||||
|
||||
ServiceState state() const { return m_state; }
|
||||
qint32 processId() const { return m_processId; }
|
||||
void *serviceHandle() const { return m_serviceHandle; }
|
||||
const QString &serviceName() const { return m_serviceName; }
|
||||
|
||||
void startMonitor(void *managerHandle);
|
||||
void stopMonitor();
|
||||
|
||||
void onServiceNotify(quint32 notificationTriggered, qint32 processId);
|
||||
|
||||
signals:
|
||||
void stateChanged();
|
||||
|
||||
private:
|
||||
ServiceState m_state = ServiceStateUnknown;
|
||||
qint32 m_processId = 0;
|
||||
|
||||
void *m_serviceHandle = nullptr;
|
||||
|
||||
const QString m_serviceName;
|
||||
|
||||
QByteArray m_buffer;
|
||||
};
|
||||
|
||||
#endif // SERVICEMONITOR_H
|
Loading…
Reference in New Issue
Block a user