Installer: Add "Portable" option.

This commit is contained in:
Nodir Temirkhodjaev 2019-03-10 23:03:59 +05:00
parent b85e43f85f
commit fa23df7d6c
23 changed files with 124 additions and 141 deletions

View File

@ -24,6 +24,7 @@ AlwaysShowDirOnReadyPage=yes
AlwaysShowGroupOnReadyPage=yes AlwaysShowGroupOnReadyPage=yes
AllowNoIcons=yes AllowNoIcons=yes
OutputBaseFilename=FortFirewall-{#APP_VERSION_STR} OutputBaseFilename=FortFirewall-{#APP_VERSION_STR}
Uninstallable=not IsTaskSelected('portable')
UninstallFilesDir={app}\uninst UninstallFilesDir={app}\uninst
ArchitecturesInstallIn64BitMode=x64 ArchitecturesInstallIn64BitMode=x64
Compression=lzma2/ultra Compression=lzma2/ultra
@ -33,8 +34,12 @@ SolidCompression=yes
Name: en; MessagesFile: "compiler:Default.isl" Name: en; MessagesFile: "compiler:Default.isl"
Name: ru; MessagesFile: "compiler:Languages\Russian.isl" Name: ru; MessagesFile: "compiler:Languages\Russian.isl"
[Tasks]
Name: "portable"; Description: "Portable"; Flags: unchecked
[Files] [Files]
Source: ".\build\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: ".\build\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: ".\README.portable"; DestDir: "{app}"; Check: IsTaskSelected('portable')
[Icons] [Icons]
; Start menu shortcut ; 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" Name: "{group}\{cm:UninstallProgram,{#APP_NAME}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\FortFirewall.ico"
[Run] [Run]
Filename: "{app}\driver\scripts\uninstall.bat"; Description: "Uninstall driver"; Flags: runascurrentuser Filename: "{app}\driver\scripts\reinstall.bat"; Description: "Re-install driver"; Flags: runascurrentuser
Filename: "{app}\driver\scripts\install.bat"; Description: "Install driver"; Flags: runascurrentuser
[UninstallRun] [UninstallRun]
Filename: "{app}\driver\scripts\uninstall.bat"; Flags: runascurrentuser Filename: "{app}\driver\scripts\uninstall.bat"; Flags: runascurrentuser

9
deploy/README.portable Normal file
View File

@ -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.

View File

@ -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_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_VALIDATE FORT_CTL_CODE(0, FILE_WRITE_DATA)
#define FORT_IOCTL_SETFLAGS FORT_CTL_CODE(1, FILE_WRITE_DATA) #define FORT_IOCTL_SETCONF FORT_CTL_CODE(1, FILE_WRITE_DATA)
#define FORT_IOCTL_GETLOG FORT_CTL_CODE(2, FILE_READ_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 #ifndef NT_SUCCESS

View File

@ -73,6 +73,10 @@ typedef struct fort_conf {
char data[4]; char data[4];
} FORT_CONF, *PFORT_CONF; } FORT_CONF, *PFORT_CONF;
typedef struct fort_conf_version {
UINT16 driver_version;
} FORT_CONF_VERSION, *PFORT_CONF_VERSION;
typedef struct fort_conf_io { typedef struct fort_conf_io {
UINT16 driver_version; UINT16 driver_version;

View File

@ -7,6 +7,6 @@
#define APP_UPDATES_URL "https://github.com/tnodir/fort/releases" #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 APP_UPDATES_API_URL "https://api.github.com/repos/tnodir/fort/releases/latest"
#define DRIVER_VERSION 10 #define DRIVER_VERSION 11
#endif // VERSION_H #endif // VERSION_H

View File

@ -1097,6 +1097,16 @@ fort_device_control (PDEVICE_OBJECT device, PIRP irp)
irp_stack = IoGetCurrentIrpStackLocation(irp); irp_stack = IoGetCurrentIrpStackLocation(irp);
switch (irp_stack->Parameters.DeviceIoControl.IoControlCode) { 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: { case FORT_IOCTL_SETCONF: {
const PFORT_CONF_IO conf_io = irp->AssociatedIrp.SystemBuffer; const PFORT_CONF_IO conf_io = irp->AssociatedIrp.SystemBuffer;
const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength; const ULONG len = irp_stack->Parameters.DeviceIoControl.InputBufferLength;

View File

@ -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%

View File

@ -1,3 +0,0 @@
BcdEdit.exe -set loadoptions ENABLE_INTEGRITY_CHECKS
BcdEdit.exe -set NOINTEGRITYCHECKS OFF
BcdEdit.exe -set TESTSIGNING OFF

View File

@ -1,3 +0,0 @@
BcdEdit.exe -set loadoptions DISABLE_INTEGRITY_CHECKS
BcdEdit.exe -set NOINTEGRITYCHECKS ON
BcdEdit.exe -set TESTSIGNING ON

View File

@ -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%

View File

@ -1,7 +1,7 @@
#include "firewallconf.h" #include "firewallconf.h"
#include <QCoreApplication>
#include "../util/fileutil.h"
#include "../util/net/netutil.h" #include "../util/net/netutil.h"
#include "addressgroup.h" #include "addressgroup.h"
#include "appgroup.h" #include "appgroup.h"
@ -362,6 +362,6 @@ void FirewallConf::setupDefault()
AppGroup *appGroup = new AppGroup(); AppGroup *appGroup = new AppGroup();
appGroup->setName("Main"); appGroup->setName("Main");
appGroup->setAllowText(qApp->applicationDirPath() + '/'); appGroup->setAllowText(FileUtil::appBinLocation() + '/');
addAppGroup(appGroup); addAppGroup(appGroup);
} }

View File

@ -1,5 +1,6 @@
#include "drivermanager.h" #include "drivermanager.h"
#include <QProcess>
#include <QThreadPool> #include <QThreadPool>
#include "../conf/firewallconf.h" #include "../conf/firewallconf.h"
@ -7,6 +8,7 @@
#include "../log/logbuffer.h" #include "../log/logbuffer.h"
#include "../util/conf/confutil.h" #include "../util/conf/confutil.h"
#include "../util/device.h" #include "../util/device.h"
#include "../util/fileutil.h"
#include "../util/osutil.h" #include "../util/osutil.h"
#include "driverworker.h" #include "driverworker.h"
@ -61,6 +63,21 @@ bool DriverManager::closeDevice()
return m_device->close(); 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) bool DriverManager::writeConf(const FirewallConf &conf)
{ {
ConfUtil confUtil; ConfUtil confUtil;
@ -102,3 +119,14 @@ bool DriverManager::writeData(quint32 code, QByteArray &buf, int size)
return true; 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);
}

View File

@ -22,6 +22,8 @@ public:
bool isDeviceOpened() const; bool isDeviceOpened() const;
static void reinstallDriver();
signals: signals:
void errorMessageChanged(); void errorMessageChanged();
@ -29,6 +31,8 @@ public slots:
bool openDevice(); bool openDevice();
bool closeDevice(); bool closeDevice();
bool validate();
bool writeConf(const FirewallConf &conf); bool writeConf(const FirewallConf &conf);
bool writeConfFlags(const FirewallConf &conf); bool writeConfFlags(const FirewallConf &conf);

View File

@ -23,6 +23,11 @@ QString FortCommon::deviceName()
return QLatin1String(FORT_DEVICE_NAME); return QLatin1String(FORT_DEVICE_NAME);
} }
quint32 FortCommon::ioctlValidate()
{
return FORT_IOCTL_VALIDATE;
}
quint32 FortCommon::ioctlSetConf() quint32 FortCommon::ioctlSetConf()
{ {
return FORT_IOCTL_SETCONF; return FORT_IOCTL_SETCONF;

View File

@ -13,6 +13,7 @@ public:
static QString deviceName(); static QString deviceName();
static quint32 ioctlValidate();
static quint32 ioctlSetConf(); static quint32 ioctlSetConf();
static quint32 ioctlSetFlags(); static quint32 ioctlSetFlags();
static quint32 ioctlGetLog(); static quint32 ioctlGetLog();

View File

@ -121,7 +121,21 @@ void FortManager::registerQmlTypes()
bool FortManager::setupDriver() 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()); showErrorBox("Setup Driver: " + m_driverManager->errorMessage());
return false; return false;
} }

View File

@ -68,13 +68,19 @@ void FortSettings::processArguments(const QStringList &args)
parser.process(args); parser.process(args);
// Portable Mode
m_isPortable = FileUtil::fileExists(FileUtil::appBinLocation()
+ "/README.portable");
// Provider Boot // Provider Boot
m_hasProvBoot = parser.isSet(provBootOption); m_hasProvBoot = parser.isSet(provBootOption);
// Profile Path // Profile Path
m_profilePath = parser.value(profileOption); m_profilePath = parser.value(profileOption);
if (m_profilePath.isEmpty()) { if (m_profilePath.isEmpty()) {
m_profilePath = FileUtil::appConfigLocation(); m_profilePath = m_isPortable
? FileUtil::appBinLocation() + "/Data"
: FileUtil::appConfigLocation();
} }
m_profilePath = FileUtil::pathSlash( m_profilePath = FileUtil::pathSlash(
FileUtil::absolutePath(m_profilePath)); FileUtil::absolutePath(m_profilePath));

View File

@ -45,6 +45,7 @@ public:
explicit FortSettings(const QStringList &args, explicit FortSettings(const QStringList &args,
QObject *parent = nullptr); QObject *parent = nullptr);
bool isPortable() const { return m_isPortable; }
bool hasProvBoot() const { return m_hasProvBoot; } bool hasProvBoot() const { return m_hasProvBoot; }
bool debug() const { return iniBool("base/debug"); } bool debug() const { return iniBool("base/debug"); }
@ -208,6 +209,7 @@ private:
static QString startupShortcutPath(); static QString startupShortcutPath();
private: private:
uint m_isPortable : 1;
uint m_hasProvBoot : 1; uint m_hasProvBoot : 1;
uint m_bulkUpdating : 1; uint m_bulkUpdating : 1;
uint m_bulkUpdatingEmit : 1; uint m_bulkUpdatingEmit : 1;

View File

@ -4,6 +4,7 @@
#include <QDir> #include <QDir>
#include <QTranslator> #include <QTranslator>
#include "util/fileutil.h"
#include "util/stringutil.h" #include "util/stringutil.h"
#define TRANSLATION_FILE_PREFIX "i18n_" #define TRANSLATION_FILE_PREFIX "i18n_"
@ -113,7 +114,7 @@ void TranslationManager::uninstallTranslator(int language)
{ {
QTranslator *translator = m_translators.at(language); QTranslator *translator = m_translators.at(language);
if (translator) { if (translator) {
qApp->removeTranslator(translator); QCoreApplication::removeTranslator(translator);
} }
} }
@ -124,7 +125,7 @@ void TranslationManager::installTranslator(int language, const QLocale &locale)
translator = loadTranslator(language, locale); translator = loadTranslator(language, locale);
} }
if (translator) { if (translator) {
qApp->installTranslator(translator); QCoreApplication::installTranslator(translator);
} }
} }
@ -149,5 +150,5 @@ void TranslationManager::refreshTranslations()
QString TranslationManager::i18nDir() QString TranslationManager::i18nDir()
{ {
return qApp->applicationDirPath() + "/i18n"; return FileUtil::appBinLocation() + "/i18n";
} }

View File

@ -102,6 +102,20 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf)
return flagsSize; 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<AddressGroup *> &addressGroups, bool ConfUtil::parseAddressGroups(const QList<AddressGroup *> &addressGroups,
addrranges_arr_t &addressRanges, addrranges_arr_t &addressRanges,
numbers_arr_t &addressGroupOffsets, numbers_arr_t &addressGroupOffsets,

View File

@ -39,6 +39,7 @@ signals:
public slots: public slots:
int write(const FirewallConf &conf, QByteArray &buf); int write(const FirewallConf &conf, QByteArray &buf);
int writeFlags(const FirewallConf &conf, QByteArray &buf); int writeFlags(const FirewallConf &conf, QByteArray &buf);
int writeVersion(QByteArray &buf);
private: private:
void setErrorMessage(const QString &errorMessage); void setErrorMessage(const QString &errorMessage);

View File

@ -1,5 +1,6 @@
#include "fileutil.h" #include "fileutil.h"
#include <QCoreApplication>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QStandardPaths> #include <QStandardPaths>
@ -149,6 +150,11 @@ bool FileUtil::writeFileData(const QString &filePath, const QByteArray &data)
&& file.flush(); && file.flush();
} }
QString FileUtil::appBinLocation()
{
return QCoreApplication::applicationDirPath();
}
QString FileUtil::appConfigLocation() QString FileUtil::appConfigLocation()
{ {
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);

View File

@ -40,6 +40,7 @@ public:
static bool writeFile(const QString &filePath, const QString &text); static bool writeFile(const QString &filePath, const QString &text);
static bool writeFileData(const QString &filePath, const QByteArray &data); static bool writeFileData(const QString &filePath, const QByteArray &data);
static QString appBinLocation();
static QString appConfigLocation(); static QString appConfigLocation();
static QString applicationsLocation(); static QString applicationsLocation();
}; };