From fa23df7d6cad48811b5d13385f386bfbd5862c31 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Sun, 10 Mar 2019 23:03:59 +0500 Subject: [PATCH] Installer: Add "Portable" option. --- deploy/FortFirewall.iss | 8 ++- deploy/README.portable | 9 +++ src/common/common.h | 7 +- src/common/fortconf.h | 4 ++ src/common/version.h | 2 +- src/driver/fortdrv.c | 10 +++ src/driver/scripts/install.bat | 88 -------------------------- src/driver/scripts/testsigning-off.bat | 3 - src/driver/scripts/testsigning-on.bat | 3 - src/driver/scripts/uninstall.bat | 34 ---------- src/ui/conf/firewallconf.cpp | 4 +- src/ui/driver/drivermanager.cpp | 28 ++++++++ src/ui/driver/drivermanager.h | 4 ++ src/ui/fortcommon.cpp | 5 ++ src/ui/fortcommon.h | 1 + src/ui/fortmanager.cpp | 16 ++++- src/ui/fortsettings.cpp | 8 ++- src/ui/fortsettings.h | 2 + src/ui/translationmanager.cpp | 7 +- src/ui/util/conf/confutil.cpp | 14 ++++ src/ui/util/conf/confutil.h | 1 + src/ui/util/fileutil.cpp | 6 ++ src/ui/util/fileutil.h | 1 + 23 files changed, 124 insertions(+), 141 deletions(-) create mode 100644 deploy/README.portable delete mode 100644 src/driver/scripts/install.bat delete mode 100644 src/driver/scripts/testsigning-off.bat delete mode 100644 src/driver/scripts/testsigning-on.bat delete mode 100644 src/driver/scripts/uninstall.bat diff --git a/deploy/FortFirewall.iss b/deploy/FortFirewall.iss index 025c8614..2f15c04b 100644 --- a/deploy/FortFirewall.iss +++ b/deploy/FortFirewall.iss @@ -24,6 +24,7 @@ AlwaysShowDirOnReadyPage=yes AlwaysShowGroupOnReadyPage=yes AllowNoIcons=yes OutputBaseFilename=FortFirewall-{#APP_VERSION_STR} +Uninstallable=not IsTaskSelected('portable') UninstallFilesDir={app}\uninst ArchitecturesInstallIn64BitMode=x64 Compression=lzma2/ultra @@ -33,8 +34,12 @@ SolidCompression=yes Name: en; MessagesFile: "compiler:Default.isl" Name: ru; MessagesFile: "compiler:Languages\Russian.isl" +[Tasks] +Name: "portable"; Description: "Portable"; Flags: unchecked + [Files] Source: ".\build\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: ".\README.portable"; DestDir: "{app}"; Check: IsTaskSelected('portable') [Icons] ; Start menu shortcut @@ -43,8 +48,7 @@ Name: "{group}\{#APP_NAME}"; Filename: "{app}\{#APP_EXE_NAME}"; IconFilename: "{ Name: "{group}\{cm:UninstallProgram,{#APP_NAME}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\FortFirewall.ico" [Run] -Filename: "{app}\driver\scripts\uninstall.bat"; Description: "Uninstall driver"; Flags: runascurrentuser -Filename: "{app}\driver\scripts\install.bat"; Description: "Install driver"; Flags: runascurrentuser +Filename: "{app}\driver\scripts\reinstall.bat"; Description: "Re-install driver"; Flags: runascurrentuser [UninstallRun] Filename: "{app}\driver\scripts\uninstall.bat"; Flags: runascurrentuser diff --git a/deploy/README.portable b/deploy/README.portable new file mode 100644 index 00000000..390ac879 --- /dev/null +++ b/deploy/README.portable @@ -0,0 +1,9 @@ +README.portable +=============== + +This version of Fort Firewall is portable, i.e. does not need to +be installed. It will run from any directory you place it in, even +from a USB thumbdrive. It will not write permanent entries into the +Windows registry. + +It needs administrator privileges to install drivers only. diff --git a/src/common/common.h b/src/common/common.h index d7798243..6d51f913 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -79,9 +79,10 @@ DEFINE_GUID(FORT_GUID_FILTER_REAUTH_OUT, #define FORT_CTL_CODE(i,a) CTL_CODE(FORT_DEVICE_TYPE, FORT_IOCTL_BASE + (i), METHOD_BUFFERED, (a)) -#define FORT_IOCTL_SETCONF FORT_CTL_CODE(0, FILE_WRITE_DATA) -#define FORT_IOCTL_SETFLAGS FORT_CTL_CODE(1, FILE_WRITE_DATA) -#define FORT_IOCTL_GETLOG FORT_CTL_CODE(2, FILE_READ_DATA) +#define FORT_IOCTL_VALIDATE FORT_CTL_CODE(0, FILE_WRITE_DATA) +#define FORT_IOCTL_SETCONF FORT_CTL_CODE(1, FILE_WRITE_DATA) +#define FORT_IOCTL_SETFLAGS FORT_CTL_CODE(2, FILE_WRITE_DATA) +#define FORT_IOCTL_GETLOG FORT_CTL_CODE(3, FILE_READ_DATA) #ifndef NT_SUCCESS diff --git a/src/common/fortconf.h b/src/common/fortconf.h index 760f1d25..60791050 100644 --- a/src/common/fortconf.h +++ b/src/common/fortconf.h @@ -73,6 +73,10 @@ typedef struct fort_conf { char data[4]; } FORT_CONF, *PFORT_CONF; +typedef struct fort_conf_version { + UINT16 driver_version; +} FORT_CONF_VERSION, *PFORT_CONF_VERSION; + typedef struct fort_conf_io { UINT16 driver_version; diff --git a/src/common/version.h b/src/common/version.h index 91375035..a5d65f20 100644 --- a/src/common/version.h +++ b/src/common/version.h @@ -7,6 +7,6 @@ #define APP_UPDATES_URL "https://github.com/tnodir/fort/releases" #define APP_UPDATES_API_URL "https://api.github.com/repos/tnodir/fort/releases/latest" -#define DRIVER_VERSION 10 +#define DRIVER_VERSION 11 #endif // VERSION_H diff --git a/src/driver/fortdrv.c b/src/driver/fortdrv.c index 20bdf490..6866217e 100644 --- a/src/driver/fortdrv.c +++ b/src/driver/fortdrv.c @@ -1097,6 +1097,16 @@ fort_device_control (PDEVICE_OBJECT device, PIRP irp) irp_stack = IoGetCurrentIrpStackLocation(irp); switch (irp_stack->Parameters.DeviceIoControl.IoControlCode) { + case FORT_IOCTL_VALIDATE: { + const PFORT_CONF_VERSION conf_ver = irp->AssociatedIrp.SystemBuffer; + const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength; + + if (len == sizeof(FORT_CONF_VERSION)) { + status = (conf_ver->driver_version == DRIVER_VERSION) + ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + } + break; + } case FORT_IOCTL_SETCONF: { const PFORT_CONF_IO conf_io = irp->AssociatedIrp.SystemBuffer; const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength; diff --git a/src/driver/scripts/install.bat b/src/driver/scripts/install.bat deleted file mode 100644 index 55145936..00000000 --- a/src/driver/scripts/install.bat +++ /dev/null @@ -1,88 +0,0 @@ -@rem Install driver - -@set DISPNAME=Fort Firewall -@set CERTNAME=FortFirewallTestCert -@set CERTPATH=%~dp0%CERTNAME%.cer - -@set ARCH=32 -@if defined PROGRAMFILES(X86) @set ARCH=64 - -@set BASENAME=fortfw -@set FILENAME=%BASENAME%%ARCH%.sys -@set SRCPATH=%~dp0..\%FILENAME% -@set DSTPATH=%SystemRoot%\System32\drivers\%BASENAME%.sys - - -@rem Copy driver to system storage -@if exist "%DSTPATH%" ( - @echo Error: Driver already installed. Uninstall it first - @set RCODE=1 - @goto EXIT -) - -copy "%SRCPATH%" "%DSTPATH%" -@if ERRORLEVEL 1 ( - @echo Error: Cannot copy driver to system - @set RCODE=%ERRORLEVEL% - @goto EXIT -) - - -@rem Create testing certificate -@if exist "%CERTPATH%" ( - @goto CERT_ADDED -) - -"%~dp0MakeCert" -r -pe -ss "%DISPNAME%" -n "CN=%CERTNAME%" "%CERTPATH%" -@if ERRORLEVEL 1 ( - @echo Error: Cannot create certificate - @set RCODE=%ERRORLEVEL% - @goto EXIT -) - -"%~dp0CertMgr" /add "%CERTPATH%" /s /r localMachine root -@if ERRORLEVEL 1 ( - @echo Error: Cannot add certificate to store - @set RCODE=%ERRORLEVEL% - @goto EXIT -) - -Del "%CERTPATH%" - -:CERT_ADDED - - -@rem Sign the driver -"%~dp0SignTool" sign /a /v /s "%DISPNAME%" /n "%CERTNAME%" "%DSTPATH%" -@if ERRORLEVEL 1 ( - @echo Error: Cannot sign the driver - @set RCODE=%ERRORLEVEL% - @goto EXIT -) - - -@rem Create service -sc create %BASENAME% binPath= "%DSTPATH%" type= kernel start= auto depend= BFE DisplayName= "%DISPNAME%" -@if ERRORLEVEL 1 ( - @echo Error: Cannot create a service - @set RCODE=%ERRORLEVEL% - @goto EXIT -) - -sc start %BASENAME% -@if ERRORLEVEL 1 ( - @echo Error: Cannot start the service - @set RCODE=%ERRORLEVEL% - @goto EXIT -) - - -@set RCODE=0 -@goto EXIT - -:EXIT -@echo End execution... Error Code = %RCODE% -@if %RCODE% neq 0 ( - @pause -) -@exit /b %RCODE% diff --git a/src/driver/scripts/testsigning-off.bat b/src/driver/scripts/testsigning-off.bat deleted file mode 100644 index c4ee5bd1..00000000 --- a/src/driver/scripts/testsigning-off.bat +++ /dev/null @@ -1,3 +0,0 @@ -BcdEdit.exe -set loadoptions ENABLE_INTEGRITY_CHECKS -BcdEdit.exe -set NOINTEGRITYCHECKS OFF -BcdEdit.exe -set TESTSIGNING OFF diff --git a/src/driver/scripts/testsigning-on.bat b/src/driver/scripts/testsigning-on.bat deleted file mode 100644 index f7195c56..00000000 --- a/src/driver/scripts/testsigning-on.bat +++ /dev/null @@ -1,3 +0,0 @@ -BcdEdit.exe -set loadoptions DISABLE_INTEGRITY_CHECKS -BcdEdit.exe -set NOINTEGRITYCHECKS ON -BcdEdit.exe -set TESTSIGNING ON diff --git a/src/driver/scripts/uninstall.bat b/src/driver/scripts/uninstall.bat deleted file mode 100644 index 2abeace4..00000000 --- a/src/driver/scripts/uninstall.bat +++ /dev/null @@ -1,34 +0,0 @@ -@rem Uninstall driver - -@set DISPNAME=Fort Firewall -@set CERTNAME=FortFirewallTestCert - -@set BASENAME=fortfw -@set DSTPATH=%SystemRoot%\System32\drivers\%BASENAME%.sys - - -@rem Remove the service -sc stop %BASENAME% -sc delete %BASENAME% -@if ERRORLEVEL 1 ( - @echo Error: Cannot delete the service - @set RCODE=%ERRORLEVEL% - @rem @goto EXIT -) - - -@rem Remove driver from system storage -Del "%DSTPATH%" - - -@rem Remove driver from system storage -"%~dp0CertMgr" /del /c /n "%CERTNAME%" -s -r localMachine Root -"%~dp0CertMgr" /del /c /n "%CERTNAME%" -s "%DISPNAME%" - - -@set RCODE=0 -@goto EXIT - -:EXIT -@echo End execution... Error Code = %RCODE% -@exit /b %RCODE% diff --git a/src/ui/conf/firewallconf.cpp b/src/ui/conf/firewallconf.cpp index 982b619b..c5246e8d 100644 --- a/src/ui/conf/firewallconf.cpp +++ b/src/ui/conf/firewallconf.cpp @@ -1,7 +1,7 @@ #include "firewallconf.h" -#include +#include "../util/fileutil.h" #include "../util/net/netutil.h" #include "addressgroup.h" #include "appgroup.h" @@ -362,6 +362,6 @@ void FirewallConf::setupDefault() AppGroup *appGroup = new AppGroup(); appGroup->setName("Main"); - appGroup->setAllowText(qApp->applicationDirPath() + '/'); + appGroup->setAllowText(FileUtil::appBinLocation() + '/'); addAppGroup(appGroup); } diff --git a/src/ui/driver/drivermanager.cpp b/src/ui/driver/drivermanager.cpp index a7484cef..2d7662bb 100644 --- a/src/ui/driver/drivermanager.cpp +++ b/src/ui/driver/drivermanager.cpp @@ -1,5 +1,6 @@ #include "drivermanager.h" +#include #include #include "../conf/firewallconf.h" @@ -7,6 +8,7 @@ #include "../log/logbuffer.h" #include "../util/conf/confutil.h" #include "../util/device.h" +#include "../util/fileutil.h" #include "../util/osutil.h" #include "driverworker.h" @@ -61,6 +63,21 @@ bool DriverManager::closeDevice() return m_device->close(); } +bool DriverManager::validate() +{ + ConfUtil confUtil; + QByteArray buf; + + const int verSize = confUtil.writeVersion(buf); + if (!verSize) { + setErrorMessage(confUtil.errorMessage()); + return false; + } + + return writeData(FortCommon::ioctlValidate(), + buf, verSize); +} + bool DriverManager::writeConf(const FirewallConf &conf) { ConfUtil confUtil; @@ -102,3 +119,14 @@ bool DriverManager::writeData(quint32 code, QByteArray &buf, int size) return true; } + +void DriverManager::reinstallDriver() +{ + QString binPath = FileUtil::appBinLocation(); + binPath.replace('/', '\\'); + + const QString cmdPath = qEnvironmentVariable("COMSPEC"); + const QString scriptPath = binPath + "\\driver\\scripts\\reinstall-lnk.bat"; + + QProcess::execute(cmdPath, QStringList() << "/C" << scriptPath); +} diff --git a/src/ui/driver/drivermanager.h b/src/ui/driver/drivermanager.h index ceaa576f..ee759f21 100644 --- a/src/ui/driver/drivermanager.h +++ b/src/ui/driver/drivermanager.h @@ -22,6 +22,8 @@ public: bool isDeviceOpened() const; + static void reinstallDriver(); + signals: void errorMessageChanged(); @@ -29,6 +31,8 @@ public slots: bool openDevice(); bool closeDevice(); + bool validate(); + bool writeConf(const FirewallConf &conf); bool writeConfFlags(const FirewallConf &conf); diff --git a/src/ui/fortcommon.cpp b/src/ui/fortcommon.cpp index b2491ce7..de700f80 100644 --- a/src/ui/fortcommon.cpp +++ b/src/ui/fortcommon.cpp @@ -23,6 +23,11 @@ QString FortCommon::deviceName() return QLatin1String(FORT_DEVICE_NAME); } +quint32 FortCommon::ioctlValidate() +{ + return FORT_IOCTL_VALIDATE; +} + quint32 FortCommon::ioctlSetConf() { return FORT_IOCTL_SETCONF; diff --git a/src/ui/fortcommon.h b/src/ui/fortcommon.h index fe2617f0..7891c893 100644 --- a/src/ui/fortcommon.h +++ b/src/ui/fortcommon.h @@ -13,6 +13,7 @@ public: static QString deviceName(); + static quint32 ioctlValidate(); static quint32 ioctlSetConf(); static quint32 ioctlSetFlags(); static quint32 ioctlGetLog(); diff --git a/src/ui/fortmanager.cpp b/src/ui/fortmanager.cpp index 35639687..09b208e2 100644 --- a/src/ui/fortmanager.cpp +++ b/src/ui/fortmanager.cpp @@ -121,7 +121,21 @@ void FortManager::registerQmlTypes() bool FortManager::setupDriver() { - if (!m_driverManager->openDevice()) { + bool opened = m_driverManager->openDevice(); + + // Try to (re)install the driver in portable mode + if (m_fortSettings->isPortable() + && !(opened && m_driverManager->validate())) { + if (opened) { + m_driverManager->closeDevice(); + } + + m_driverManager->reinstallDriver(); + + opened = m_driverManager->openDevice(); + } + + if (!opened) { showErrorBox("Setup Driver: " + m_driverManager->errorMessage()); return false; } diff --git a/src/ui/fortsettings.cpp b/src/ui/fortsettings.cpp index a29b039d..fda87f95 100644 --- a/src/ui/fortsettings.cpp +++ b/src/ui/fortsettings.cpp @@ -68,13 +68,19 @@ void FortSettings::processArguments(const QStringList &args) parser.process(args); + // Portable Mode + m_isPortable = FileUtil::fileExists(FileUtil::appBinLocation() + + "/README.portable"); + // Provider Boot m_hasProvBoot = parser.isSet(provBootOption); // Profile Path m_profilePath = parser.value(profileOption); if (m_profilePath.isEmpty()) { - m_profilePath = FileUtil::appConfigLocation(); + m_profilePath = m_isPortable + ? FileUtil::appBinLocation() + "/Data" + : FileUtil::appConfigLocation(); } m_profilePath = FileUtil::pathSlash( FileUtil::absolutePath(m_profilePath)); diff --git a/src/ui/fortsettings.h b/src/ui/fortsettings.h index 7e266510..9f22954d 100644 --- a/src/ui/fortsettings.h +++ b/src/ui/fortsettings.h @@ -45,6 +45,7 @@ public: explicit FortSettings(const QStringList &args, QObject *parent = nullptr); + bool isPortable() const { return m_isPortable; } bool hasProvBoot() const { return m_hasProvBoot; } bool debug() const { return iniBool("base/debug"); } @@ -208,6 +209,7 @@ private: static QString startupShortcutPath(); private: + uint m_isPortable : 1; uint m_hasProvBoot : 1; uint m_bulkUpdating : 1; uint m_bulkUpdatingEmit : 1; diff --git a/src/ui/translationmanager.cpp b/src/ui/translationmanager.cpp index 7f53a057..171b5a7f 100644 --- a/src/ui/translationmanager.cpp +++ b/src/ui/translationmanager.cpp @@ -4,6 +4,7 @@ #include #include +#include "util/fileutil.h" #include "util/stringutil.h" #define TRANSLATION_FILE_PREFIX "i18n_" @@ -113,7 +114,7 @@ void TranslationManager::uninstallTranslator(int language) { QTranslator *translator = m_translators.at(language); if (translator) { - qApp->removeTranslator(translator); + QCoreApplication::removeTranslator(translator); } } @@ -124,7 +125,7 @@ void TranslationManager::installTranslator(int language, const QLocale &locale) translator = loadTranslator(language, locale); } if (translator) { - qApp->installTranslator(translator); + QCoreApplication::installTranslator(translator); } } @@ -149,5 +150,5 @@ void TranslationManager::refreshTranslations() QString TranslationManager::i18nDir() { - return qApp->applicationDirPath() + "/i18n"; + return FileUtil::appBinLocation() + "/i18n"; } diff --git a/src/ui/util/conf/confutil.cpp b/src/ui/util/conf/confutil.cpp index 7636901c..59fe5324 100644 --- a/src/ui/util/conf/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -102,6 +102,20 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf) return flagsSize; } +int ConfUtil::writeVersion(QByteArray &buf) +{ + const int verSize = sizeof(FORT_CONF_VERSION); + + buf.reserve(verSize); + + // Fill the buffer + PFORT_CONF_VERSION confVer = (PFORT_CONF_VERSION) buf.data(); + + confVer->driver_version = DRIVER_VERSION; + + return verSize; +} + bool ConfUtil::parseAddressGroups(const QList &addressGroups, addrranges_arr_t &addressRanges, numbers_arr_t &addressGroupOffsets, diff --git a/src/ui/util/conf/confutil.h b/src/ui/util/conf/confutil.h index 6ae2c399..309db32e 100644 --- a/src/ui/util/conf/confutil.h +++ b/src/ui/util/conf/confutil.h @@ -39,6 +39,7 @@ signals: public slots: int write(const FirewallConf &conf, QByteArray &buf); int writeFlags(const FirewallConf &conf, QByteArray &buf); + int writeVersion(QByteArray &buf); private: void setErrorMessage(const QString &errorMessage); diff --git a/src/ui/util/fileutil.cpp b/src/ui/util/fileutil.cpp index 8a480b4a..2a31b55a 100644 --- a/src/ui/util/fileutil.cpp +++ b/src/ui/util/fileutil.cpp @@ -1,5 +1,6 @@ #include "fileutil.h" +#include #include #include #include @@ -149,6 +150,11 @@ bool FileUtil::writeFileData(const QString &filePath, const QByteArray &data) && file.flush(); } +QString FileUtil::appBinLocation() +{ + return QCoreApplication::applicationDirPath(); +} + QString FileUtil::appConfigLocation() { return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); diff --git a/src/ui/util/fileutil.h b/src/ui/util/fileutil.h index 94fa8daf..c602b578 100644 --- a/src/ui/util/fileutil.h +++ b/src/ui/util/fileutil.h @@ -40,6 +40,7 @@ public: static bool writeFile(const QString &filePath, const QString &text); static bool writeFileData(const QString &filePath, const QByteArray &data); + static QString appBinLocation(); static QString appConfigLocation(); static QString applicationsLocation(); };