Client app template and ui
This commit is contained in:
parent
3006c67472
commit
f68415f08e
53 changed files with 4280 additions and 0 deletions
130
client/publib/debug.cpp
Normal file
130
client/publib/debug.cpp
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#include "debug.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QDateTime>
|
||||
|
||||
#define LOGS_DIR "logs"
|
||||
#define CLIENT_LOG_SUFFIX "amneziavpn.log"
|
||||
#define MAX_LOG_FILES 5
|
||||
#define FORMAT_STRING "yyyy-MM-dd--hh-mm-ss"
|
||||
|
||||
QFile Debug::m_clientLog;
|
||||
QTextStream Debug::m_clientLogTextStream;
|
||||
QString Debug::m_clientLogName;
|
||||
|
||||
void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
// Skip Qt warnings
|
||||
if (msg.contains("known incorrect sRGB profile")) return;
|
||||
if (msg.contains("libpng warning")) return;
|
||||
if (msg.contains("Unknown property ffont")) return;
|
||||
|
||||
Debug::m_clientLogTextStream << qFormatLogMessage(type, context, msg) << endl << flush;
|
||||
}
|
||||
|
||||
bool Debug::init()
|
||||
{
|
||||
QString path = qApp->applicationDirPath();
|
||||
QDir appDir(path);
|
||||
|
||||
// init function is called before exec application, so data location folder may not exist
|
||||
if (!appDir.exists())
|
||||
{
|
||||
qWarning() << "Debug: init: log directory doesn't exist or mkpath command error:" << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!appDir.exists(LOGS_DIR) && !appDir.mkdir(LOGS_DIR))
|
||||
{
|
||||
qWarning() << "Debug: init: log directory doesn't exist or mkdir command error:" << path << LOGS_DIR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!appDir.cd(LOGS_DIR))
|
||||
{
|
||||
qWarning() << "Debug: init: cd command error:" << path << LOGS_DIR;
|
||||
return false;
|
||||
}
|
||||
|
||||
//delete older log files
|
||||
auto clientLogsCount = 0;
|
||||
QFileInfoList logDirList = appDir.entryInfoList(
|
||||
QDir::Files | QDir::NoDotAndDotDot,
|
||||
QDir::Time);
|
||||
for (auto fileInfo : logDirList)
|
||||
{
|
||||
if ((fileInfo.completeSuffix() == CLIENT_LOG_SUFFIX &&
|
||||
++clientLogsCount > MAX_LOG_FILES))
|
||||
{
|
||||
appDir.remove(fileInfo.filePath());
|
||||
}
|
||||
}
|
||||
|
||||
//prepare log file names
|
||||
auto currentDateTime = QDateTime::currentDateTime().toString(FORMAT_STRING);
|
||||
|
||||
m_clientLogName = QString("%1.%2").arg(currentDateTime).arg(CLIENT_LOG_SUFFIX);
|
||||
return init(appDir);
|
||||
}
|
||||
|
||||
bool Debug::init(QDir& appDir)
|
||||
{
|
||||
Q_UNUSED(appDir)
|
||||
qSetMessagePattern("[%{time}|%{type}] %{message}");
|
||||
|
||||
#ifndef QT_DEBUG
|
||||
m_clientLog.setFileName(appDir.filePath(m_clientLogName));
|
||||
if (!m_clientLog.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
||||
qWarning() << "Debug::init - failed to open m_clientLog file:" << m_clientLogName;
|
||||
return false;
|
||||
}
|
||||
m_clientLog.setTextModeEnabled(true);
|
||||
m_clientLogTextStream.setDevice(&m_clientLog);
|
||||
qInstallMessageHandler(debugMessageHandler);
|
||||
#else
|
||||
#ifdef DEBUG_OUTPUT_TWO_DIRECTIONAL
|
||||
m_clientLog.setFileName(appDir.filePath(m_clientLogName));
|
||||
if (!m_clientLog.open(QIODevice::WriteOnly | QIODevice::Append))
|
||||
return false;
|
||||
m_clientLog.setTextModeEnabled(true);
|
||||
m_clientLogTextStream.setDevice(&m_clientLog);
|
||||
defaultMessageHandler = qInstallMessageHandler(debugMessageHandler);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
if (!fixOvpnLogPermissions())
|
||||
qWarning() << "Debug: permissions for ovpn.log were not fixed";
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Debug::getPathToClientLog()
|
||||
{
|
||||
QString path = qApp->applicationDirPath();
|
||||
QDir appDir(path);
|
||||
if (!appDir.exists(LOGS_DIR) || !appDir.cd(LOGS_DIR))
|
||||
{
|
||||
qWarning() << "Debug: log directory doesn't exist or cd command error:" << path;
|
||||
return "";
|
||||
}
|
||||
|
||||
return appDir.filePath(m_clientLogName);
|
||||
}
|
||||
|
||||
QString Debug::getPathToLogsDir()
|
||||
{
|
||||
QString path = qApp->applicationDirPath();
|
||||
QDir appDir(path);
|
||||
if (!appDir.exists(LOGS_DIR) || !appDir.cd(LOGS_DIR))
|
||||
{
|
||||
qWarning() << "Debug: log directory doesn't exist or cd command error" << path;
|
||||
return "";
|
||||
}
|
||||
return appDir.absolutePath();
|
||||
}
|
||||
|
||||
|
||||
27
client/publib/debug.h
Normal file
27
client/publib/debug.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
|
||||
class Debug
|
||||
{
|
||||
public:
|
||||
static bool init();
|
||||
static QString getPathToClientLog();
|
||||
static QString getPathToLogsDir();
|
||||
|
||||
private:
|
||||
static bool init(QDir& appDir);
|
||||
|
||||
private:
|
||||
static QFile m_clientLog;
|
||||
static QTextStream m_clientLogTextStream;
|
||||
static QString m_clientLogName;
|
||||
|
||||
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
||||
};
|
||||
|
||||
#endif // DEBUG_H
|
||||
88
client/publib/runguard.cpp
Normal file
88
client/publib/runguard.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include "runguard.h"
|
||||
#include <QCryptographicHash>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
QString generateKeyHash( const QString& key, const QString& salt )
|
||||
{
|
||||
QByteArray data;
|
||||
|
||||
data.append( key.toUtf8() );
|
||||
data.append( salt.toUtf8() );
|
||||
data = QCryptographicHash::hash( data, QCryptographicHash::Sha1 ).toHex();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RunGuard::RunGuard(const QString& key)
|
||||
: key( key )
|
||||
, memLockKey( generateKeyHash( key, "_memLockKey" ) )
|
||||
, sharedmemKey( generateKeyHash( key, "_sharedmemKey" ) )
|
||||
, sharedMem( sharedmemKey )
|
||||
, memLock( memLockKey, 1 )
|
||||
{
|
||||
qDebug() << "RunGuard::RunGuard key" << key;
|
||||
}
|
||||
|
||||
RunGuard &RunGuard::instance(const QString& key)
|
||||
{
|
||||
static RunGuard s(key);
|
||||
return s;
|
||||
}
|
||||
|
||||
void RunGuard::activate()
|
||||
{
|
||||
memLock.acquire();
|
||||
{
|
||||
QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/
|
||||
fix.attach();
|
||||
}
|
||||
memLock.release();
|
||||
}
|
||||
|
||||
RunGuard::~RunGuard()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
bool RunGuard::isAnotherRunning() const
|
||||
{
|
||||
if ( sharedMem.isAttached() )
|
||||
return false;
|
||||
|
||||
memLock.acquire();
|
||||
const bool isRunning = sharedMem.attach();
|
||||
if ( isRunning )
|
||||
sharedMem.detach();
|
||||
memLock.release();
|
||||
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
bool RunGuard::tryToRun()
|
||||
{
|
||||
if ( isAnotherRunning() ) // Extra check
|
||||
return false;
|
||||
|
||||
memLock.acquire();
|
||||
const bool result = sharedMem.create( sizeof( quint64 ) );
|
||||
memLock.release();
|
||||
if ( !result )
|
||||
{
|
||||
release();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RunGuard::release()
|
||||
{
|
||||
memLock.acquire();
|
||||
if ( sharedMem.isAttached() )
|
||||
sharedMem.detach();
|
||||
memLock.release();
|
||||
}
|
||||
37
client/publib/runguard.h
Normal file
37
client/publib/runguard.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef RUNGUARD_H
|
||||
#define RUNGUARD_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedMemory>
|
||||
#include <QSystemSemaphore>
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @brief The RunGuard class - The application single instance (via shared memory)
|
||||
*/
|
||||
class RunGuard
|
||||
{
|
||||
|
||||
public:
|
||||
static RunGuard &instance(const QString& key = QString());
|
||||
|
||||
~RunGuard();
|
||||
|
||||
void activate();
|
||||
bool isAnotherRunning() const;
|
||||
bool tryToRun();
|
||||
void release();
|
||||
|
||||
private:
|
||||
RunGuard(const QString& key);
|
||||
Q_DISABLE_COPY( RunGuard )
|
||||
|
||||
const QString key;
|
||||
const QString memLockKey;
|
||||
const QString sharedmemKey;
|
||||
|
||||
mutable QSharedMemory sharedMem;
|
||||
mutable QSystemSemaphore memLock;
|
||||
|
||||
};
|
||||
#endif // RUNGUARD_H
|
||||
261
client/publib/winhelp.cpp
Normal file
261
client/publib/winhelp.cpp
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
#include "winhelp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <Ras.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
|
||||
#define REG_AUTORUN_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
||||
|
||||
int winhelpGetRegistry(const char *name, const char *reg, char *value)
|
||||
{
|
||||
unsigned long nType = REG_SZ, nData = MAX_PATH;
|
||||
if(ERROR_SUCCESS != SHGetValueA(HKEY_CURRENT_USER, reg,
|
||||
name, &nType, value, &nData))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpSetRegistry(const char *name, const char *reg, const char *value)
|
||||
{
|
||||
if(ERROR_SUCCESS != SHSetValueA(HKEY_CURRENT_USER, reg,
|
||||
name, REG_SZ, value, (DWORD)strlen(value)))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpLaunchStartupRegister(const char *name, int enable, const char *p)
|
||||
{
|
||||
char path[MAX_PATH] = {0};
|
||||
if(p && strlen(p) == 0)
|
||||
p = NULL;
|
||||
if(p) {
|
||||
if(enable)
|
||||
strcpy(path, "\"");
|
||||
else
|
||||
strcpy(path, ";\"");
|
||||
GetModuleFileNameA(NULL, path + strlen(path), MAX_PATH);
|
||||
strcat(path, "\" ");
|
||||
strcat(path, p);
|
||||
} else {
|
||||
if(enable)
|
||||
strcpy(path, "");
|
||||
else
|
||||
strcpy(path, ";");
|
||||
GetModuleFileNameA(NULL, path + strlen(path), MAX_PATH);
|
||||
}
|
||||
if(winhelpSetRegistry(name, REG_AUTORUN_PATH, path) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use the task scheduler, we do not need to care about UAC when start up */
|
||||
int winhelpLaunchStartupTaskScheduler(const char *name, int enable, const char *p)
|
||||
{
|
||||
char cmd[MAX_PATH * 10] = {0};
|
||||
char path[MAX_PATH] = {0};
|
||||
UINT i = 0;
|
||||
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||
if (QString(path).contains("build-vpn-")) {
|
||||
qDebug() << "winhelpLaunchStartupTaskScheduler : skipping auto launch for build dir";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(enable) {
|
||||
if(p == NULL)
|
||||
p = "";
|
||||
sprintf(cmd, "schtasks /create /sc onlogon /tr \"\\\"%s\\\" %s\" "
|
||||
"/tn \"%s\" /f /rl highest", path, p, name);
|
||||
|
||||
} else {
|
||||
sprintf(cmd, "schtasks /delete /tn \"%s\" /f", name);
|
||||
}
|
||||
qDebug().noquote() << "winhelpLaunchStartupTaskScheduler cmd:" << cmd;
|
||||
i = WinExec(cmd, SW_HIDE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpLaunchStartup(const char *name, int enable, const char *p)
|
||||
{
|
||||
OSVERSIONINFOA info = {0};
|
||||
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
if(GetVersionExA(&info) < 0)
|
||||
return -2;
|
||||
if(info.dwMajorVersion >= 6)
|
||||
return winhelpLaunchStartupTaskScheduler(name, enable, p);
|
||||
else
|
||||
return winhelpLaunchStartupRegister(name, enable, p);
|
||||
}
|
||||
|
||||
int str2int(const char *s)
|
||||
{
|
||||
int r = 0;
|
||||
while(*s && *(s + 1) && *(s + 2) && *(s + 3)) {
|
||||
r += ((const int *)s)[0];
|
||||
s += 4;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int winhelpOneProcess()
|
||||
{
|
||||
char path[MAX_PATH] = {0};
|
||||
int i = 0, size = 0, cur = 0;
|
||||
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||
size = strlen(path);
|
||||
for(i = size; i >= 0 && path[i] != '\\' ; i--);
|
||||
cur = i + 1;
|
||||
while(path[i] != '.' && path[i])i++;
|
||||
path[i] = '\0';
|
||||
sprintf(path, "ONE_%s", path + cur);
|
||||
CreateEventA(NULL, FALSE, FALSE, path);
|
||||
if(GetLastError())
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpSystemBits()
|
||||
{
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64)(HANDLE, PBOOL);
|
||||
int b64 = FALSE;
|
||||
LPFN_ISWOW64 fnIsWow64 = (LPFN_ISWOW64)GetProcAddress(
|
||||
GetModuleHandleA("kernel32"), "IsWow64Process");
|
||||
if(NULL != fnIsWow64) {
|
||||
if(!fnIsWow64(GetCurrentProcess(),&b64)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return b64 ? 64 : 86;
|
||||
}
|
||||
|
||||
bool winhelpIsSystem_x64()
|
||||
{
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64)(HANDLE, PBOOL);
|
||||
int b64 = FALSE;
|
||||
LPFN_ISWOW64 fnIsWow64 = (LPFN_ISWOW64)GetProcAddress(
|
||||
GetModuleHandleA("kernel32"), "IsWow64Process");
|
||||
if(NULL != fnIsWow64) {
|
||||
if(!fnIsWow64(GetCurrentProcess(),&b64)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return b64 ? true : false;
|
||||
}
|
||||
|
||||
typedef struct _PROCESS_QUERY
|
||||
{
|
||||
HANDLE h;
|
||||
PROCESSENTRY32 d;
|
||||
}PROCESS_QUERY;
|
||||
|
||||
int winhelpProcessQuery(void **p)
|
||||
{
|
||||
PROCESS_QUERY *q = (PROCESS_QUERY *)malloc(sizeof(PROCESS_QUERY));
|
||||
if(q == NULL)
|
||||
return -2;
|
||||
q->h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if(q->h == INVALID_HANDLE_VALUE) {
|
||||
free(q);
|
||||
return -1;
|
||||
}
|
||||
if(FALSE == Process32First(q->h, &q->d)) {
|
||||
CloseHandle(q->h);
|
||||
free(q);
|
||||
return -3;
|
||||
}
|
||||
*p = (void *)q;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpProcessNext(void *h, char *name)
|
||||
{
|
||||
PROCESS_QUERY *q = (PROCESS_QUERY *)h;
|
||||
int pid = 0;
|
||||
if(q == NULL)
|
||||
return 0;
|
||||
if(q->h == NULL) {
|
||||
free(q);
|
||||
return 0;
|
||||
}
|
||||
if(name)
|
||||
wsprintfA(name, "%ls", q->d.szExeFile);
|
||||
pid = (int)q->d.th32ProcessID;
|
||||
|
||||
if(FALSE == Process32Next(q->h, &q->d)) {
|
||||
CloseHandle(q->h);
|
||||
q->h = NULL;
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
int winhelpRecvEvent(const char *event)
|
||||
{
|
||||
HANDLE hEvent = CreateEventA(NULL, FALSE, FALSE, event);
|
||||
if(hEvent == NULL)
|
||||
return 0;
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
CloseHandle(hEvent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpSendEvent(const char *event)
|
||||
{
|
||||
HANDLE hEvent = OpenEventA(EVENT_ALL_ACCESS, FALSE, event);
|
||||
if(hEvent == NULL)
|
||||
return 0;
|
||||
SetEvent(hEvent);
|
||||
CloseHandle(hEvent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int winhelpSystemVersion()
|
||||
{
|
||||
OSVERSIONINFOA ver = {0};
|
||||
int version = 0;
|
||||
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
GetVersionExA(&ver);
|
||||
version = ver.dwMajorVersion * 0x100 + ver.dwMinorVersion;
|
||||
return version;
|
||||
}
|
||||
|
||||
int winhelperSetMTUSize(const char *subname, int size)
|
||||
{
|
||||
char cmd[MAX_PATH] = {0};
|
||||
sprintf(cmd, "netsh interface ipv4 set subinterface \"%s\" mtu=%d store=persistent",
|
||||
subname, size);
|
||||
return (int)WinExec(cmd, SW_HIDE);
|
||||
}
|
||||
|
||||
int winhelpRecvSendBytes(const char *dev, int *recv, int *send)
|
||||
{
|
||||
MIB_IFTABLE *it = NULL;
|
||||
DWORD size = sizeof(MIB_IFTABLE), ret = 0, i = 0;
|
||||
DWORD tr = 0, ts = 0;
|
||||
|
||||
if(it = (MIB_IFTABLE *)malloc(sizeof (MIB_IFTABLE)), it == NULL)
|
||||
return -1;
|
||||
if(GetIfTable(it, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER) {
|
||||
free(it);
|
||||
if(it = (MIB_IFTABLE *)malloc(size), it == NULL)
|
||||
return -2;
|
||||
}
|
||||
if(ret = GetIfTable(it, &size, FALSE), ret != NO_ERROR) {
|
||||
free(it);
|
||||
return -3;
|
||||
}
|
||||
for(i = 0; i < it->dwNumEntries; i++) {
|
||||
MIB_IFROW *ir = &it->table[i];
|
||||
if(strstr((const char *)ir->bDescr, dev) == 0)
|
||||
continue;
|
||||
tr += (int)ir->dwInOctets;
|
||||
ts += (int)ir->dwOutOctets;
|
||||
}
|
||||
*recv = tr;
|
||||
*send = ts;
|
||||
free(it);
|
||||
return 1;
|
||||
}
|
||||
|
||||
26
client/publib/winhelp.h
Normal file
26
client/publib/winhelp.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef WINHELP_H
|
||||
#define WINHELP_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int winhelpLaunchStartup(const char *, int, const char *);
|
||||
extern int winhelpOneProcess();
|
||||
extern int winhelpSystemBits();
|
||||
extern bool winhelpIsSystem_x64();
|
||||
extern int winhelpProcessQuery(void **);
|
||||
extern int winhelpProcessNext(void *, char *);
|
||||
extern int winhelpRecvEvent(const char *);
|
||||
extern int winhelpSendEvent(const char *);
|
||||
extern int winhelpSystemVersion();
|
||||
extern int winhelperSetMTUSize(const char *, int);
|
||||
extern int winhelpRecvSendBytes(const char *, int *, int *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WINHELP_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue