UI: Refactor drive list handling

This commit is contained in:
Nodir Temirkhodjaev 2024-01-09 11:13:54 +03:00
parent f7302c78fc
commit 137c91f50d
19 changed files with 209 additions and 120 deletions

View File

@ -65,23 +65,7 @@ AppInfoManager::AppInfoManager(const QString &filePath, QObject *parent, quint32
void AppInfoManager::setUp()
{
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return;
}
SqliteDb::MigrateOptions opt = {
.sqlDir = ":/appinfo/migrations",
.version = DATABASE_USER_VERSION,
.recreate = true,
.importOldData = false,
};
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return;
}
setupDb();
}
WorkerObject *AppInfoManager::createWorker()
@ -153,6 +137,29 @@ void AppInfoManager::updateAppAccessTime(const QString &appPath)
sqliteDb()->executeEx(sqlUpdateAppAccessTime, QVariantList() << appPath);
}
bool AppInfoManager::setupDb()
{
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return false;
}
SqliteDb::MigrateOptions opt = {
.sqlDir = ":/appinfo/migrations",
.version = DATABASE_USER_VERSION,
.recreate = true,
.importOldData = false,
};
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return false;
}
return true;
}
void AppInfoManager::saveAppIcon(const QImage &appIcon, QVariant &iconId, bool &ok)
{
const uint iconHash = uint(qHashBits(appIcon.constBits(), size_t(appIcon.sizeInBytes())));

View File

@ -51,6 +51,8 @@ protected:
virtual void updateAppAccessTime(const QString &appPath);
private:
bool setupDb();
void saveAppIcon(const QImage &appIcon, QVariant &iconId, bool &ok);
void saveAppInfo(
const QString &appPath, const AppInfo &appInfo, const QVariant &iconId, bool &ok);

View File

@ -11,6 +11,7 @@
#include <driver/drivermanager.h>
#include <log/logentryblocked.h>
#include <log/logmanager.h>
#include <manager/drivelistmanager.h>
#include <manager/envmanager.h>
#include <manager/windowmanager.h>
#include <util/conf/confutil.h>
@ -146,7 +147,17 @@ void ConfAppManager::setUp()
setupAppEndTimer();
setupDbDriveMask();
setupDriveListManager();
}
void ConfAppManager::setupDriveListManager()
{
connect(IoC<DriveListManager>(), &DriveListManager::driveMaskChanged, this,
[&](quint32 addedMask, quint32 /*removedMask*/) {
if ((m_driveMask & addedMask) != 0) {
updateDriverConf();
}
});
}
void ConfAppManager::purgeAppsOnStart()
@ -182,13 +193,6 @@ void ConfAppManager::updateAppEndTimer()
}
}
void ConfAppManager::setupDbDriveMask()
{
const QString filePath = sqliteDb()->filePath();
m_dbDriveMask = FileUtil::driveMaskByPath(filePath);
}
void ConfAppManager::emitAppAlerted()
{
m_appAlertedTimer.startTrigger();
@ -504,18 +508,6 @@ bool ConfAppManager::updateDriverConf(bool onlyFlags)
return true;
}
void ConfAppManager::updateDriverConfByDriveMask(quint32 driveMask)
{
if ((m_dbDriveMask & driveMask) != 0) {
IoC<WindowManager>()->restart();
return;
}
if ((m_driveMask & driveMask) != 0) {
updateDriverConf();
}
}
bool ConfAppManager::addOrUpdateApp(const App &app)
{
const AppGroup *appGroup = conf()->appGroupAt(app.groupIndex);

View File

@ -38,7 +38,8 @@ public:
virtual void deleteApps(const QVector<qint64> &appIdList);
virtual bool purgeApps();
virtual bool updateApp(const App &app);
virtual void updateAppsBlocked(const QVector<qint64> &appIdList, bool blocked, bool killProcess);
virtual void updateAppsBlocked(
const QVector<qint64> &appIdList, bool blocked, bool killProcess);
virtual bool updateAppName(qint64 appId, const QString &appName);
bool walkApps(const std::function<walkAppsCallback> &func) override;
@ -48,8 +49,6 @@ public:
virtual bool updateDriverConf(bool onlyFlags = false);
void updateDriverConfByDriveMask(quint32 driveMask);
signals:
void appAlerted();
void appChanged();
@ -61,9 +60,9 @@ protected:
virtual void setupAppEndTimer();
void updateAppEndTimer();
void setupDbDriveMask();
private:
void setupDriveListManager();
bool deleteApp(qint64 appId, bool &isWildcard);
bool updateAppBlocked(qint64 appId, bool blocked, bool killProcess, bool &isWildcard);
@ -88,7 +87,6 @@ private:
bool checkEndTransaction(bool ok);
private:
quint32 m_dbDriveMask = 0;
quint32 m_driveMask = 0;
ConfManager *m_confManager = nullptr;

View File

@ -11,6 +11,7 @@
#include <driver/drivermanager.h>
#include <fortsettings.h>
#include <log/logmanager.h>
#include <manager/drivelistmanager.h>
#include <manager/envmanager.h>
#include <manager/serviceinfomanager.h>
#include <manager/windowmanager.h>
@ -420,6 +421,7 @@ IniUser &ConfManager::iniUser() const
void ConfManager::setUp()
{
setupDb();
setupDriveListManager();
}
void ConfManager::initConfToEdit()
@ -513,6 +515,23 @@ bool ConfManager::setupDb()
return true;
}
void ConfManager::setupDriveListManager()
{
m_driveMask = FileUtil::driveMaskByPath(sqliteDb()->filePath());
connect(IoC<DriveListManager>(), &DriveListManager::driveMaskChanged, this,
[&](quint32 addedMask, quint32 removedMask) {
// Restart on profile drive attached
if ((m_driveMask & addedMask) != 0) {
IoC<WindowManager>()->restart();
}
// Close DB on drive detached
else if ((m_driveMask & removedMask) != 0) {
sqliteDb()->close();
}
});
}
void ConfManager::setupDefault(FirewallConf &conf) const
{
conf.setupDefaultAddressGroups();

View File

@ -81,6 +81,7 @@ protected:
private:
bool setupDb();
void setupDriveListManager();
void setupDefault(FirewallConf &conf) const;
@ -99,6 +100,8 @@ private:
bool checkEndTransaction(bool ok);
private:
quint32 m_driveMask = 0;
SqliteDbPtr m_sqliteDb;
FirewallConf *m_conf = nullptr;

View File

@ -62,9 +62,6 @@ inline void setupMasterServices(IocContainer *ioc, const FortSettings *settings)
ioc->setService(new LogManager());
ioc->setService(new ServiceInfoManager());
ioc->setService(new TaskManager());
// For Master only
ioc->setService(new DriveListManager());
}
inline void setupClientServices(IocContainer *ioc, const FortSettings *settings)
@ -109,6 +106,7 @@ inline void setupServices(IocContainer *ioc, const FortSettings *settings)
ioc->setService(new TranslationManager());
}
ioc->setService(new DriveListManager());
ioc->setService(new NativeEventFilter());
ioc->setService(new AppInfoCache());
ioc->setService(new HostInfoCache());
@ -399,10 +397,7 @@ void FortManager::setupServiceInfoManager()
void FortManager::setupDriveListManager()
{
const auto settings = IoC<FortSettings>();
if (!settings->isMaster())
return;
auto settings = IoC<FortSettings>();
auto driveListManager = IoC<DriveListManager>();
if (settings->isService()) {
@ -413,9 +408,6 @@ void FortManager::setupDriveListManager()
&DriveListManager::onDriveListChanged);
}
connect(driveListManager, &DriveListManager::driveMaskAdded, IoC<ConfAppManager>(),
&ConfAppManager::updateDriverConfByDriveMask);
driveListManager->initialize();
}

View File

@ -23,10 +23,11 @@ void DriveListManager::onDriveListChanged()
return;
const quint32 addedMask = (driveMask & (driveMask ^ m_driveMask));
const quint32 removedMask = (m_driveMask ^ (m_driveMask & m_driveMask));
m_driveMask = driveMask;
if (addedMask != 0) {
emit driveMaskAdded(addedMask);
if (addedMask != 0 || removedMask != 0) {
emit driveMaskChanged(addedMask, removedMask);
}
}

View File

@ -15,7 +15,7 @@ public:
void initialize();
signals:
void driveMaskAdded(quint32 driveMask);
void driveMaskChanged(quint32 addedMask, quint32 removedMask);
public slots:
void onDriveListChanged();

View File

@ -22,11 +22,16 @@ AskPendingManager::AskPendingManager(QObject *parent) :
}
void AskPendingManager::setUp()
{
setupDb();
}
bool AskPendingManager::setupDb()
{
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return;
return false;
}
SqliteDb::MigrateOptions opt = {
@ -36,8 +41,14 @@ void AskPendingManager::setUp()
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return;
}
return false;
}
void AskPendingManager::logBlockedIp(const LogEntryBlockedIp &entry) { }
return true;
}
void AskPendingManager::logBlockedIp(const LogEntryBlockedIp &entry)
{
// TODO
Q_UNUSED(entry);
}

View File

@ -24,7 +24,8 @@ public:
void logBlockedIp(const LogEntryBlockedIp &entry);
signals:
private:
bool setupDb();
private:
SqliteDbPtr m_sqliteDb;

View File

@ -78,37 +78,7 @@ void StatBlockManager::setUp()
setupWorker();
setupConfManager();
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return;
}
SqliteDb::MigrateOptions opt = {
.sqlDir = ":/stat/migrations/block",
.version = DATABASE_USER_VERSION,
.recreate = true,
// COMPAT: Union the "conn" & "conn_block" tables
.autoCopyTables = (DATABASE_USER_VERSION != 7),
.migrateFunc = &migrateFunc,
};
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return;
}
if (roSqliteDb() != sqliteDb()) {
if (!roSqliteDb()->open()) {
qCCritical(LC) << "File open error:" << roSqliteDb()->filePath()
<< roSqliteDb()->errorMessage();
return;
}
roSqliteDb()->setBusyTimeoutMs(DATABASE_BUSY_TIMEOUT);
}
sqliteDb()->setBusyTimeoutMs(DATABASE_BUSY_TIMEOUT);
setupDb();
}
void StatBlockManager::tearDown()
@ -193,6 +163,43 @@ void StatBlockManager::setupConfManager()
connect(confManager, &ConfManager::iniChanged, this, &StatBlockManager::setupByConf);
}
bool StatBlockManager::setupDb()
{
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return false;
}
SqliteDb::MigrateOptions opt = {
.sqlDir = ":/stat/migrations/block",
.version = DATABASE_USER_VERSION,
.recreate = true,
// COMPAT: Union the "conn" & "conn_block" tables
.autoCopyTables = (DATABASE_USER_VERSION != 7),
.migrateFunc = &migrateFunc,
};
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return false;
}
if (roSqliteDb() != sqliteDb()) {
if (!roSqliteDb()->open()) {
qCCritical(LC) << "File open error:" << roSqliteDb()->filePath()
<< roSqliteDb()->errorMessage();
return false;
}
roSqliteDb()->setBusyTimeoutMs(DATABASE_BUSY_TIMEOUT);
}
sqliteDb()->setBusyTimeoutMs(DATABASE_BUSY_TIMEOUT);
return true;
}
void StatBlockManager::setupByConf(const IniOptions &ini)
{
m_keepCount = ini.blockedIpKeepCount();

View File

@ -54,6 +54,8 @@ protected:
virtual void setupConfManager();
private:
bool setupDb();
void setupByConf(const IniOptions &ini);
private:

View File

@ -73,23 +73,7 @@ const IniOptions *StatManager::ini() const
void StatManager::setUp()
{
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return;
}
SqliteDb::MigrateOptions opt = {
.sqlDir = ":/stat/migrations/traf",
.version = DATABASE_USER_VERSION,
.recreate = true,
.migrateFunc = &migrateFunc,
};
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return;
}
setupDb();
}
void StatManager::setupTrafDate()
@ -199,6 +183,29 @@ bool StatManager::clearTraffic()
return true;
}
bool StatManager::setupDb()
{
if (!sqliteDb()->open()) {
qCCritical(LC) << "File open error:" << sqliteDb()->filePath()
<< sqliteDb()->errorMessage();
return false;
}
SqliteDb::MigrateOptions opt = {
.sqlDir = ":/stat/migrations/traf",
.version = DATABASE_USER_VERSION,
.recreate = true,
.migrateFunc = &migrateFunc,
};
if (!sqliteDb()->migrate(opt)) {
qCCritical(LC) << "Migration error" << sqliteDb()->filePath();
return false;
}
return true;
}
void StatManager::logClear()
{
m_appPidPathMap.clear();

View File

@ -63,6 +63,8 @@ public slots:
virtual bool clearTraffic();
private:
bool setupDb();
void setupTrafDate();
void setupByConf();

View File

@ -4,7 +4,10 @@
#include <qt_windows.h>
#include <winioctl.h>
Device::Device(QObject *parent) : QObject(parent), m_handle(INVALID_HANDLE_VALUE) { }
Device::Device(QObject *parent) :
QObject(parent), m_handle(INVALID_HANDLE_VALUE), m_buffer(sizeof(OVERLAPPED))
{
}
Device::~Device()
{
@ -16,13 +19,15 @@ bool Device::isOpened() const
return (m_handle != INVALID_HANDLE_VALUE);
}
bool Device::open(const QString &filePath)
bool Device::open(const QString &filePath, quint32 flags)
{
const DWORD access = GENERIC_READ | GENERIC_WRITE;
const DWORD access = GENERIC_READ | ((flags & ReadWrite) != 0 ? GENERIC_WRITE : 0);
const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
const DWORD creation = OPEN_EXISTING;
const DWORD attr = FILE_ATTRIBUTE_NORMAL | SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION;
const DWORD attr = FILE_ATTRIBUTE_NORMAL | (SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION)
| ((flags & Overlapped) != 0 ? FILE_FLAG_OVERLAPPED : 0);
m_flags = flags;
m_handle = CreateFileW(
(LPCWSTR) filePath.utf16(), access, share, nullptr, creation, attr, nullptr);
@ -46,12 +51,14 @@ bool Device::cancelIo()
bool Device::ioctl(quint32 code, char *in, int inSize, char *out, int outSize, int *retSize)
{
DWORD size = 0;
const bool res = DeviceIoControl(m_handle, code, in, inSize, out, outSize, &size, nullptr);
LPOVERLAPPED overlapped = isOverlapped() ? (LPOVERLAPPED) m_buffer.data() : nullptr;
if (retSize) {
*retSize = size;
return DeviceIoControl(m_handle, code, in, inSize, out, outSize, (LPDWORD) retSize, overlapped);
}
return res;
void Device::initOverlapped(void *eventHandle)
{
LPOVERLAPPED overlapped = (LPOVERLAPPED) m_buffer.data();
ZeroMemory(overlapped, sizeof(OVERLAPPED));
overlapped->hEvent = eventHandle;
}

View File

@ -2,6 +2,7 @@
#define DEVICE_H
#include <QObject>
#include <QVarLengthArray>
#include "classhelpers.h"
@ -10,14 +11,23 @@ class Device : public QObject
Q_OBJECT
public:
enum OpenFlag : qint8 {
ReadOnly = 0x01,
ReadWrite = 0x02,
Overlapped = 0x04,
};
Q_DECLARE_FLAGS(OpenFlags, OpenFlag)
explicit Device(QObject *parent = nullptr);
~Device() override;
CLASS_DELETE_COPY_MOVE(Device)
bool isOverlapped() const { return (m_flags & Overlapped) != 0; }
bool isOpened() const;
public slots:
bool open(const QString &filePath);
bool open(const QString &filePath, quint32 flags = ReadWrite);
bool close();
bool cancelIo();
@ -25,8 +35,16 @@ public slots:
bool ioctl(quint32 code, char *in = nullptr, int inSize = 0, char *out = nullptr,
int outSize = 0, int *retSize = nullptr);
void initOverlapped(void *eventHandle = nullptr);
private:
quint32 m_flags = 0;
void *m_handle = nullptr;
QVarLengthArray<char, 4 * sizeof(qintptr)> m_buffer;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Device::OpenFlags)
#endif // DEVICE_H

View File

@ -9,6 +9,7 @@ RegKey::RegKey(RegHandle parentHandle, const QString &subKey, quint32 flags)
{
LPCWSTR subKeyStr = (LPCWSTR) subKey.utf16();
const REGSAM samDesired = ((flags & ReadOnly) != 0 ? KEY_READ : KEY_ALL_ACCESS)
| ((flags & Notify) != 0 ? KEY_NOTIFY : 0)
| ((flags & Native64Key) != 0 ? KEY_WOW64_64KEY : 0)
| ((flags & Native32Key) != 0 ? KEY_WOW64_32KEY : 0);
@ -146,6 +147,13 @@ bool RegKey::contains(const QString &name) const
return !RegQueryValueEx((HKEY) handle(), (LPCWSTR) name.utf16(), 0, nullptr, nullptr, nullptr);
}
bool RegKey::notify(
bool watchSubtree, quint32 filterFlags, qintptr eventHandle, bool isAsynchronous)
{
return !RegNotifyChangeKeyValue(
(HKEY) handle(), watchSubtree, filterFlags, (HANDLE) eventHandle, isAsynchronous);
}
RegKey::RegHandle RegKey::predefinedRootHandle(Root root)
{
switch (root) {

View File

@ -15,6 +15,7 @@ public:
ReadOnly = 0x01,
ReadWrite = 0x02,
Create = 0x04,
Notify = 0x08,
Native64Key = 0x10,
Native32Key = 0x20,
DefaultReadOnly = (ReadOnly | Native64Key),
@ -22,6 +23,14 @@ public:
DefaultCreate = (ReadWrite | Create | Native64Key)
};
// Sync with REG_NOTIFY_CHANGE_*
enum NotifyFlag : qint8 {
NotifyChangeName = 0x01,
NotifyChangeAttributes = 0x02,
NotifyChangeLastSet = 0x04,
NotifyChangeSecurity = 0x08,
};
protected:
using RegHandle = void *;
explicit RegKey(RegHandle parentHandle, const QString &subKey, quint32 flags);
@ -44,6 +53,9 @@ public:
QVariant value(const QString &name, bool *expand = nullptr) const;
bool contains(const QString &name) const;
bool notify(bool watchSubtree, quint32 filterFlags, qintptr eventHandle = 0,
bool isAsynchronous = true);
private:
RegHandle handle() const { return m_handle; }