1.10.0
|
@ -21,8 +21,8 @@
|
|||
#ifndef _MY_VERSION_H
|
||||
#define _MY_VERSION_H
|
||||
|
||||
#define MY_VERSION_BINARY 5,64,8
|
||||
#define MY_VERSION_STRING "5.64.8"
|
||||
#define MY_VERSION_BINARY 5,65,0
|
||||
#define MY_VERSION_STRING "5.65.0"
|
||||
#define MY_ABI_VERSION 0x56000
|
||||
|
||||
// These #defines are used by either Resource Compiler or NSIS installer
|
||||
|
|
|
@ -586,6 +586,11 @@ typedef struct _FILE_POSITION_INFORMATION {
|
|||
LARGE_INTEGER CurrentByteOffset;
|
||||
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
|
||||
|
||||
// FileEndOfFileInformation
|
||||
typedef struct _FILE_END_OF_FILE_INFORMATION {
|
||||
LARGE_INTEGER EndOfFile;
|
||||
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
|
||||
|
||||
// FileStreamInformation
|
||||
typedef struct _FILE_STREAM_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
|
|
|
@ -198,8 +198,10 @@ QDateTime C7zFileEngine::fileTime(FileTime time) const
|
|||
|
||||
void C7zFileEngine::setFileName(const QString& file)
|
||||
{
|
||||
int pos = file.indexOf(":") + 2;
|
||||
int pos = file.indexOf(":") + 1;
|
||||
_filename = file.mid(pos);
|
||||
while (_filename.left(1) == "\\" || _filename.left(1) == "/")
|
||||
_filename.remove(0, 1);
|
||||
|
||||
if (_filename.isEmpty()) { // root
|
||||
_flags = ExistsFlag | DirectoryType | ReadOwnerPerm | ReadUserPerm | ReadGroupPerm | ReadOtherPerm;
|
||||
|
@ -268,20 +270,34 @@ bool C7zFileEngine::supportsExtension(Extension extension) const
|
|||
// C7zFileEngineHandler
|
||||
//
|
||||
|
||||
C7zFileEngineHandler::C7zFileEngineHandler(const QString& ArchivePath, const QString& Scheme, QObject* parent)
|
||||
C7zFileEngineHandler::C7zFileEngineHandler(const QString& Scheme, QObject* parent)
|
||||
: QObject(parent), m_pArchive(NULL)
|
||||
{
|
||||
CArchive* pArchive = new CArchive(ArchivePath);
|
||||
if (pArchive->Open() > 0)
|
||||
m_pArchive = pArchive;
|
||||
else
|
||||
delete pArchive;
|
||||
m_Scheme = Scheme + ":";
|
||||
}
|
||||
|
||||
C7zFileEngineHandler::~C7zFileEngineHandler()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool C7zFileEngineHandler::Open(const QString& ArchivePath)
|
||||
{
|
||||
Close();
|
||||
|
||||
CArchive* pArchive = new CArchive(ArchivePath);
|
||||
if (pArchive->Open() <= 0) {
|
||||
delete pArchive;
|
||||
return false;
|
||||
}
|
||||
m_pArchive = pArchive;
|
||||
return true;
|
||||
}
|
||||
|
||||
void C7zFileEngineHandler::Close()
|
||||
{
|
||||
delete m_pArchive;
|
||||
m_pArchive = NULL;
|
||||
}
|
||||
|
||||
QAbstractFileEngine* C7zFileEngineHandler::create(const QString& filename) const
|
||||
|
|
|
@ -73,9 +73,12 @@ private:
|
|||
class MISCHELPERS_EXPORT C7zFileEngineHandler : public QObject, public QAbstractFileEngineHandler
|
||||
{
|
||||
public:
|
||||
C7zFileEngineHandler(const QString& ArchivePath, const QString& Scheme, QObject* parent = NULL);
|
||||
C7zFileEngineHandler(const QString& Scheme, QObject* parent = NULL);
|
||||
~C7zFileEngineHandler();
|
||||
|
||||
bool Open(const QString& ArchivePath);
|
||||
void Close();
|
||||
|
||||
bool IsOpen() { return m_pArchive != NULL; }
|
||||
QString Prefix() { return m_Scheme; }
|
||||
|
||||
|
|
|
@ -616,7 +616,7 @@ void SafeShow(QWidget* pWidget) {
|
|||
if (Lock == false) {
|
||||
Lock = true;
|
||||
pWidget->show();
|
||||
QApplication::processEvents(QEventLoop::ExcludeSocketNotifiers | QEventLoop::ExcludeSocketNotifiers);
|
||||
QApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
|
||||
Lock = false;
|
||||
} else
|
||||
pWidget->show();
|
||||
|
|
|
@ -36,8 +36,8 @@ CFinder::CFinder(QObject* pFilterTarget, QWidget *parent, int iOptions)
|
|||
m_pSearchLayout->setAlignment(Qt::AlignLeft);
|
||||
|
||||
m_pSearch = new QLineEdit();
|
||||
m_pSearch->setMinimumWidth(150);
|
||||
m_pSearch->setMaximumWidth(350);
|
||||
m_pSearch->setMinimumWidth(200);
|
||||
//m_pSearch->setMaximumWidth(400);
|
||||
m_pSearchLayout->addWidget(m_pSearch);
|
||||
QObject::connect(m_pSearch, SIGNAL(textChanged(QString)), this, SLOT(OnText()));
|
||||
QObject::connect(m_pSearch, SIGNAL(returnPressed()), this, SLOT(OnReturn()));
|
||||
|
|
|
@ -73,7 +73,7 @@ void CSymbolProvider::run()
|
|||
|
||||
while (m_bRunning)
|
||||
{
|
||||
quint64 OldTime = GetTickCount64() - 3000; // cleanup everything older than 3 sec
|
||||
quint64 OldTime = GetTickCount64() - 3000; // cleanup everythign older than 3 sec
|
||||
if (LastCleanUp < OldTime)
|
||||
{
|
||||
QMutexLocker Lock(&m_SymLock);
|
||||
|
@ -108,6 +108,8 @@ void CSymbolProvider::run()
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" BOOL CALLBACK SymbolCallbackFunction(HANDLE ProcessHandle, ULONG ActionCode, ULONG64 CallbackData, ULONG64 UserContext);
|
||||
|
||||
QString CSymbolProvider::Resolve(quint64 pid, quint64 Address)
|
||||
{
|
||||
QMutexLocker Lock(&m_SymLock);
|
||||
|
@ -115,6 +117,8 @@ QString CSymbolProvider::Resolve(quint64 pid, quint64 Address)
|
|||
SWorker& Worker = m_Workers[pid];
|
||||
if (Worker.handle == 0)
|
||||
{
|
||||
Worker.pProvider = this;
|
||||
|
||||
static ACCESS_MASK accesses[] =
|
||||
{
|
||||
//STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff, // pre-Vista full access
|
||||
|
@ -128,12 +132,12 @@ QString CSymbolProvider::Resolve(quint64 pid, quint64 Address)
|
|||
break;
|
||||
}
|
||||
|
||||
static QAtomicInt FakeHandle = 1; // real handles are divisible by 4
|
||||
static QAtomicInt FakeHandle = 1; // real handles are divisable b 4
|
||||
if (Worker.handle == (quint64)INVALID_HANDLE_VALUE)
|
||||
Worker.handle = FakeHandle.fetchAndAddAcquire(4);
|
||||
|
||||
__sys_SymInitialize((HANDLE)Worker.handle, NULL, TRUE);
|
||||
//__sys_SymRegisterCallbackW64((HANDLE)Worker.handle, SymbolCallbackFunction, (ULONG64)&Worker);
|
||||
__sys_SymRegisterCallbackW64((HANDLE)Worker.handle, SymbolCallbackFunction, (ULONG64)&Worker);
|
||||
__sys_SymSetSearchPathW((HANDLE)Worker.handle, m_SymPath.toStdWString().c_str());
|
||||
}
|
||||
Worker.last = GetTickCount64();
|
||||
|
@ -174,6 +178,8 @@ QString CSymbolProvider::Resolve(quint64 pid, quint64 Address)
|
|||
void CSymbolProvider::ResolveAsync(quint64 pid, quint64 Address, QObject* receiver, const char* member)
|
||||
{
|
||||
CSymbolProvider* This = CSymbolProvider::Instance();
|
||||
if (!This)
|
||||
return;
|
||||
|
||||
if (!QAbstractEventDispatcher::instance(QThread::currentThread())) {
|
||||
qWarning("CSymbolProvider::ResolveAsync() called with no event dispatcher");
|
||||
|
@ -188,7 +194,7 @@ void CSymbolProvider::ResolveAsync(quint64 pid, quint64 Address, QObject* receiv
|
|||
This->m_JobQueue.append(pJob);
|
||||
}
|
||||
|
||||
/*extern "C" BOOL CALLBACK SymbolCallbackFunction(HANDLE ProcessHandle, ULONG ActionCode, ULONG64 CallbackData, ULONG64 UserContext)
|
||||
extern "C" BOOL CALLBACK SymbolCallbackFunction(HANDLE ProcessHandle, ULONG ActionCode, ULONG64 CallbackData, ULONG64 UserContext)
|
||||
{
|
||||
CSymbolProvider::SWorker* pWorker = (CSymbolProvider::SWorker*)UserContext;
|
||||
|
||||
|
@ -196,7 +202,7 @@ void CSymbolProvider::ResolveAsync(quint64 pid, quint64 Address, QObject* receiv
|
|||
{
|
||||
case CBA_DEFERRED_SYMBOL_LOAD_START:
|
||||
{
|
||||
PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 callbackData = (PIMAGEHLP_DEFERRED_SYMBOL_LOADW64)CallbackData;
|
||||
/*PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 callbackData = (PIMAGEHLP_DEFERRED_SYMBOL_LOADW64)CallbackData;
|
||||
|
||||
IMAGEHLP_MODULEW64 ModuleInfo;
|
||||
ModuleInfo.SizeOfStruct = sizeof(ModuleInfo);
|
||||
|
@ -238,25 +244,26 @@ void CSymbolProvider::ResolveAsync(quint64 pid, quint64 Address, QObject* receiv
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
break;
|
||||
case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE:
|
||||
{
|
||||
PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 callbackData = (PIMAGEHLP_DEFERRED_SYMBOL_LOADW64)CallbackData;
|
||||
/*PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 callbackData = (PIMAGEHLP_DEFERRED_SYMBOL_LOADW64)CallbackData;
|
||||
|
||||
if (callbackData->hFile)
|
||||
{
|
||||
NtClose(callbackData->hFile);
|
||||
callbackData->hFile = NULL;
|
||||
}
|
||||
return TRUE;*/
|
||||
}
|
||||
return TRUE;
|
||||
break;
|
||||
case CBA_READ_MEMORY:
|
||||
{
|
||||
PIMAGEHLP_CBA_READ_MEMORY callbackData = (PIMAGEHLP_CBA_READ_MEMORY)CallbackData;
|
||||
|
||||
if ((pWorker->handle & 1) == 0)
|
||||
/*if ((pWorker->handle & 1) == 0)
|
||||
{
|
||||
if (NT_SUCCESS(NtReadVirtualMemory(
|
||||
ProcessHandle,
|
||||
|
@ -268,19 +275,56 @@ void CSymbolProvider::ResolveAsync(quint64 pid, quint64 Address, QObject* receiv
|
|||
{
|
||||
return TRUE;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
break;
|
||||
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
|
||||
{
|
||||
if (pWorker->last == 0) // terminating
|
||||
return TRUE;
|
||||
//if (pWorker->last == 0) // terminating
|
||||
// return TRUE;
|
||||
}
|
||||
break;
|
||||
case CBA_XML_LOG:
|
||||
{
|
||||
PWSTR callbackData = (PWSTR)CallbackData;
|
||||
QString data = QString::fromWCharArray(callbackData);
|
||||
//qDebug() << data;
|
||||
|
||||
QVariantMap result;
|
||||
QXmlStreamReader xmlReader(data);
|
||||
while (!xmlReader.atEnd() && !xmlReader.hasError()) {
|
||||
QXmlStreamReader::TokenType token = xmlReader.readNext();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
QString elementName = xmlReader.name().toString();
|
||||
QVariantMap attributes;
|
||||
QXmlStreamAttributes xmlAttributes = xmlReader.attributes();
|
||||
for (const auto& attribute : xmlAttributes) {
|
||||
attributes.insert(attribute.name().toString(), attribute.value().toString());
|
||||
}
|
||||
|
||||
result.insert(elementName, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
QString Message;
|
||||
if (!result.value("Activity").toMap()["details"].toString().isEmpty())
|
||||
Message = result.value("Activity").toMap()["details"].toString();
|
||||
//if (!result.value("Log").toMap()["message"].toString().isEmpty())
|
||||
// Message = result.value("Log").toMap()["message"].toString();
|
||||
if (!result.value("Progress").toMap()["percent"].toString().isEmpty())
|
||||
Message = pWorker->LastMessage + QString(" (%1%)").arg(result.value("Progress").toMap()["percent"].toString());
|
||||
else if (!Message.isEmpty())
|
||||
pWorker->LastMessage = Message;
|
||||
if(!Message.isEmpty() || result.isEmpty())
|
||||
emit pWorker->pProvider->StatusChanged(Message);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}*/
|
||||
}
|
||||
|
||||
bool MyBeginInitOnce(QAtomicInt& InitOnce)
|
||||
{
|
||||
|
@ -298,11 +342,6 @@ bool MyBeginInitOnce(QAtomicInt& InitOnce)
|
|||
}
|
||||
}
|
||||
|
||||
void MyEndInitOnce(QAtomicInt& InitOnce)
|
||||
{
|
||||
InitOnce = 1;
|
||||
}
|
||||
|
||||
CSymbolProvider* CSymbolProvider::Instance()
|
||||
{
|
||||
static QAtomicInt InitOnce = 0;
|
||||
|
@ -310,6 +349,7 @@ CSymbolProvider* CSymbolProvider::Instance()
|
|||
if (MyBeginInitOnce(InitOnce))
|
||||
{
|
||||
HMODULE DbgHelpMod = LoadLibrary(L"dbghelp.dll");
|
||||
|
||||
__sys_SymFromAddr = (P_SymFromAddr)GetProcAddress(DbgHelpMod, "SymFromAddr");
|
||||
__sys_SymGetModuleInfoW64 = (P_SymGetModuleInfoW64)GetProcAddress(DbgHelpMod, "SymGetModuleInfoW64");
|
||||
__sys_SymSetOptions = (P_SymSetOptions)GetProcAddress(DbgHelpMod, "SymSetOptions");
|
||||
|
@ -319,6 +359,13 @@ CSymbolProvider* CSymbolProvider::Instance()
|
|||
__sys_SymCleanup = (P_SymCleanup)GetProcAddress(DbgHelpMod, "SymCleanup");
|
||||
__sys_SymRegisterCallbackW64 = (P_SymRegisterCallbackW64)GetProcAddress(DbgHelpMod, "SymRegisterCallbackW64");
|
||||
|
||||
if (!__sys_SymSetOptions) {
|
||||
if (DbgHelpMod)
|
||||
FreeLibrary(DbgHelpMod);
|
||||
InitOnce = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__sys_SymSetOptions(
|
||||
__sys_SymGetOptions() | SYMOPT_UNDNAME |
|
||||
SYMOPT_AUTO_PUBLICS | SYMOPT_CASE_INSENSITIVE | SYMOPT_DEFERRED_LOADS |
|
||||
|
@ -328,7 +375,7 @@ CSymbolProvider* CSymbolProvider::Instance()
|
|||
|
||||
g_SymbolProvider = new CSymbolProvider();
|
||||
|
||||
MyEndInitOnce(InitOnce);
|
||||
InitOnce = 1;
|
||||
}
|
||||
|
||||
return g_SymbolProvider;
|
||||
|
|
|
@ -24,8 +24,13 @@ public:
|
|||
SWorker() : last(-1), handle(0) {}
|
||||
quint64 last;
|
||||
quint64 handle;
|
||||
CSymbolProvider* pProvider;
|
||||
QString LastMessage;
|
||||
};
|
||||
|
||||
signals:
|
||||
void StatusChanged(const QString& Message);
|
||||
|
||||
protected:
|
||||
//void timerEvent(QTimerEvent* pEvent);
|
||||
//int m_uTimerID;
|
||||
|
|
|
@ -170,8 +170,10 @@ NTSTATUS NtIo_DeleteFolderRecursively(POBJECT_ATTRIBUTES objattrs, bool (*cb)(co
|
|||
|
||||
NTSTATUS status = NtIo_DeleteFolderRecursivelyImpl(objattrs, cb, param);
|
||||
|
||||
if (NT_SUCCESS(status))
|
||||
if (NT_SUCCESS(status)) {
|
||||
NtIo_RemoveJunction(objattrs);
|
||||
status = NtDeleteFile(objattrs);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -31,15 +31,17 @@ typedef long NTSTATUS;
|
|||
|
||||
#include <winnt.h>
|
||||
|
||||
//struct SBoxedProcess
|
||||
//{
|
||||
//};
|
||||
struct SBoxedProcess
|
||||
{
|
||||
HANDLE Handle;
|
||||
};
|
||||
|
||||
CBoxedProcess::CBoxedProcess(quint32 ProcessId, class CSandBox* pBox)
|
||||
{
|
||||
m_pBox = pBox;
|
||||
|
||||
//m = new SBoxedProcess;
|
||||
m = new SBoxedProcess;
|
||||
m->Handle = NULL;
|
||||
|
||||
m_ProcessId = ProcessId;
|
||||
|
||||
|
@ -48,6 +50,7 @@ CBoxedProcess::CBoxedProcess(quint32 ProcessId, class CSandBox* pBox)
|
|||
|
||||
m_ProcessFlags = 0;
|
||||
m_ImageType = -1;
|
||||
m_ReturnCode = STATUS_PENDING;
|
||||
|
||||
m_uTerminated = 0;
|
||||
//m_bSuspended = IsSuspended();
|
||||
|
@ -57,7 +60,9 @@ CBoxedProcess::CBoxedProcess(quint32 ProcessId, class CSandBox* pBox)
|
|||
|
||||
CBoxedProcess::~CBoxedProcess()
|
||||
{
|
||||
//delete m;
|
||||
if (m->Handle)
|
||||
NtClose(m->Handle);
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
|
@ -225,10 +230,10 @@ bool CBoxedProcess::InitProcessInfo()
|
|||
ProcessHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)m_ProcessId);
|
||||
if (ProcessHandle == NULL)
|
||||
return false;
|
||||
m->Handle = ProcessHandle;
|
||||
|
||||
InitProcessInfoImpl(ProcessHandle);
|
||||
|
||||
NtClose(ProcessHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -300,6 +305,11 @@ SB_STATUS CBoxedProcess::Terminate()
|
|||
void CBoxedProcess::SetTerminated()
|
||||
{
|
||||
m_uTerminated = ::GetTickCount64();
|
||||
|
||||
DWORD ExitCode = 0;
|
||||
if (m->Handle)
|
||||
GetExitCodeProcess(m->Handle, &ExitCode);
|
||||
m_ReturnCode = ExitCode;
|
||||
}
|
||||
|
||||
bool CBoxedProcess::IsTerminated(quint64 forMs) const
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
virtual QDateTime GetTimeStamp() const { return m_StartTime; }
|
||||
virtual quint32 GetProcessFlags() const { return m_ProcessFlags; }
|
||||
virtual quint32 GetImageType() const { return m_ImageType; }
|
||||
virtual quint32 GetReturnCode() const { return m_ReturnCode; }
|
||||
|
||||
virtual SB_STATUS Terminate();
|
||||
virtual bool IsTerminated(quint64 forMs = 0) const;
|
||||
|
@ -74,6 +75,7 @@ protected:
|
|||
QString m_CommandLine;
|
||||
quint32 m_SessionId;
|
||||
QDateTime m_StartTime;
|
||||
quint32 m_ReturnCode;
|
||||
quint64 m_uTerminated;
|
||||
//bool m_bSuspended;
|
||||
bool m_bIsWoW64;
|
||||
|
@ -86,8 +88,8 @@ protected:
|
|||
|
||||
QHash<quint64, SSymbol> m_Symbols;
|
||||
|
||||
//private:
|
||||
// struct SBoxedProcess* m;
|
||||
private:
|
||||
struct SBoxedProcess* m;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<CBoxedProcess> CBoxedProcessPtr;
|
||||
|
|
|
@ -134,13 +134,13 @@ void CSandBox::SetBoxPaths(const QString& FilePath, const QString& RegPath, cons
|
|||
m_IpcPath = IpcPath;
|
||||
}
|
||||
|
||||
SB_STATUS CSandBox::RunStart(const QString& Command, bool Elevated, const QString& WorkingDir)
|
||||
SB_STATUS CSandBox::RunStart(const QString& Command, bool Elevated)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if ((QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) != 0)
|
||||
return RunSandboxed(Command);
|
||||
#endif
|
||||
return m_pAPI->RunStart(m_Name, Command, Elevated, WorkingDir);
|
||||
return m_pAPI->RunStart(m_Name, Command, Elevated);
|
||||
}
|
||||
|
||||
SB_STATUS CSandBox::RunSandboxed(const QString& Command)
|
||||
|
@ -230,6 +230,9 @@ SB_STATUS CSandBox__MoveFolder(const QString& SourcePath, const QString& ParentF
|
|||
|
||||
SB_STATUS CSandBox::RenameBox(const QString& NewName)
|
||||
{
|
||||
if (GetActiveProcessCount() > 0)
|
||||
return SB_ERR(SB_RemNotStopped);
|
||||
|
||||
if (NewName.compare(m_Name, Qt::CaseInsensitive) == 0)
|
||||
return SB_OK;
|
||||
|
||||
|
@ -244,9 +247,11 @@ SB_STATUS CSandBox::RenameBox(const QString& NewName)
|
|||
QString Name = FilePath.takeLast();
|
||||
if (Name.compare(m_Name, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
Status = CSandBox__MoveFolder(m_FilePath, FilePath.join("\\"), NewName);
|
||||
if (Status.IsError())
|
||||
return Status;
|
||||
//Status = CSandBox__MoveFolder(m_FilePath, FilePath.join("\\"), NewName);
|
||||
//if (Status.IsError())
|
||||
// return Status;
|
||||
if(!QDir().rename(m_FilePath, FilePath.join("\\") + "\\" + NewName))
|
||||
return SB_ERR(SB_FailedMoveDir, QVariantList() << m_FilePath << (FilePath.join("\\") + "\\" + NewName), 0xC0000001 /*STATUS_UNSUCCESSFUL*/);
|
||||
|
||||
QString FileRootPath = GetText("FileRootPath");
|
||||
if (!FileRootPath.isEmpty())
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
virtual int GetActiveProcessCount() const { return m_ActiveProcessCount; }
|
||||
|
||||
virtual SB_STATUS RunStart(const QString& Command, bool Elevated = false, const QString& WorkingDir = QString());
|
||||
virtual SB_STATUS RunStart(const QString& Command, bool Elevated = false);
|
||||
virtual SB_STATUS RunSandboxed(const QString& Command);
|
||||
virtual SB_STATUS TerminateAll();
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ __int64 CSbieIni::GetNum64(const QString& Setting, __int64 Default, bool bWithGl
|
|||
{
|
||||
QString StrValue = GetText(Setting, QString(), bWithGlobal, true, withTemplates);
|
||||
bool ok;
|
||||
__int64 Value = StrValue.toULongLong(&ok);
|
||||
__int64 Value = StrValue.toLongLong(&ok);
|
||||
if (!ok) return Default;
|
||||
return Value;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "SbieTemplates.h"
|
||||
#include "../SbieAPI.h"
|
||||
#include "../SbieUtils.h"
|
||||
|
||||
#include <ntstatus.h>
|
||||
#define WIN32_NO_STATUS
|
||||
|
@ -38,23 +39,116 @@ CSbieTemplates::CSbieTemplates(CSbieAPI* pAPI, QObject* paretn)
|
|||
InitExpandPaths(true);
|
||||
}
|
||||
|
||||
bool CSbieTemplates::RunCheck()
|
||||
void CSbieTemplates::RunCheck()
|
||||
{
|
||||
CollectObjects();
|
||||
CollectClasses();
|
||||
CollectServices();
|
||||
CollectProducts();
|
||||
|
||||
CollectTemplates();
|
||||
|
||||
QStringList Used = m_pAPI->GetGlobalSettings()->GetTextList("Template", false);
|
||||
QStringList Rejected = m_pAPI->GetGlobalSettings()->GetTextList("TemplateReject", false);
|
||||
|
||||
for(QMap<QString, int>::iterator I = m_Templates.begin(); I != m_Templates.end(); ++I)
|
||||
{
|
||||
int Value = eNone;
|
||||
if (Used.contains(I.key(), Qt::CaseInsensitive))
|
||||
Value |= eEnabled;
|
||||
if (CheckTemplate(I.key()))
|
||||
Value |= eRequired;
|
||||
if (Rejected.contains(I.key() , Qt::CaseInsensitive))
|
||||
Value |= eDisabled;
|
||||
I.value() = Value;
|
||||
}
|
||||
}
|
||||
|
||||
void CSbieTemplates::CollectTemplates()
|
||||
{
|
||||
m_Templates.clear();
|
||||
|
||||
QStringList Templates;
|
||||
Templates.append(GetTemplateNames("EmailReader"));
|
||||
Templates.append(GetTemplateNames("Print"));
|
||||
Templates.append(GetTemplateNames("Security"));
|
||||
Templates.append(GetTemplateNames("Desktop"));
|
||||
Templates.append(GetTemplateNames("Download"));
|
||||
Templates.append(GetTemplateNames("Misc"));
|
||||
Templates.append(GetTemplateNames("WebBrowser"));
|
||||
Templates.append(GetTemplateNames("MediaPlayer"));
|
||||
Templates.append(GetTemplateNames("TorrentClient"));
|
||||
|
||||
foreach(const QString& Template, Templates)
|
||||
m_Templates.insert(Template, 0);
|
||||
}
|
||||
|
||||
void CSbieTemplates::SetCheckResult(const QStringList& Result)
|
||||
{
|
||||
CollectTemplates();
|
||||
|
||||
QStringList Used = m_pAPI->GetGlobalSettings()->GetTextList("Template", false);
|
||||
QStringList Rejected = m_pAPI->GetGlobalSettings()->GetTextList("TemplateReject", false);
|
||||
|
||||
for(QMap<QString, int>::iterator I = m_Templates.begin(); I != m_Templates.end(); ++I)
|
||||
{
|
||||
int Value = eNone;
|
||||
if (Used.contains(I.key(), Qt::CaseInsensitive))
|
||||
Value |= eEnabled;
|
||||
if (Result.contains(I.key()))
|
||||
Value |= eRequired;
|
||||
if (Rejected.contains(I.key() , Qt::CaseInsensitive))
|
||||
Value |= eDisabled;
|
||||
I.value() = Value;
|
||||
}
|
||||
}
|
||||
|
||||
bool CSbieTemplates::GetCheckState()
|
||||
{
|
||||
for (QMap<QString, int>::iterator I = m_Templates.begin(); I != m_Templates.end(); ++I)
|
||||
{
|
||||
if ((I.value() & eRequired) != 0 && (I.value() & eConfigured) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSbieTemplates::Reset()
|
||||
{
|
||||
m_Objects.clear();
|
||||
m_Classes.clear();
|
||||
m_Services.clear();
|
||||
m_Products.clear();
|
||||
}
|
||||
|
||||
QStringList CSbieTemplates::GetObjects()
|
||||
{
|
||||
if (m_Objects.isEmpty())
|
||||
CollectObjects();
|
||||
return m_Objects;
|
||||
}
|
||||
|
||||
QStringList CSbieTemplates::GetClasses()
|
||||
{
|
||||
if (m_Classes.isEmpty())
|
||||
CollectClasses();
|
||||
return m_Classes;
|
||||
}
|
||||
|
||||
QStringList CSbieTemplates::GetServices()
|
||||
{
|
||||
if (m_Services.isEmpty())
|
||||
CollectServices();
|
||||
return m_Services;
|
||||
}
|
||||
|
||||
QStringList CSbieTemplates::GetProducts()
|
||||
{
|
||||
if (m_Products.isEmpty())
|
||||
CollectProducts();
|
||||
return m_Products;
|
||||
}
|
||||
|
||||
void CSbieTemplates::CollectObjects()
|
||||
{
|
||||
m_Objects.clear();
|
||||
|
@ -127,7 +221,7 @@ void CSbieTemplates::CollectObjects()
|
|||
if (i == 0)
|
||||
objdirs.append(objpath);
|
||||
else
|
||||
m_Objects.push_back(objpath.toLower().toStdWString());
|
||||
m_Objects.append(objpath.toLower());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +241,7 @@ void CSbieTemplates::CollectClasses()
|
|||
if (clsnm[0] && wcsncmp(clsnm, L"Sandbox:", 8) != 0)
|
||||
{
|
||||
_wcslwr(clsnm);
|
||||
((CSbieTemplates*)lparam)->m_Classes.push_back(clsnm);
|
||||
((CSbieTemplates*)lparam)->m_Classes.append(QString::fromWCharArray(clsnm));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -177,7 +271,7 @@ void CSbieTemplates::CollectServices()
|
|||
for (ULONG i = 0; i < num; ++i)
|
||||
{
|
||||
_wcslwr(info[i].lpServiceName);
|
||||
m_Services.push_back(info[i].lpServiceName);
|
||||
m_Services.append(QString::fromWCharArray(info[i].lpServiceName));
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
@ -215,7 +309,7 @@ void CSbieTemplates::CollectProducts()
|
|||
rc = RegEnumKeyEx(hkey, index, name, &name_len, NULL, NULL, NULL, NULL);
|
||||
if (rc == 0) {
|
||||
_wcslwr(name);
|
||||
m_Products.push_back(name);
|
||||
m_Products.append(QString::fromWCharArray(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,79 +355,6 @@ QStringList CSbieTemplates::GetTemplateNames(const QString& forClass)
|
|||
return list;
|
||||
}
|
||||
|
||||
void CSbieTemplates::CollectTemplates()
|
||||
{
|
||||
m_Templates.clear();
|
||||
|
||||
QStringList Templates;
|
||||
Templates.append(GetTemplateNames("EmailReader"));
|
||||
Templates.append(GetTemplateNames("Print"));
|
||||
Templates.append(GetTemplateNames("Security"));
|
||||
Templates.append(GetTemplateNames("Desktop"));
|
||||
Templates.append(GetTemplateNames("Download"));
|
||||
Templates.append(GetTemplateNames("Misc"));
|
||||
Templates.append(GetTemplateNames("WebBrowser"));
|
||||
Templates.append(GetTemplateNames("MediaPlayer"));
|
||||
Templates.append(GetTemplateNames("TorrentClient"));
|
||||
|
||||
foreach(const QString& Template, Templates)
|
||||
m_Templates.insert(Template, 0);
|
||||
|
||||
QStringList Used = m_pAPI->GetGlobalSettings()->GetTextList("Template", false);
|
||||
QStringList Rejected = m_pAPI->GetGlobalSettings()->GetTextList("TemplateReject", false);
|
||||
|
||||
for(QMap<QString, int>::iterator I = m_Templates.begin(); I != m_Templates.end(); ++I)
|
||||
{
|
||||
int Value = eNone;
|
||||
if (Used.contains(I.key(), Qt::CaseInsensitive))
|
||||
Value |= eEnabled;
|
||||
if (CheckTemplate(I.key()))
|
||||
Value |= eRequired;
|
||||
if (Rejected.contains(I.key() , Qt::CaseInsensitive))
|
||||
Value |= eDisabled;
|
||||
I.value() = Value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T* wildcmpex(const T* Wild, const T* Str)
|
||||
{
|
||||
const T *cp = NULL, *mp = NULL;
|
||||
|
||||
while ((*Str) && (*Wild != '*'))
|
||||
{
|
||||
if ((*Wild != *Str) && (*Wild != '?'))
|
||||
return NULL;
|
||||
Wild++;
|
||||
Str++;
|
||||
}
|
||||
|
||||
while (*Str)
|
||||
{
|
||||
if (*Wild == '*')
|
||||
{
|
||||
if (!*++Wild)
|
||||
return Str;
|
||||
mp = Wild;
|
||||
cp = Str + 1;
|
||||
}
|
||||
else if ((*Wild == *Str) || (*Wild == '?'))
|
||||
{
|
||||
Wild++;
|
||||
Str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Wild = mp;
|
||||
Str = cp++;
|
||||
}
|
||||
}
|
||||
|
||||
while (*Wild == '*')
|
||||
Wild++;
|
||||
return *Wild ? NULL : Str;
|
||||
}
|
||||
|
||||
bool CSbieTemplates::CheckTemplate(const QString& Name)
|
||||
{
|
||||
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni("Template_" + Name, m_pAPI));
|
||||
|
@ -345,53 +366,13 @@ bool CSbieTemplates::CheckTemplate(const QString& Name)
|
|||
if (!(scanIpc || scanWin || scanSvc))
|
||||
return false;
|
||||
|
||||
std::list<std::wstring> Keys, Files;
|
||||
QList<QPair<QString, QString>> settings = pTemplate->GetIniSection(0, true);
|
||||
for(QList<QPair<QString, QString>>::iterator I = settings.begin(); I != settings.end(); ++I)
|
||||
{
|
||||
QString setting = I->first;
|
||||
|
||||
std::list<std::wstring> *List = NULL;
|
||||
if (scanIpc && setting.compare("OpenIpcPath", Qt::CaseInsensitive) == 0)
|
||||
List = &m_Objects;
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanIpc", Qt::CaseInsensitive) == 0)
|
||||
List = &m_Objects;
|
||||
else if (scanWin && setting.compare("OpenWinClass", Qt::CaseInsensitive) == 0)
|
||||
List = &m_Classes;
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanWinClass", Qt::CaseInsensitive) == 0)
|
||||
List = &m_Classes;
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanService", Qt::CaseInsensitive) == 0)
|
||||
List = &m_Services;
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanProduct", Qt::CaseInsensitive) == 0)
|
||||
List = &m_Products;
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanKey", Qt::CaseInsensitive) == 0)
|
||||
List = &Keys;
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanFile", Qt::CaseInsensitive) == 0)
|
||||
List = &Files;
|
||||
else
|
||||
continue;
|
||||
|
||||
QString value = I->second;
|
||||
if(!value.isEmpty())
|
||||
{
|
||||
if (List == &Keys) {
|
||||
if (CheckRegistryKey(value))
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
else if (List == &Files) {
|
||||
if (CheckFile(value))
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip to unspecific entries
|
||||
if (List == &m_Classes)
|
||||
{
|
||||
if(value.left(2).compare("*:") == 0)
|
||||
continue;
|
||||
}
|
||||
if (List == &m_Objects)
|
||||
if (scanIpc && ((setting.compare("OpenIpcPath", Qt::CaseInsensitive) == 0) || setting.compare("Tmpl.ScanIpc", Qt::CaseInsensitive) == 0))
|
||||
{
|
||||
if (value.compare("\\RPC Control\\epmapper") == 0)
|
||||
continue;
|
||||
|
@ -401,15 +382,38 @@ bool CSbieTemplates::CheckTemplate(const QString& Name)
|
|||
continue;
|
||||
if (value.compare("*\\BaseNamedObjects*\\NamedBuffer*mAH*Process*API*") == 0)
|
||||
continue;
|
||||
}
|
||||
//
|
||||
|
||||
std::wstring wild = value.toLower().toStdWString();
|
||||
for (std::list<std::wstring>::iterator I = List->begin(); I != List->end(); ++I)
|
||||
{
|
||||
if (wildcmpex(wild.c_str(), I->c_str()) != NULL)
|
||||
if (CheckObjects(value))
|
||||
return true;
|
||||
}
|
||||
else if (scanWin && ((setting.compare("OpenWinClass", Qt::CaseInsensitive) == 0 || setting.compare("Tmpl.ScanWinClass", Qt::CaseInsensitive) == 0)))
|
||||
{
|
||||
// skip to unspecific entries
|
||||
if(value.left(2).compare("*:") == 0)
|
||||
continue;
|
||||
|
||||
if (CheckClasses(value))
|
||||
return true;
|
||||
}
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanService", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
if (CheckServices(value))
|
||||
return true;
|
||||
}
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanProduct", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
if (CheckProducts(value))
|
||||
return true;
|
||||
}
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanKey", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
if (CheckRegistryKey(value))
|
||||
return true;
|
||||
}
|
||||
else if (scanSvc && setting.compare("Tmpl.ScanFile", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
if (CheckFile(ExpandPath(value)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,12 +441,56 @@ bool CSbieTemplates::CheckRegistryKey(const QString& Value)
|
|||
|
||||
bool CSbieTemplates::CheckFile(const QString& Value)
|
||||
{
|
||||
std::wstring path = ExpandPath(Value).toStdWString();
|
||||
std::wstring path = Value.toStdWString();
|
||||
if (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSbieTemplates::CheckClasses(const QString& value)
|
||||
{
|
||||
QString Value = value.toLower();
|
||||
for (auto I = m_Classes.begin(); I != m_Classes.end(); ++I)
|
||||
{
|
||||
if (CSbieUtils::WildCompare(Value, *I))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSbieTemplates::CheckServices(const QString& value)
|
||||
{
|
||||
QString Value = value.toLower();
|
||||
for (auto I = m_Services.begin(); I != m_Services.end(); ++I)
|
||||
{
|
||||
if (CSbieUtils::WildCompare(Value, *I))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSbieTemplates::CheckProducts(const QString& value)
|
||||
{
|
||||
QString Value = value.toLower();
|
||||
for (auto I = m_Products.begin(); I != m_Products.end(); ++I)
|
||||
{
|
||||
if (CSbieUtils::WildCompare(Value, *I))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSbieTemplates::CheckObjects(const QString& value)
|
||||
{
|
||||
QString Value = value.toLower();
|
||||
for (auto I = m_Objects.begin(); I != m_Objects.end(); ++I)
|
||||
{
|
||||
if (CSbieUtils::WildCompare(Value, *I))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSbieTemplates::InitExpandPaths(bool WithUser)
|
||||
{
|
||||
std::wstring keyPath(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\");
|
||||
|
|
|
@ -11,7 +11,9 @@ class QSBIEAPI_EXPORT CSbieTemplates : public QObject
|
|||
public:
|
||||
CSbieTemplates(class CSbieAPI* pAPI, QObject* paretn = 0);
|
||||
|
||||
bool RunCheck();
|
||||
void RunCheck();
|
||||
void SetCheckResult(const QStringList& Result);
|
||||
bool GetCheckState();
|
||||
|
||||
enum EStates
|
||||
{
|
||||
|
@ -22,8 +24,24 @@ public:
|
|||
eConfigured = eEnabled | eDisabled
|
||||
};
|
||||
|
||||
void Reset();
|
||||
|
||||
QStringList GetObjects();
|
||||
QStringList GetClasses();
|
||||
QStringList GetServices();
|
||||
QStringList GetProducts();
|
||||
QMap<QString, int> GetTemplates() { return m_Templates; }
|
||||
|
||||
|
||||
QString ExpandPath(QString path);
|
||||
|
||||
bool CheckRegistryKey(const QString& Value);
|
||||
bool CheckFile(const QString& Value);
|
||||
bool CheckClasses(const QString& Value);
|
||||
bool CheckServices(const QString& Value);
|
||||
bool CheckProducts(const QString& Value);
|
||||
bool CheckObjects(const QString& Value);
|
||||
|
||||
protected:
|
||||
void CollectObjects();
|
||||
void CollectClasses();
|
||||
|
@ -34,16 +52,13 @@ protected:
|
|||
QStringList GetTemplateNames(const QString& forClass);
|
||||
|
||||
bool CheckTemplate(const QString& Name);
|
||||
bool CheckRegistryKey(const QString& Value);
|
||||
bool CheckFile(const QString& Value);
|
||||
|
||||
void InitExpandPaths(bool WithUser);
|
||||
QString ExpandPath(QString path);
|
||||
|
||||
std::list<std::wstring> m_Objects;
|
||||
std::list<std::wstring> m_Classes;
|
||||
std::list<std::wstring> m_Services;
|
||||
std::list<std::wstring> m_Products;
|
||||
QStringList m_Objects;
|
||||
QStringList m_Classes;
|
||||
QStringList m_Services;
|
||||
QStringList m_Products;
|
||||
|
||||
QMap<QString, int> m_Templates;
|
||||
|
||||
|
|
|
@ -133,8 +133,8 @@ CSbieAPI::CSbieAPI(QObject* parent) : QThread(parent)
|
|||
{
|
||||
m = new SSbieAPI();
|
||||
|
||||
m_pGlobalSection = new CSbieIni("GlobalSettings", this, this);
|
||||
m_pUserSection = new CSbieIni("UserSettings", this, this); // dummy
|
||||
m_pGlobalSection = QSharedPointer<CSbieIni>(new CSbieIni("GlobalSettings", this));
|
||||
m_pUserSection = QSharedPointer<CSbieIni>(new CSbieIni("UserSettings", this)); // dummy
|
||||
|
||||
m_IniReLoad = false;
|
||||
m_bReloadPending = false;
|
||||
|
@ -324,7 +324,7 @@ SB_STATUS CSbieAPI::Connect(bool takeOver, bool withQueue)
|
|||
if (m_UserName.isEmpty()) {
|
||||
QString UserSection = GetUserSection(&m_UserName);
|
||||
if(!UserSection.isEmpty())
|
||||
m_pUserSection = new CSbieIni(UserSection, this, this);
|
||||
m_pUserSection = QSharedPointer<CSbieIni>(new CSbieIni(UserSection, this));
|
||||
}
|
||||
|
||||
if (m_UserDir.isEmpty()) {
|
||||
|
@ -745,20 +745,6 @@ SB_STATUS CSbieAPI::CallServer(void* req, SScopedVoid* prpl) const
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*void CSbieAPI::OnMonitorEntry(quint32 ProcessId, quint32 Type, const QString& Value)
|
||||
{
|
||||
QMap<quint32, CBoxedProcessPtr>::iterator I = m_BoxedProxesses.find(ProcessId);
|
||||
if (I == m_BoxedProxesses.end())
|
||||
{
|
||||
UpdateProcesses(true);
|
||||
I = m_BoxedProxesses.find(ProcessId);
|
||||
}
|
||||
if (I == m_BoxedProxesses.end())
|
||||
return;
|
||||
|
||||
I.value()->AddResourceEntry(Type, Value);
|
||||
}*/
|
||||
|
||||
QString CSbieAPI::GetVersion()
|
||||
{
|
||||
WCHAR out_version[16];
|
||||
|
@ -1033,7 +1019,7 @@ QString CSbieAPI::GetUserSection(QString* pUserName, bool* pIsAdmin) const
|
|||
return UserSection;
|
||||
}
|
||||
|
||||
SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, bool Elevated, const QString& WorkingDir, QProcess* pProcess)
|
||||
SB_RESULT(quint32) CSbieAPI::RunStart(const QString& BoxName, const QString& Command, bool Elevated, const QString& WorkingDir, QProcess* pProcess)
|
||||
{
|
||||
if (m_SbiePath.isEmpty())
|
||||
return SB_ERR(SB_PathFail);
|
||||
|
@ -1106,7 +1092,7 @@ SB_STATUS CSbieAPI::RunStart(const QString& BoxName, const QString& Command, boo
|
|||
|
||||
if(pid == 0)
|
||||
return SB_ERR();
|
||||
return SB_OK;
|
||||
return CSbieResult<quint32>((quint32)pid);
|
||||
}
|
||||
|
||||
QString CSbieAPI::GetStartPath() const
|
||||
|
@ -1144,7 +1130,7 @@ SB_STATUS CSbieAPI::ReloadBoxes(bool bForceUpdate)
|
|||
m_SandBoxes.insert(BoxName.toLower(), pBox);
|
||||
emit BoxAdded(pBox);
|
||||
}
|
||||
UpdateBoxPaths(pBox);
|
||||
UpdateBoxPaths(pBox.data());
|
||||
|
||||
pBox->m_IsEnabled = bIsEnabled;
|
||||
|
||||
|
@ -1346,6 +1332,18 @@ SB_STATUS CSbieAPI::ValidateName(const QString& BoxName)
|
|||
return SB_OK;
|
||||
}
|
||||
|
||||
QString CSbieAPI::MkNewName(QString Name)
|
||||
{
|
||||
Name.replace(QRegularExpression("[<>:\"/\\\\|?*\\[\\]]"), "-").replace(" ", "_");
|
||||
for (int i=0;; i++) {
|
||||
QString NewName = Name;
|
||||
if (i > 0) NewName.append("_" + QString::number(i));
|
||||
if (m_SandBoxes.contains(NewName.toLower()))
|
||||
continue;
|
||||
return NewName;
|
||||
}
|
||||
}
|
||||
|
||||
SB_STATUS CSbieAPI::CreateBox(const QString& BoxName, bool bReLoad)
|
||||
{
|
||||
SB_STATUS Status = ValidateName(BoxName);
|
||||
|
@ -1390,7 +1388,7 @@ SB_STATUS CSbieAPI__GetProcessPIDs(SSbieAPI* m, const QString& BoxName, bool bAl
|
|||
return SB_OK;
|
||||
}
|
||||
|
||||
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions)
|
||||
SB_STATUS CSbieAPI::UpdateProcesses(int iKeep, bool bAllSessions)
|
||||
{
|
||||
ULONG count = 0;
|
||||
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, "", bAllSessions, NULL, &count); // query count
|
||||
|
@ -1427,6 +1425,7 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions)
|
|||
if (pBox->m_ActiveProcessCount == 0) {
|
||||
pBox->m_ActiveProcessCount = 1;
|
||||
pBox->OpenBox();
|
||||
m_bBoxesDirty = true;
|
||||
emit BoxOpened(pBox);
|
||||
}
|
||||
|
||||
|
@ -1447,7 +1446,7 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions)
|
|||
pProcess->SetTerminated();
|
||||
pProcess->m_pBox->m_ActiveProcessDirty = true;
|
||||
}
|
||||
else if (!bKeep && pProcess->IsTerminated(1500)) { // keep for at least 1.5 seconds
|
||||
else if (iKeep != -1 && pProcess->IsTerminated(iKeep)) {
|
||||
pProcess->m_pBox->m_ProcessList.remove(pProcess->m_ProcessId);
|
||||
m_BoxedProxesses.remove(pProcess->m_ProcessId);
|
||||
}
|
||||
|
@ -1467,6 +1466,7 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions)
|
|||
pBox->m_ActiveProcessCount = ActiveProcessCount;
|
||||
if (WasBoxClosed) {
|
||||
pBox->CloseBox();
|
||||
m_bBoxesDirty = true;
|
||||
emit BoxClosed(pBox);
|
||||
}
|
||||
}
|
||||
|
@ -1476,69 +1476,6 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions)
|
|||
return SB_OK;
|
||||
}
|
||||
|
||||
/*SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep)
|
||||
{
|
||||
foreach(const CSandBoxPtr& pBox, m_SandBoxes)
|
||||
UpdateProcesses(bKeep, pBox);
|
||||
return SB_OK;
|
||||
}
|
||||
|
||||
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox)
|
||||
{
|
||||
ULONG count = 0;
|
||||
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, pBox->GetName(), NULL, &count); // query the count
|
||||
if (Status.IsError())
|
||||
return Status;
|
||||
|
||||
count += 128; // add some extra space
|
||||
ULONG* boxed_pids = new ULONG[count];
|
||||
|
||||
Status = CSbieAPI__GetProcessPIDs(m, pBox->GetName(), boxed_pids, &count); // query the count
|
||||
if (Status.IsError())
|
||||
goto finish;
|
||||
|
||||
QMap<quint32, CBoxedProcessPtr> OldProcessList = pBox->m_ProcessList;
|
||||
|
||||
for (int i=0; i < count; i++)
|
||||
{
|
||||
quint32 ProcessId = boxed_pids[i];
|
||||
|
||||
CBoxedProcessPtr pProcess = OldProcessList.take(ProcessId);
|
||||
if (!pProcess)
|
||||
{
|
||||
pProcess = CBoxedProcessPtr(NewBoxedProcess(ProcessId, pBox.data()));
|
||||
pBox->m_ProcessList.insert(ProcessId, pProcess);
|
||||
m_BoxedProxesses.insert(ProcessId, pProcess);
|
||||
|
||||
UpdateProcessInfo(pProcess);
|
||||
pProcess->InitProcessInfo();
|
||||
}
|
||||
|
||||
pProcess->InitProcessInfoEx();
|
||||
}
|
||||
|
||||
foreach(const CBoxedProcessPtr& pProcess, OldProcessList)
|
||||
{
|
||||
if (!pProcess->IsTerminated())
|
||||
pProcess->SetTerminated();
|
||||
else if (!bKeep && pProcess->IsTerminated(1500)) { // keep for at least 1.5 seconds
|
||||
pBox->m_ProcessList.remove(pProcess->m_ProcessId);
|
||||
m_BoxedProxesses.remove(pProcess->m_ProcessId);
|
||||
}
|
||||
}
|
||||
|
||||
bool WasBoxClosed = pBox->m_ActiveProcessCount > 0 && count == 0;
|
||||
pBox->m_ActiveProcessCount = count;
|
||||
if (WasBoxClosed) {
|
||||
pBox->CloseBox();
|
||||
emit BoxClosed(pBox->GetName());
|
||||
}
|
||||
|
||||
finish:
|
||||
delete[] boxed_pids;
|
||||
return Status;
|
||||
}*/
|
||||
|
||||
bool CSbieAPI::HasProcesses(const QString& BoxName)
|
||||
{
|
||||
ULONG count;
|
||||
|
@ -1576,7 +1513,7 @@ SB_STATUS CSbieAPI__QueryBoxPath(SSbieAPI* m, const WCHAR *box_name, WCHAR *out_
|
|||
return SB_OK;
|
||||
}
|
||||
|
||||
SB_STATUS CSbieAPI::UpdateBoxPaths(const CSandBoxPtr& pSandBox)
|
||||
SB_STATUS CSbieAPI::UpdateBoxPaths(CSandBox* pSandBox)
|
||||
{
|
||||
std::wstring boxName = pSandBox->GetName().toStdWString();
|
||||
|
||||
|
@ -2380,6 +2317,7 @@ CBoxedProcessPtr CSbieAPI::OnProcessBoxed(quint32 ProcessId, const QString& Path
|
|||
if (pBox->m_ActiveProcessCount == 0) {
|
||||
pBox->m_ActiveProcessCount = 1;
|
||||
pBox->OpenBox();
|
||||
m_bBoxesDirty = true;
|
||||
emit BoxOpened(pBox);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,10 +60,10 @@ public:
|
|||
|
||||
virtual SB_STATUS ReloadBoxes(bool bForceUpdate = false);
|
||||
static SB_STATUS ValidateName(const QString& BoxName);
|
||||
virtual QString MkNewName(QString Name);
|
||||
virtual SB_STATUS CreateBox(const QString& BoxName, bool bReLoad = true);
|
||||
|
||||
virtual SB_STATUS UpdateProcesses(bool bKeep, bool bAllSessions);
|
||||
//virtual SB_STATUS UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox);
|
||||
virtual SB_STATUS UpdateProcesses(int iKeep, bool bAllSessions);
|
||||
|
||||
virtual QMap<QString, CSandBoxPtr> GetAllBoxes() { return m_SandBoxes; }
|
||||
virtual QMap<quint32, CBoxedProcessPtr> GetAllProcesses() { return m_BoxedProxesses; }
|
||||
|
@ -98,8 +98,8 @@ public:
|
|||
virtual QString SbieIniGetEx(const QString& Section, const QString& Setting);
|
||||
virtual SB_STATUS SbieIniSet(const QString& Section, const QString& Setting, const QString& Value, ESetMode Mode = eIniUpdate, bool bRefresh = true);
|
||||
virtual bool IsBox(const QString& BoxName, bool& bIsEnabled);
|
||||
virtual CSbieIni* GetGlobalSettings() const { return m_pGlobalSection; }
|
||||
virtual CSbieIni* GetUserSettings() const { return m_pUserSection; }
|
||||
virtual QSharedPointer<CSbieIni> GetGlobalSettings() const { return m_pGlobalSection; }
|
||||
virtual QSharedPointer<CSbieIni> GetUserSettings() const { return m_pUserSection; }
|
||||
virtual QString GetCurrentUserName() const { return m_UserName; }
|
||||
virtual QString GetCurrentUserSid() const { return m_UserSid; }
|
||||
virtual bool IsConfigLocked();
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
|
||||
virtual QString GetSbieMsgStr(quint32 code, quint32 Lang = 1033);
|
||||
|
||||
virtual SB_STATUS RunStart(const QString& BoxName, const QString& Command, bool Elevated = false, const QString& WorkingDir = QString(), QProcess* pProcess = NULL);
|
||||
virtual SB_RESULT(quint32) RunStart(const QString& BoxName, const QString& Command, bool Elevated = false, const QString& WorkingDir = QString(), QProcess* pProcess = NULL);
|
||||
virtual QString GetStartPath() const;
|
||||
|
||||
virtual quint32 GetSessionID() const;
|
||||
|
@ -181,7 +181,6 @@ signals:
|
|||
void QueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 RequestId, const QVariantMap& Data);
|
||||
|
||||
protected slots:
|
||||
//virtual void OnMonitorEntry(quint32 ProcessId, quint32 Type, const QString& Value);
|
||||
virtual void OnIniChanged(const QString &path);
|
||||
virtual void OnReloadConfig();
|
||||
virtual CBoxedProcessPtr OnProcessBoxed(quint32 ProcessId, const QString& Path, const QString& Box, quint32 ParentId, const QString& CmdLine);
|
||||
|
@ -210,7 +209,7 @@ protected:
|
|||
|
||||
virtual SB_STATUS RunSandboxed(const QString& BoxName, const QString& Command, QString WrkDir = QString(), quint32 Flags = 0);
|
||||
|
||||
virtual SB_STATUS UpdateBoxPaths(const CSandBoxPtr& pSandBox);
|
||||
virtual SB_STATUS UpdateBoxPaths(CSandBox* pSandBox);
|
||||
virtual SB_STATUS UpdateProcessInfo(const CBoxedProcessPtr& pProcess);
|
||||
|
||||
virtual void GetUserPaths();
|
||||
|
@ -251,8 +250,8 @@ protected:
|
|||
bool m_bWithQueue;
|
||||
bool m_bTerminate;
|
||||
|
||||
CSbieIni* m_pGlobalSection;
|
||||
CSbieIni* m_pUserSection;
|
||||
QSharedPointer<CSbieIni>m_pGlobalSection;
|
||||
QSharedPointer<CSbieIni>m_pUserSection;
|
||||
QString m_UserName;
|
||||
QString m_UserSid;
|
||||
|
||||
|
|
|
@ -29,9 +29,11 @@ enum ESbieMsgCodes
|
|||
SB_DeleteProtect,
|
||||
SB_DeleteNotEmpty,
|
||||
SB_DeleteError,
|
||||
SB_RemNotStopped,
|
||||
//SB_RemNotEmpty,
|
||||
SB_DelNotEmpty,
|
||||
SB_FailedMoveDir,
|
||||
SB_FailedMoveImage,
|
||||
SB_SnapMkDirFail,
|
||||
SB_SnapCopyDatFail,
|
||||
SB_SnapNotFound,
|
||||
|
@ -46,6 +48,10 @@ enum ESbieMsgCodes
|
|||
SB_NameExists,
|
||||
SB_PasswordBad,
|
||||
SB_Canceled,
|
||||
SB_DeleteNoMount,
|
||||
|
||||
SB_OtherError,
|
||||
|
||||
SB_LastError
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,54 @@ typedef long NTSTATUS;
|
|||
|
||||
#include "SbieAPI.h"
|
||||
|
||||
template <typename T>
|
||||
__forceinline bool charIsNull(const T* v) { return *v == 0; }
|
||||
__forceinline bool charIsNull(const QChar* v) { return v->isNull(); }
|
||||
|
||||
template <typename T>
|
||||
bool wildcmpex(const T* Wild, const T* Str)
|
||||
{
|
||||
const T *cp = NULL, *mp = NULL;
|
||||
|
||||
while (!charIsNull(Str) && (*Wild != '*'))
|
||||
{
|
||||
if ((*Wild != *Str) && (*Wild != '?'))
|
||||
return false;
|
||||
Wild++;
|
||||
Str++;
|
||||
}
|
||||
|
||||
while (!charIsNull(Str))
|
||||
{
|
||||
if (*Wild == '*')
|
||||
{
|
||||
if (charIsNull(++Wild))
|
||||
return Str;
|
||||
mp = Wild;
|
||||
cp = Str + 1;
|
||||
}
|
||||
else if ((*Wild == *Str) || (*Wild == '?'))
|
||||
{
|
||||
Wild++;
|
||||
Str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Wild = mp;
|
||||
Str = cp++;
|
||||
}
|
||||
}
|
||||
|
||||
while (*Wild == '*')
|
||||
Wild++;
|
||||
return charIsNull(Wild);
|
||||
}
|
||||
|
||||
bool CSbieUtils::WildCompare(const QString& L, const QString& R)
|
||||
{
|
||||
return wildcmpex(L.data(), R.data());
|
||||
}
|
||||
|
||||
int GetServiceStatus(const wchar_t* name)
|
||||
{
|
||||
SC_HANDLE scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_ENUMERATE_SERVICE);
|
||||
|
@ -442,10 +490,8 @@ void CSbieUtils::RemoveContextMenu2()
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Shortcuts
|
||||
|
||||
bool CSbieUtils::CreateShortcut(CSbieAPI* pApi, QString LinkPath, const QString &LinkName, const QString &boxname, const QString &arguments, const QString &iconPath, int iconIndex, const QString &workdir, bool bRunElevated)
|
||||
bool CSbieUtils::CreateShortcut(const QString& StartExe, QString LinkPath, const QString &LinkName, const QString &boxname, const QString &arguments, const QString &iconPath, int iconIndex, const QString &workdir, bool bRunElevated)
|
||||
{
|
||||
QString StartExe = pApi->GetStartPath();
|
||||
|
||||
QString StartArgs;
|
||||
if (bRunElevated)
|
||||
StartArgs += "/elevated ";
|
||||
|
@ -475,7 +521,7 @@ bool CSbieUtils::CreateShortcut(CSbieAPI* pApi, QString LinkPath, const QString
|
|||
if (!workdir.isEmpty())
|
||||
pShellLink->SetWorkingDirectory(workdir.toStdWString().c_str());
|
||||
if (!LinkName.isEmpty()) {
|
||||
QString desc = QString("%1 [%2]").arg(LinkName).arg(boxname.isEmpty() ? pApi->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox") : boxname);
|
||||
QString desc = QString("%1 [%2]").arg(LinkName).arg(boxname);
|
||||
pShellLink->SetDescription(desc.toStdWString().c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ public:
|
|||
eAll = 0xFF
|
||||
};
|
||||
|
||||
static bool WildCompare(const QString& L, const QString& R);
|
||||
|
||||
static SB_STATUS DoAssist();
|
||||
|
||||
static SB_RESULT(void*) Start(EComponent Component);
|
||||
|
@ -34,7 +36,7 @@ public:
|
|||
static void AddContextMenu2(const QString& StartPath, const QString& RunStr, const QString& IconPath = QString());
|
||||
static void RemoveContextMenu2();
|
||||
|
||||
static bool CreateShortcut(class CSbieAPI* pApi, QString LinkPath, const QString &LinkName, const QString &boxname, const QString &arguments, const QString &iconPath = QString(), int iconIndex = 0, const QString &workdir = QString(), bool bRunElevated = false);
|
||||
static bool CreateShortcut(const QString& StartExe, QString LinkPath, const QString &LinkName, const QString &boxname, const QString &arguments, const QString &iconPath = QString(), int iconIndex = 0, const QString &workdir = QString(), bool bRunElevated = false);
|
||||
static bool GetStartMenuShortcut(class CSbieAPI* pApi, QString &BoxName, QString &LinkPath, QString &IconPath, quint32& IconIndex, QString &WorkDir);
|
||||
|
||||
static CSbieProgressPtr RunCommand(const QString& Command, bool noGui = false);
|
||||
|
|
|
@ -0,0 +1,444 @@
|
|||
#include "stdafx.h"
|
||||
#include "AddonManager.h"
|
||||
#include "SandMan.h"
|
||||
#include "OnlineUpdater.h"
|
||||
#include "../MiscHelpers/Common/Common.h"
|
||||
#include "../MiscHelpers/Common/OtherFunctions.h"
|
||||
#include <QUrlQuery>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include "QSbieAPI/Sandboxie/SbieTemplates.h"
|
||||
#include <QtConcurrent>
|
||||
#include "../MiscHelpers/Archive/Archive.h"
|
||||
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
CAddonManager::CAddonManager(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CAddonManager::UpdateAddons()
|
||||
{
|
||||
theGUI->m_pUpdater->GetUpdates(this, SLOT(OnUpdateData(const QVariantMap&, const QVariantMap&)));
|
||||
}
|
||||
|
||||
void CAddonManager::OnUpdateData(const QVariantMap& Data, const QVariantMap& Params)
|
||||
{
|
||||
if (Data.isEmpty() || Data["error"].toBool())
|
||||
return;
|
||||
|
||||
QVariantMap Addons = Data["addons"].toMap();
|
||||
|
||||
QJsonDocument doc(QJsonValue::fromVariant(Addons).toObject());
|
||||
WriteStringToFile(theConf->GetConfigDir() + "/addons.json", doc.toJson());
|
||||
|
||||
LoadAddons();
|
||||
emit DataUpdated();
|
||||
}
|
||||
|
||||
QList<CAddonPtr> CAddonManager::GetAddons()
|
||||
{
|
||||
if (m_Addons.isEmpty()) {
|
||||
if (!LoadAddons())
|
||||
UpdateAddons();
|
||||
}
|
||||
else {
|
||||
foreach(const CAddonPtr& pAddon, m_Addons)
|
||||
pAddon->Installed = CheckAddon(pAddon);
|
||||
}
|
||||
return m_Addons;
|
||||
}
|
||||
|
||||
bool CAddonManager::LoadAddons()
|
||||
{
|
||||
m_Addons.clear();
|
||||
|
||||
QString AddonPath = theConf->GetConfigDir() + "/addons.json";
|
||||
QVariantMap Data = QJsonDocument::fromJson(ReadFileAsString(AddonPath).toUtf8()).toVariant().toMap();
|
||||
foreach(const QVariant vAddon, Data["list"].toList()) {
|
||||
CAddonPtr pAddon = CAddonPtr(new CAddon(vAddon.toMap()));
|
||||
pAddon->Installed = CheckAddon(pAddon);
|
||||
m_Addons.append(pAddon);
|
||||
}
|
||||
|
||||
return !m_Addons.isEmpty();
|
||||
}
|
||||
|
||||
CAddonPtr CAddonManager::GetAddon(const QString& Id)
|
||||
{
|
||||
if (m_Addons.isEmpty())
|
||||
LoadAddons();
|
||||
|
||||
foreach(const CAddonPtr& pAddon, m_Addons) {
|
||||
if (pAddon->Id.compare(Id, Qt::CaseInsensitive) == 0) {
|
||||
pAddon->Installed = CheckAddon(pAddon);
|
||||
return pAddon;
|
||||
}
|
||||
}
|
||||
return CAddonPtr();
|
||||
}
|
||||
|
||||
bool CAddonManager::HasAddon(const QString& Id)
|
||||
{
|
||||
CAddonPtr pAddon = GetAddon("FileChecker");
|
||||
return pAddon && pAddon->Installed;
|
||||
}
|
||||
|
||||
bool CAddonManager::CheckAddon(const CAddonPtr& pAddon)
|
||||
{
|
||||
QString Key = pAddon->GetSpecificEntry("uninstall_key").toString();
|
||||
if (!Key.isEmpty()) {
|
||||
QSettings settings(Key, QSettings::NativeFormat);
|
||||
QString Uninstall = settings.value("UninstallString").toString();
|
||||
return !Uninstall.isEmpty();
|
||||
}
|
||||
|
||||
QStringList Files = pAddon->GetSpecificEntry("files").toStringList();
|
||||
foreach(const QString & File, Files) {
|
||||
if (theGUI->GetCompat()->CheckFile(ExpandPath(File)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SB_PROGRESS CAddonManager::TryInstallAddon(const QString& Id, QWidget* pParent, const QString& Prompt)
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", Prompt.isEmpty() ? tr("Do you want to download and install %1?").arg(Id) : Prompt,
|
||||
QMessageBox::Question, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton, pParent ? pParent : theGUI).exec() != QMessageBox::Yes)
|
||||
return SB_ERR(SB_OtherError);
|
||||
|
||||
SB_PROGRESS Status = InstallAddon(Id);
|
||||
if (Status.GetStatus() == OP_ASYNC)
|
||||
theGUI->AddAsyncOp(Status.GetValue(), false, tr("Installing: %1").arg(Id), pParent);
|
||||
else
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, pParent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
SB_PROGRESS CAddonManager::InstallAddon(const QString& Id)
|
||||
{
|
||||
CAddonPtr pAddon = GetAddon(Id);
|
||||
if (!pAddon)
|
||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon not found, please try updating the addon list in the global settings!"));
|
||||
if (pAddon->Installed)
|
||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon already installed!"));
|
||||
|
||||
QString Entry;
|
||||
QString Url = pAddon->GetSpecificEntry("download", &Entry).toString();
|
||||
if (Url.isEmpty())
|
||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon has no download url, addon may not be available for your platform."));
|
||||
|
||||
QVariantMap Params;
|
||||
Params["name"] = Id;
|
||||
Params["path"] = theGUI->m_pUpdater->GetUpdateDir(true) + "/" + QUrl(Url).fileName();
|
||||
Params["signature"] = pAddon->Data.value(Entry + "_sig");
|
||||
theGUI->m_pUpdater->DownloadFile(Url, this, SLOT(OnAddonDownloaded(const QString&, const QVariantMap&)), Params);
|
||||
|
||||
pAddon->pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
connect(pAddon->pProgress.data(), SIGNAL(Finished()), this, SIGNAL(AddonInstalled()));
|
||||
pAddon->pProgress->ShowMessage(tr("Downloading Addon %1").arg(pAddon->Id));
|
||||
return SB_PROGRESS(OP_ASYNC, pAddon->pProgress);
|
||||
}
|
||||
|
||||
extern "C" NTSTATUS VerifyFileSignatureImpl(const wchar_t* FilePath, PVOID Signature, ULONG SignatureSize);
|
||||
|
||||
void CAddonManager::OnAddonDownloaded(const QString& Path, const QVariantMap& Params)
|
||||
{
|
||||
CAddonPtr pAddon = GetAddon(Params["name"].toString());
|
||||
|
||||
QByteArray Signature = QByteArray::fromBase64(Params["signature"].toByteArray());
|
||||
|
||||
if (VerifyFileSignatureImpl(QString(Path).replace("/","\\").toStdWString().c_str(), Signature.data(), Signature.size()) < 0) { // !NT_SUCCESS
|
||||
pAddon->pProgress->Finish(SB_ERR(SB_OtherError, QVariantList() << tr("Download signature is not valid!")));
|
||||
pAddon->pProgress.create();
|
||||
return;
|
||||
}
|
||||
|
||||
pAddon->pProgress->ShowMessage(tr("Installing Addon %1").arg(pAddon->Id));
|
||||
|
||||
QtConcurrent::run(CAddonManager::InstallAddonAsync, Path, pAddon);
|
||||
}
|
||||
|
||||
void CAddonManager::InstallAddonAsync(const QString& FilePath, CAddonPtr pAddon)
|
||||
{
|
||||
SB_STATUS Status = SB_OK;
|
||||
|
||||
CArchive Archive(FilePath);
|
||||
|
||||
if (Archive.Open() == 1)
|
||||
{
|
||||
QString FileDir = Split2(FilePath, ".", true).first.replace("/", "\\");
|
||||
if (Archive.Extract(FileDir)) {
|
||||
|
||||
QString Cmd = pAddon->GetSpecificEntry("installer").toString();
|
||||
QString Path = ExpandPath(pAddon->GetSpecificEntry("install_path").toString());
|
||||
if (!Cmd.isEmpty() && QFile::exists(FileDir + Cmd))
|
||||
{
|
||||
pAddon->pProgress->ShowMessage(tr("Running Installer for %1").arg(pAddon->Id));
|
||||
|
||||
std::wstring sbiehome = theAPI->GetSbiePath().toStdWString();
|
||||
std::wstring plusdata = theConf->GetConfigDir().toStdWString();
|
||||
|
||||
LPWCH environmentStrings = GetEnvironmentStrings();
|
||||
|
||||
DWORD environmentLen = 0;
|
||||
for (LPWCH current = environmentStrings; *current; current += wcslen(current) + 1)
|
||||
environmentLen += wcslen(current) + 1;
|
||||
|
||||
LPWCH modifiedEnvironment = (LPWCH)LocalAlloc(0, (environmentLen + sbiehome.length() + 1 + plusdata.length() + 1 + 1) * sizeof(wchar_t));
|
||||
memcpy(modifiedEnvironment, environmentStrings, (environmentLen + 1) * sizeof(wchar_t));
|
||||
|
||||
FreeEnvironmentStrings(environmentStrings);
|
||||
|
||||
LPWCH modifiedEnvironmentEnd = modifiedEnvironment + environmentLen;
|
||||
|
||||
wcscpy(modifiedEnvironmentEnd, L"SBIEHOME=");
|
||||
wcscat(modifiedEnvironmentEnd, sbiehome.c_str());
|
||||
modifiedEnvironmentEnd += wcslen(modifiedEnvironmentEnd) + 1;
|
||||
|
||||
wcscpy(modifiedEnvironmentEnd, L"PLUSDATA=");
|
||||
wcscat(modifiedEnvironmentEnd, plusdata.c_str());
|
||||
modifiedEnvironmentEnd += wcslen(modifiedEnvironmentEnd) + 1;
|
||||
|
||||
*modifiedEnvironmentEnd = 0;
|
||||
|
||||
STARTUPINFO si = { sizeof(si), 0 };
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
if (CreateProcessW(NULL, (wchar_t*)(FileDir + Cmd).toStdWString().c_str(), NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, modifiedEnvironment, NULL, &si, &pi))
|
||||
{
|
||||
while (WaitForSingleObject(pi.hProcess, 1000) == WAIT_TIMEOUT && !pAddon->pProgress->IsCanceled());
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
else
|
||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Failes to start installer (%1)!").arg(GetLastError()));
|
||||
|
||||
LocalFree(modifiedEnvironment);
|
||||
}
|
||||
else if (!Path.isEmpty())
|
||||
{
|
||||
pAddon->pProgress->ShowMessage(tr("Copying Files for %1").arg(pAddon->Id));
|
||||
|
||||
std::wstring from;
|
||||
foreach(const QString & file, ListDir(FileDir)) {
|
||||
QString File = QString(file).replace("/", "\\");
|
||||
from.append((FileDir + "\\" + File).toStdWString());
|
||||
from.append(L"\0", 1);
|
||||
}
|
||||
from.append(L"\0", 1);
|
||||
|
||||
std::wstring to;
|
||||
to.append(Path.toStdWString());
|
||||
to.append(L"\0", 1);
|
||||
|
||||
SHFILEOPSTRUCT SHFileOp;
|
||||
memset(&SHFileOp, 0, sizeof(SHFILEOPSTRUCT));
|
||||
SHFileOp.hwnd = NULL;
|
||||
SHFileOp.wFunc = FO_MOVE;
|
||||
SHFileOp.pFrom = from.c_str();
|
||||
SHFileOp.pTo = to.c_str();
|
||||
SHFileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
|
||||
|
||||
SHFileOperation(&SHFileOp);
|
||||
}
|
||||
|
||||
QDir(FileDir).removeRecursively();
|
||||
}
|
||||
else
|
||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Failes to unpack addon!"));
|
||||
Archive.Close();
|
||||
}
|
||||
|
||||
QFile::remove(FilePath);
|
||||
|
||||
if (!Status.IsError()) {
|
||||
pAddon->Installed = CheckAddon(pAddon);
|
||||
if (!pAddon->Installed)
|
||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Addon Instalation Failed!"));
|
||||
}
|
||||
pAddon->pProgress->Finish(Status);
|
||||
pAddon->pProgress.create();
|
||||
}
|
||||
|
||||
SB_PROGRESS CAddonManager::TryRemoveAddon(const QString& Id, QWidget* pParent)
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you want to remove %1?").arg(Id),
|
||||
QMessageBox::Question, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton, pParent ? pParent : theGUI).exec() != QMessageBox::Yes)
|
||||
return SB_ERR(SB_OtherError);
|
||||
|
||||
SB_PROGRESS Status = RemoveAddon(Id);
|
||||
if (Status.GetStatus() == OP_ASYNC)
|
||||
theGUI->AddAsyncOp(Status.GetValue(), false, tr("Removing: %1").arg(Id), pParent);
|
||||
else
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, pParent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
SB_PROGRESS CAddonManager::RemoveAddon(const QString& Id)
|
||||
{
|
||||
CAddonPtr pAddon = GetAddon(Id);
|
||||
if (!pAddon)
|
||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon not found!"));
|
||||
|
||||
pAddon->pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
QtConcurrent::run(CAddonManager::RemoveAddonAsync, pAddon);
|
||||
return SB_PROGRESS(OP_ASYNC, pAddon->pProgress);
|
||||
}
|
||||
|
||||
void CAddonManager::CleanupPath(const QString& Path)
|
||||
{
|
||||
StrPair PathName = Split2(Path, "\\", true);
|
||||
if (ListDir(PathName.first).isEmpty())
|
||||
{
|
||||
QDir().rmdir(PathName.first);
|
||||
//qDebug() << "delete dir" << PathName.first;
|
||||
CleanupPath(PathName.first);
|
||||
}
|
||||
}
|
||||
|
||||
void CAddonManager::RemoveAddonAsync(CAddonPtr pAddon)
|
||||
{
|
||||
SB_STATUS Status = SB_OK;
|
||||
|
||||
QString Key = pAddon->GetSpecificEntry("uninstall_key").toString();
|
||||
if (!Key.isEmpty())
|
||||
{
|
||||
QSettings settings(Key, QSettings::NativeFormat);
|
||||
QString Cmd = settings.value("UninstallString").toString();
|
||||
|
||||
pAddon->pProgress->ShowMessage(tr("Running Uninstaller for %1").arg(pAddon->Id));
|
||||
|
||||
STARTUPINFO si = { sizeof(si), 0 };
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
if (CreateProcessW(NULL, (wchar_t*)Cmd.toStdWString().c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
while (WaitForSingleObject(pi.hProcess, 1000) == WAIT_TIMEOUT && !pAddon->pProgress->IsCanceled());
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
else
|
||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Failes to start uninstaller!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList Files = pAddon->GetSpecificEntry("files").toStringList();
|
||||
//foreach(const QString & File, Files) {
|
||||
// pAddon->pProgress->ShowMessage(tr("Removing %1").arg(File));
|
||||
// QString FilePath = ExpandPath(File);
|
||||
// QFile::remove(FilePath);
|
||||
// CleanupPath(FilePath);
|
||||
//}
|
||||
|
||||
std::wstring from;
|
||||
foreach(const QString & File, Files) {
|
||||
QString FilePath = ExpandPath(File);
|
||||
if (QFile::exists(FilePath)) {
|
||||
from.append(FilePath.toStdWString());
|
||||
from.append(L"\0", 1);
|
||||
}
|
||||
}
|
||||
from.append(L"\0", 1);
|
||||
|
||||
SHFILEOPSTRUCT SHFileOp;
|
||||
memset(&SHFileOp, 0, sizeof(SHFILEOPSTRUCT));
|
||||
SHFileOp.hwnd = NULL;
|
||||
SHFileOp.wFunc = FO_DELETE;
|
||||
SHFileOp.pFrom = from.c_str();
|
||||
SHFileOp.pTo = NULL;
|
||||
SHFileOp.fFlags = FOF_NOCONFIRMATION;
|
||||
|
||||
SHFileOperation(&SHFileOp);
|
||||
}
|
||||
|
||||
if (!Status.IsError()) {
|
||||
pAddon->Installed = CheckAddon(pAddon);
|
||||
if (pAddon->Installed)
|
||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Addon Removal Failed!"));
|
||||
}
|
||||
pAddon->pProgress->Finish(Status);
|
||||
pAddon->pProgress.create();
|
||||
}
|
||||
|
||||
QString CAddonManager::ExpandPath(QString Path)
|
||||
{
|
||||
Path.replace("%SbieHome%", theAPI->GetSbiePath(), Qt::CaseInsensitive);
|
||||
Path.replace("%PlusData%", theConf->GetConfigDir(), Qt::CaseInsensitive);
|
||||
|
||||
return theGUI->GetCompat()->ExpandPath(Path);
|
||||
}
|
||||
|
||||
QString GetArch()
|
||||
{
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
switch (systemInfo.wProcessorArchitecture)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL: return "x86";
|
||||
case PROCESSOR_ARCHITECTURE_AMD64: return "x64";
|
||||
case PROCESSOR_ARCHITECTURE_ARM64: return "a64";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
|
||||
QVariant CAddon::GetSpecificEntry(const QString& Name, QString* pName)
|
||||
{
|
||||
#ifdef _M_ARM64
|
||||
QString arch = "a64";
|
||||
#elif _WIN64
|
||||
QString arch = "x64";
|
||||
#else
|
||||
QString arch = "x86";
|
||||
#endif
|
||||
|
||||
//
|
||||
// First we check the qt cpecific entry for our version of qt and platform
|
||||
//
|
||||
|
||||
QString qt = QString("qt%1_%2_%3_%4").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR).arg(QT_VERSION_PATCH).arg(arch);
|
||||
#ifdef _DEBUG
|
||||
qt.append("d");
|
||||
#endif // _DEBUG
|
||||
if (Data.contains(Name + "_" + qt)) {
|
||||
if (pName) *pName = Name + "_" + qt;
|
||||
return Data[Name + "_" + qt];
|
||||
}
|
||||
|
||||
//
|
||||
// Second we check the actual architecture
|
||||
//
|
||||
|
||||
QString match = Data["match_arch"].toString();
|
||||
if (match != "agent")
|
||||
arch = GetArch();
|
||||
if (Data.contains(Name + "_" + arch)) {
|
||||
if (pName) *pName = Name + "_" + arch;
|
||||
return Data[Name + "_" + arch];
|
||||
}
|
||||
|
||||
//
|
||||
// last we try the unsoecific entry
|
||||
//
|
||||
|
||||
if (Data.contains(Name)) {
|
||||
if (pName) *pName = Name;
|
||||
return Data[Name];
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString CAddon::GetLocalizedEntry(const QString& Name)
|
||||
{
|
||||
if (Data.contains(Name + "_" + theGUI->m_Language))
|
||||
return Data[Name + "_" + theGUI->m_Language].toString();
|
||||
|
||||
QString LangAux = theGUI->m_Language; // Short version as fallback
|
||||
LangAux.truncate(LangAux.lastIndexOf('_'));
|
||||
if (Data.contains(Name + "_" + LangAux))
|
||||
return Data[Name + "_" + LangAux].toString();
|
||||
|
||||
return Data[Name].toString();
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
#include <QObject>
|
||||
#include "../QSbieAPI/SbieStatus.h"
|
||||
|
||||
|
||||
class CAddon : public QObject
|
||||
{
|
||||
public:
|
||||
CAddon(const QVariantMap& Data) : Installed(false), Data(Data)
|
||||
{
|
||||
Id = Data["id"].toString();
|
||||
}
|
||||
QString Id;
|
||||
QVariantMap Data;
|
||||
bool Installed;
|
||||
CSbieProgressPtr pProgress;
|
||||
|
||||
QVariant GetSpecificEntry(const QString& Name, QString* pName = NULL);
|
||||
QString GetLocalizedEntry(const QString& Name);
|
||||
};
|
||||
|
||||
typedef QSharedPointer<CAddon> CAddonPtr;
|
||||
|
||||
class CAddonManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CAddonManager(QObject* parent = NULL);
|
||||
|
||||
bool LoadAddons();
|
||||
|
||||
void UpdateAddons();
|
||||
|
||||
QList<CAddonPtr> GetAddons();
|
||||
|
||||
CAddonPtr GetAddon(const QString& Id);
|
||||
bool HasAddon(const QString& Id);
|
||||
|
||||
SB_PROGRESS TryInstallAddon(const QString& Id, QWidget* pParent, const QString& Prompt = QString());
|
||||
SB_PROGRESS InstallAddon(const QString& Id);
|
||||
SB_PROGRESS TryRemoveAddon(const QString& Id, QWidget* pParent);
|
||||
SB_PROGRESS RemoveAddon(const QString& Id);
|
||||
|
||||
signals:
|
||||
void DataUpdated();
|
||||
void AddonInstalled();
|
||||
|
||||
private slots:
|
||||
void OnUpdateData(const QVariantMap& Data, const QVariantMap& Params);
|
||||
void OnAddonDownloaded(const QString& Path, const QVariantMap& Params);
|
||||
|
||||
protected:
|
||||
static bool CheckAddon(const CAddonPtr& pAddon);
|
||||
|
||||
static void CleanupPath(const QString& Path);
|
||||
|
||||
static void InstallAddonAsync(const QString& FilePath, CAddonPtr pAddon);
|
||||
static void RemoveAddonAsync(CAddonPtr pAddon);
|
||||
|
||||
static QString ExpandPath(QString Path);
|
||||
|
||||
QList<CAddonPtr> m_Addons;
|
||||
};
|
||||
|
|
@ -0,0 +1,386 @@
|
|||
#include "stdafx.h"
|
||||
#include "BoxEngine.h"
|
||||
#include "../../QSbieAPI/SbieUtils.h"
|
||||
|
||||
#include "BoxObject.h"
|
||||
#include "SbieObject.h"
|
||||
#include "IniObject.h"
|
||||
#include "SysObject.h"
|
||||
#include "WizardObject.h"
|
||||
|
||||
#include "../Wizards/BoxAssistant.h"
|
||||
|
||||
#include <private/qv4engine_p.h>
|
||||
#include <private/qv4script_p.h>
|
||||
|
||||
int CBoxEngine::m_InstanceCount = 0;
|
||||
|
||||
CBoxEngine::CBoxEngine(QObject* parent) : QThread(parent)
|
||||
{
|
||||
m_InstanceCount++;
|
||||
|
||||
m_State = eUnknown;
|
||||
m_pEngine = NULL;
|
||||
m_pDebuggerBackend = NULL;
|
||||
|
||||
//static QQmlDebuggingEnabler qQmlEnableDebuggingHelper(false);
|
||||
//QQmlDebuggingEnabler::startTcpDebugServer(1234, QQmlDebuggingEnabler::WaitForClient);
|
||||
}
|
||||
|
||||
CBoxEngine::~CBoxEngine()
|
||||
{
|
||||
m_Mutex.lock();
|
||||
if (m_State == eQuery || m_State == eReady)
|
||||
Continue(true, eCanceled);
|
||||
else {
|
||||
if (m_State == eRunning || m_State == eRunningAsync)
|
||||
m_State = eCanceled;
|
||||
m_Mutex.unlock();
|
||||
}
|
||||
|
||||
if (!wait(30 * 1000)) {
|
||||
qDebug() << "Failed to terminate Box Engine";
|
||||
return;
|
||||
}
|
||||
|
||||
m_InstanceCount--;
|
||||
}
|
||||
|
||||
QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *v, const QV4::Value *argv, int argc)
|
||||
{
|
||||
QV4::Scope scope(b);
|
||||
QV4::ExecutionEngine *v4 = scope.engine;
|
||||
|
||||
CBoxEngine* pEngine = qobject_cast<CBoxEngine*>(CJSEngineExt::getEngineByHandle(v4)->thread());
|
||||
CBoxAssistant* Wizard = qobject_cast<CBoxAssistant*>(pEngine->parent()); // todo make teranslation work also for system scripts
|
||||
|
||||
QString Result;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (i == 0) Result = (Wizard ? Wizard->Tr(argv[i].toQStringNoThrow()) : argv[i].toQStringNoThrow());
|
||||
else Result = Result.arg(argv[i].toQStringNoThrow());
|
||||
}
|
||||
|
||||
return QV4::Encode(scope.engine->newString(Result));
|
||||
}
|
||||
|
||||
QV4::ReturnedValue method_print(const QV4::FunctionObject *b, const QV4::Value *v, const QV4::Value *argv, int argc)
|
||||
{
|
||||
QV4::Scope scope(b);
|
||||
QV4::ExecutionEngine *v4 = scope.engine;
|
||||
|
||||
QString Result;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (i > 0) Result.append(" ");
|
||||
Result.append(argv[i].toQStringNoThrow());
|
||||
}
|
||||
CBoxEngine* pEngine = qobject_cast<CBoxEngine*>(CJSEngineExt::getEngineByHandle(v4)->thread());
|
||||
pEngine->AppendLog(Result);
|
||||
|
||||
return QV4::Encode::undefined();
|
||||
}
|
||||
|
||||
QV4::ReturnedValue method_wcmp(const QV4::FunctionObject *b, const QV4::Value *v, const QV4::Value *argv, int argc)
|
||||
{
|
||||
QV4::Scope scope(b);
|
||||
QV4::ExecutionEngine *v4 = scope.engine;
|
||||
|
||||
if (argc < 2)
|
||||
return QV4::Encode::undefined();
|
||||
|
||||
return QV4::Encode(CSbieUtils::WildCompare(argv[0].toQStringNoThrow(), argv[1].toQStringNoThrow()));
|
||||
}
|
||||
|
||||
void CBoxEngine::init()
|
||||
{
|
||||
QV4::Scope scope(m_pEngine->handle());
|
||||
scope.engine->globalObject->defineDefaultProperty(QStringLiteral("tr"), method_translate);
|
||||
scope.engine->globalObject->defineDefaultProperty(QStringLiteral("print"), method_print);
|
||||
scope.engine->globalObject->defineDefaultProperty(QStringLiteral("wildCompare"), method_wcmp);
|
||||
|
||||
m_pEngine->globalObject().setProperty("system", m_pEngine->newQObject(new JSysObject(this)));
|
||||
m_pEngine->globalObject().setProperty("sbie", m_pEngine->newQObject(new JSbieObject(new CSbieObject(this), this)));
|
||||
}
|
||||
|
||||
bool CBoxEngine::RunScript(const QString& Script, const QString& Name)
|
||||
{
|
||||
if (isRunning())
|
||||
return false;
|
||||
|
||||
m_Script = Script;
|
||||
m_Name = Name;
|
||||
m_State = eRunning;
|
||||
|
||||
if(!m_pEngine) m_pEngine = new CJSEngineExt(); // the engine lives in its own thread
|
||||
//m_pEngine->installExtensions(QJSEngine::ConsoleExtension);
|
||||
|
||||
init();
|
||||
|
||||
m_pEngine->moveToThread(this);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// !!! CAUTION Multi Threading !!!
|
||||
//
|
||||
// Note: The engine runs in its own thread but the rest of SandMan
|
||||
// is mostly single threaded, also QSbieAPI is not hread safe so
|
||||
// access to it must be synchronized. We solve this by executing
|
||||
// all calls to theGUI and/or theAPI in the main thread through
|
||||
// the use of QT's slot system, we wrap all calls from the engine
|
||||
// in blocking QMetaObject::invokeMethod calls targeting to objects
|
||||
// which belong the main thread hence thay need to be created in
|
||||
// the main thread and passed to the caller from there.
|
||||
//
|
||||
//
|
||||
|
||||
start();
|
||||
|
||||
//return Wait();
|
||||
return true; // fully async operation
|
||||
}
|
||||
|
||||
void CBoxEngine::run()
|
||||
{
|
||||
//QElapsedTimer timer;
|
||||
//timer.start();
|
||||
|
||||
//auto ret = m_pEngine->evaluateScript("(()=>{" + m_Script + "})()", m_Name);
|
||||
auto ret = m_pEngine->evaluateScript(m_Script, m_Name);
|
||||
|
||||
//qDebug() << "CBoxEngine::run took" << timer.elapsed() << "ms";
|
||||
|
||||
if (IsRunning()) {
|
||||
if (ret.isError()) {
|
||||
QString Error = tr("Uncaught exception at line %1: %2").arg(ret.property("lineNumber").toInt()).arg(ret.toString());
|
||||
AppendLog(Error);
|
||||
SetState(eError, Error);
|
||||
}
|
||||
else
|
||||
SetState(eCompleted);
|
||||
}
|
||||
|
||||
m_Result = m_pEngine->globalObject().property("result").toVariant();
|
||||
|
||||
delete m_pEngine;
|
||||
m_pEngine = NULL;
|
||||
}
|
||||
|
||||
//bool CBoxEngine::Wait()
|
||||
//{
|
||||
// while (m_State == eRunning)
|
||||
// QCoreApplication::processEvents(); // keep the main thread going
|
||||
// return true;
|
||||
//}
|
||||
|
||||
bool CBoxEngine::SetResult(const QVariantMap& Result)
|
||||
{
|
||||
m_Mutex.lock();
|
||||
m_Data = Result;
|
||||
return Continue(true);
|
||||
}
|
||||
|
||||
bool CBoxEngine::Continue(bool bLocked, EState State)
|
||||
{
|
||||
Q_ASSERT(!IsRunning());
|
||||
|
||||
if (!bLocked) m_Mutex.lock();
|
||||
|
||||
// Note: we set the state directly and the engine thread emits set state from WaitLocked
|
||||
|
||||
m_State = State;
|
||||
m_Wait.wakeOne();
|
||||
m_Mutex.unlock();
|
||||
|
||||
//return Wait();
|
||||
return true; // fully async operation
|
||||
}
|
||||
|
||||
void CBoxEngine::SetState(EState state, const QString& Text)
|
||||
{
|
||||
m_State = state;
|
||||
emit StateChanged(state, Text);
|
||||
}
|
||||
|
||||
bool CBoxEngine::TestRunning() {
|
||||
|
||||
// WARNING: call this function only from the engine thread itself !!!
|
||||
|
||||
if (!IsRunning()) {
|
||||
m_pEngine->throwError(QString("Canceled"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxEngine::WaitLocked() {
|
||||
|
||||
// WARNING: call this function only from the engine thread itself !!!
|
||||
|
||||
m_Wait.wait(&m_Mutex);
|
||||
|
||||
emit StateChanged(m_State);
|
||||
|
||||
return TestRunning();
|
||||
}
|
||||
|
||||
void CBoxEngine::AppendLog(const QString& Line)
|
||||
{
|
||||
qDebug() << "BoxEngine Log:" << Line;
|
||||
|
||||
emit LogMessage(Line);
|
||||
|
||||
//QMutexLocker Locker(&m_Mutex);
|
||||
//m_Log += Line + "\n";
|
||||
}
|
||||
|
||||
QObject* CBoxEngine::GetDebuggerBackend()
|
||||
{
|
||||
if(!m_pEngine)
|
||||
m_pEngine = new CJSEngineExt();
|
||||
if (!m_pDebuggerBackend) {
|
||||
m_pDebuggerBackend = newV4ScriptDebuggerBackendDynamic(m_pEngine);
|
||||
if (m_pDebuggerBackend) {
|
||||
QMetaObject::invokeMethod(m_pDebuggerBackend, "pause", Qt::DirectConnection);
|
||||
m_pDebuggerBackend->setParent(this);
|
||||
}
|
||||
}
|
||||
return m_pDebuggerBackend;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CWizardEngine
|
||||
//
|
||||
|
||||
CWizardEngine::CWizardEngine(QObject* parent)
|
||||
: CBoxEngine(parent)
|
||||
{
|
||||
}
|
||||
|
||||
CWizardEngine::~CWizardEngine()
|
||||
{
|
||||
foreach(const SBoxShadow& pShadow, m_Shadows) {
|
||||
if (pShadow.pShadow) {
|
||||
if (pShadow.iApplyChanges == 2)
|
||||
continue; // this is a new added entry keep it
|
||||
CSandBoxPtr pBox = pShadow.pShadow.objectCast<CSandBox>();
|
||||
if(!pBox.isNull()) pBox->TerminateAll();
|
||||
pShadow.pShadow->RemoveSection();
|
||||
}
|
||||
}
|
||||
theAPI->ReloadBoxes(true);
|
||||
}
|
||||
|
||||
bool CWizardEngine::ApplyShadowChanges()
|
||||
{
|
||||
for (auto I = m_Shadows.begin(); I != m_Shadows.end(); ++I) {
|
||||
if (I->iApplyChanges != 1)
|
||||
continue;
|
||||
|
||||
if (I->pOriginal.isNull()) {
|
||||
// This is a new box or tamplete not a copy, just clear shadow flag
|
||||
I->pShadow->DelValue("IsShadow", "y");
|
||||
I->iApplyChanges = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
QList<QPair<QString, QString>> New = I->pShadow->GetIniSection();
|
||||
QList<QPair<QString, QString>> Old = I->pOriginal->GetIniSection();
|
||||
|
||||
// discard unchanged
|
||||
for (auto I = New.begin(); I != New.end();) {
|
||||
auto II = I++;
|
||||
for (auto J = Old.begin(); J != Old.end();) {
|
||||
auto JJ = J++;
|
||||
if (II->first == JJ->first && II->second == JJ->second) {
|
||||
I = New.erase(II);
|
||||
J = Old.erase(JJ);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply changed
|
||||
foreach(auto & O, Old)
|
||||
I->pOriginal->DelValue(O.first, O.second);
|
||||
foreach(auto & N, New) {
|
||||
if (N.first == "FileRootPath" || N.first == "IsShadow")
|
||||
continue; // skip
|
||||
if(N.first == "Template" && IsNoAppliedShadow("Template_" + N.second))
|
||||
continue; // don't copy not applied shadow templates
|
||||
I->pOriginal->AppendText(N.first, N.second);
|
||||
}
|
||||
}
|
||||
|
||||
theAPI->CommitIniChanges();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWizardEngine::init()
|
||||
{
|
||||
CBoxEngine::init();
|
||||
|
||||
m_pEngine->globalObject().setProperty("wizard", m_pEngine->newQObject(new JWizardObject(this)));
|
||||
}
|
||||
|
||||
void CWizardEngine::SetState(EState state, const QString& Text)
|
||||
{
|
||||
if (state == eError)
|
||||
m_Report["Error"] = Text;
|
||||
CBoxEngine::SetState(state, Text);
|
||||
}
|
||||
|
||||
QSharedPointer<CSbieIni> CWizardEngine::MakeShadow(const QSharedPointer<CSbieIni>& pIni)
|
||||
{
|
||||
SBoxShadow& pShadow = m_Shadows[pIni->GetName().toLower()];
|
||||
if (!pShadow.pShadow) {
|
||||
QString ShadowName = pIni->GetName();
|
||||
QString Suffix = tr("_Shadow");
|
||||
ShadowName.truncate(32 - (Suffix.length() + 3)); // BOXNAME_COUNT
|
||||
ShadowName = theAPI->MkNewName(ShadowName.append(Suffix));
|
||||
|
||||
QList<QPair<QString, QString>> Settings = pIni->GetIniSection();
|
||||
for (QList<QPair<QString, QString>>::iterator I = Settings.begin(); I != Settings.end(); ++I)
|
||||
theAPI->SbieIniSet(ShadowName, I->first, I->second, CSbieAPI::eIniInsert, false);
|
||||
|
||||
CSandBoxPtr pBox = pIni.objectCast<CSandBox>();
|
||||
if(!pBox.isNull())
|
||||
theAPI->SbieIniSet(ShadowName, "FileRootPath", pBox->GetFileRoot(), CSbieAPI::eIniUpdate, false);
|
||||
theAPI->SbieIniSet(ShadowName, "IsShadow", "y", CSbieAPI::eIniUpdate, false);
|
||||
|
||||
theAPI->CommitIniChanges();
|
||||
theAPI->ReloadBoxes(true);
|
||||
|
||||
pShadow.pOriginal = pIni;
|
||||
if (pBox)
|
||||
pShadow.pShadow = theAPI->GetBoxByName(ShadowName);
|
||||
else
|
||||
pShadow.pShadow = QSharedPointer<CSbieIni>(new CSbieIni(ShadowName, theAPI));
|
||||
}
|
||||
return pShadow.pShadow;
|
||||
}
|
||||
|
||||
void CWizardEngine::AddShadow(const QSharedPointer<CSbieIni>& pIni)
|
||||
{
|
||||
SBoxShadow& pShadow = m_Shadows[pIni->GetName().toLower()];
|
||||
if (!pShadow.pShadow) {
|
||||
|
||||
pIni->SetText("IsShadow", "y");
|
||||
|
||||
pShadow.pShadow = pIni;
|
||||
}
|
||||
}
|
||||
|
||||
void CWizardEngine::SetApplyShadow(const QString& OriginalName, bool bApply)
|
||||
{
|
||||
auto I = m_Shadows.find(OriginalName.toLower());
|
||||
if(I != m_Shadows.end())
|
||||
I->iApplyChanges = bApply ? 1 : 0;
|
||||
}
|
||||
|
||||
bool CWizardEngine::IsNoAppliedShadow(const QString& OriginalName)
|
||||
{
|
||||
auto I = m_Shadows.find(OriginalName.toLower());
|
||||
if (I != m_Shadows.end())
|
||||
return I->iApplyChanges == 0;
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
#pragma once
|
||||
#include <QThread>
|
||||
#include <QJSEngine>
|
||||
#include "../../QSbieAPI/SbieAPI.h"
|
||||
|
||||
#include "JSEngineExt.h"
|
||||
|
||||
class CBoxEngine : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CBoxEngine(QObject* parent = NULL);
|
||||
~CBoxEngine();
|
||||
|
||||
bool RunScript(const QString& Script, const QString& Name);
|
||||
|
||||
enum EState {
|
||||
eUnknown,
|
||||
|
||||
eRunning,
|
||||
eRunningAsync,
|
||||
eReady,
|
||||
eQuery,
|
||||
|
||||
eCompleted,
|
||||
eSuccess,
|
||||
eFailed,
|
||||
eError,
|
||||
eCanceled
|
||||
};
|
||||
|
||||
EState GetState() const { return m_State; }
|
||||
|
||||
bool IsRunning() const { return m_State == eRunning || m_State == eRunningAsync; }
|
||||
bool Continue() { return Continue(false); }
|
||||
|
||||
bool HasFailed() const { return m_State == eFailed; }
|
||||
bool HasError() const { return m_State == eError; }
|
||||
|
||||
bool IsReady() const { return m_State == eReady; }
|
||||
bool HasQuery() const { return m_State == eQuery; }
|
||||
QVariantMap GetQuery() const { QMutexLocker Locker(&m_Mutex); return m_State == eQuery ? m_Data : QVariantMap(); }
|
||||
bool SetResult(const QVariantMap& Result);
|
||||
QVariant GetResult() const { return m_Result; }
|
||||
|
||||
void AppendLog(const QString& Line);
|
||||
//QString GetLog() const { QMutexLocker Locker(&m_Mutex); return m_Log; }
|
||||
|
||||
static int GetInstanceCount() { return m_InstanceCount; }
|
||||
|
||||
QObject* GetDebuggerBackend();
|
||||
|
||||
signals:
|
||||
|
||||
void StateChanged(int state, const QString& Text = "");
|
||||
|
||||
void BoxUsed(const CSandBoxPtr& pBox);
|
||||
|
||||
void LogMessage(const QString& Line);
|
||||
|
||||
protected:
|
||||
friend class JSysObject;
|
||||
friend class JSbieObject;
|
||||
friend class JIniObject;
|
||||
friend class JConfObject;
|
||||
friend class JBoxObject;
|
||||
friend class JBoxWObject;
|
||||
|
||||
virtual void init();
|
||||
virtual void run();
|
||||
//virtual bool Wait();
|
||||
virtual bool Continue(bool bLocked, EState State = eRunning);
|
||||
|
||||
virtual void SetState(EState state, const QString& Text = "");
|
||||
bool TestRunning();
|
||||
bool WaitLocked();
|
||||
|
||||
CJSEngineExt* m_pEngine;
|
||||
QObject* m_pDebuggerBackend;
|
||||
QString m_Script;
|
||||
QString m_Name;
|
||||
QVariant m_Result;
|
||||
|
||||
mutable QMutex m_Mutex;
|
||||
QWaitCondition m_Wait;
|
||||
QVariantMap m_Data;
|
||||
EState m_State;
|
||||
|
||||
//QString m_Log;
|
||||
|
||||
static int m_InstanceCount;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CWizardEngine
|
||||
//
|
||||
|
||||
class CWizardEngine : public CBoxEngine
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CWizardEngine(QObject* parent = NULL);
|
||||
~CWizardEngine();
|
||||
|
||||
QVariantMap GetReport() { return m_Report; }
|
||||
|
||||
bool ApplyShadowChanges();
|
||||
|
||||
QSharedPointer<CSbieIni> MakeShadow(const QSharedPointer<CSbieIni>& pIni);
|
||||
void AddShadow(const QSharedPointer<CSbieIni>& pIni);
|
||||
void SetApplyShadow(const QString& OriginalName, bool bApply = true);
|
||||
bool IsNoAppliedShadow(const QString& OriginalName);
|
||||
|
||||
protected:
|
||||
friend class JWizardObject;
|
||||
|
||||
virtual void init();
|
||||
|
||||
virtual void SetState(EState state, const QString& Text = "");
|
||||
|
||||
QVariantMap m_Report;
|
||||
|
||||
struct SBoxShadow {
|
||||
SBoxShadow() : iApplyChanges(0) {}
|
||||
QSharedPointer<CSbieIni> pShadow;
|
||||
QSharedPointer<CSbieIni> pOriginal;
|
||||
int iApplyChanges;
|
||||
};
|
||||
|
||||
QMap<QString, SBoxShadow> m_Shadows;
|
||||
};
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
#include "stdafx.h"
|
||||
#include "BoxObject.h"
|
||||
#include "../SandMan.h"
|
||||
#include "../Views/SbieView.h"
|
||||
#include "../Windows/SettingsWindow.h"
|
||||
#include "../QSbieAPI/SbieUtils.h"
|
||||
|
||||
|
||||
quint32 CBoxObject::StartTask(const QString& Command, const QVariantMap& Options)
|
||||
{
|
||||
SB_RESULT(quint32) result = theGUI->RunStart(getName(), Command, Options["elevalted"].toBool(), Options["directory"].toString());
|
||||
return result.IsError() ? -1 : result.GetValue();
|
||||
}
|
||||
|
||||
QVariantList CBoxObject::ListTasks()
|
||||
{
|
||||
QVariantList List;
|
||||
foreach(const CBoxedProcessPtr& pProcess, m_pIni.objectCast<CSandBox>()->GetProcessList())
|
||||
List.append(TaskInfo(pProcess));
|
||||
return List;
|
||||
}
|
||||
|
||||
bool CBoxObject::StopTask(quint32 pid)
|
||||
{
|
||||
CBoxedProcessPtr pProcess = m_pIni.objectCast<CSandBox>()->GetProcessList().value(pid);
|
||||
if (!pProcess)
|
||||
return false;
|
||||
SB_STATUS Status = pProcess->Terminate();
|
||||
return !Status.IsError();
|
||||
}
|
||||
|
||||
bool CBoxObject::Terminate()
|
||||
{
|
||||
SB_STATUS Status = m_pIni.objectCast<CSandBox>()->TerminateAll();
|
||||
return !Status.IsError();
|
||||
}
|
||||
|
||||
QVariantMap CBoxObject::TaskInfo(quint32 pid)
|
||||
{
|
||||
return TaskInfo(m_pIni.objectCast<CSandBox>()->GetProcessList().value(pid));
|
||||
}
|
||||
|
||||
QVariantMap CBoxObject::TaskInfo(const CBoxedProcessPtr& pProcess)
|
||||
{
|
||||
QVariantMap Info;
|
||||
Info["pid"] = pProcess->GetProcessId();
|
||||
Info["parentId"] = pProcess->GetParendPID();
|
||||
Info["name"] = pProcess->GetProcessName();
|
||||
Info["commandline"] = pProcess->GetCommandLine();
|
||||
Info["fileName"] = pProcess->GetFileName();
|
||||
Info["timeStamp"] = pProcess->GetTimeStamp();
|
||||
Info["flags"] = pProcess->GetProcessFlags();
|
||||
Info["type"] = pProcess->GetImageType();
|
||||
if (pProcess->IsTerminated()) {
|
||||
Info["isRunning"] = false;
|
||||
Info["returnCode"] = pProcess->GetReturnCode();
|
||||
} else
|
||||
Info["isRunning"] = true;
|
||||
return Info;
|
||||
}
|
||||
|
||||
bool CBoxObject::DeleteContent()
|
||||
{
|
||||
SB_STATUS Status = theGUI->DeleteBoxContent(m_pIni.objectCast<CSandBox>(), CSandMan::eCleanUp);
|
||||
return !Status.IsError();
|
||||
}
|
||||
|
||||
bool CBoxObject::RemoveSandbox()
|
||||
{
|
||||
SB_STATUS Status = theGUI->DeleteBoxContent(m_pIni.objectCast<CSandBox>(), CSandMan::eForDelete);
|
||||
if (Status.GetMsgCode() == SB_Canceled)
|
||||
return false;
|
||||
Status = m_pIni.objectCast<CSandBox>()->RemoveBox();
|
||||
return !Status.IsError();
|
||||
}
|
||||
|
||||
bool CBoxObject::MakeShortcut(const QString& Target, const QVariantMap& Options)
|
||||
{
|
||||
QString Location = Options["location"].toString();
|
||||
QStandardPaths::StandardLocation location = (QStandardPaths::StandardLocation)-1;
|
||||
if (Location.compare("desktop", Qt::CaseInsensitive) == 0)
|
||||
location = QStandardPaths::DesktopLocation;
|
||||
else if (Location.compare("startmenu", Qt::CaseInsensitive) == 0)
|
||||
location = QStandardPaths::ApplicationsLocation;
|
||||
else if (Location.compare("documents", Qt::CaseInsensitive) == 0)
|
||||
location = QStandardPaths::DocumentsLocation;
|
||||
if (location != -1) {
|
||||
QString Name = Options["name"].toString();
|
||||
QString Path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).replace("/", "\\");
|
||||
if (Target == "default_browser")
|
||||
Path += "\\" + CSettingsWindow::tr("Sandboxed Web Browser") + ".lnk";
|
||||
else if (!Name.isEmpty())
|
||||
Path += "\\" + Name + ".lnk";
|
||||
else
|
||||
return false;
|
||||
QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe";
|
||||
return CSbieUtils::CreateShortcut(StartExe, Path, "", getName(), Target);
|
||||
}
|
||||
return CSbieView::CreateShortcut(Target, getName(), Options["iconPath"].toString(), Options["iconIndex"].toInt(), Options["workDir"].toString());
|
||||
}
|
||||
|
||||
void CSBoxObject::ApplyChanges(bool bApply)
|
||||
{
|
||||
CWizardEngine* pEngine = qobject_cast<CWizardEngine*>(parent());
|
||||
pEngine->SetApplyShadow(m_OriginalName, bApply);
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
#pragma once
|
||||
#include "IniObject.h"
|
||||
|
||||
class CBoxObject : public CIniObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CBoxObject(const QSharedPointer<CSbieIni>& pBox, QObject* parent)
|
||||
: CIniObject(pBox, parent) {}
|
||||
|
||||
public slots:
|
||||
|
||||
QString GetFileRoot() { return m_pIni.objectCast<CSandBox>()->GetFileRoot(); }
|
||||
QString GetRegRoot() { return m_pIni.objectCast<CSandBox>()->GetRegRoot(); }
|
||||
|
||||
quint32 StartTask(const QString& Command, const QVariantMap& Options);
|
||||
QVariantList ListTasks();
|
||||
bool StopTask(quint32 pid);
|
||||
bool Terminate();
|
||||
QVariantMap TaskInfo(quint32 pid);
|
||||
|
||||
bool DeleteContent();
|
||||
|
||||
bool RemoveSandbox();
|
||||
|
||||
|
||||
bool MakeShortcut(const QString& Target, const QVariantMap& Options);
|
||||
|
||||
protected:
|
||||
QVariantMap TaskInfo(const CBoxedProcessPtr& pProcess);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class CSBoxObject : public CBoxObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CSBoxObject(const QSharedPointer<CSbieIni>& pBox, const QString& OriginalName, QObject* parent)
|
||||
: CBoxObject(pBox, parent), m_OriginalName(OriginalName) { }
|
||||
|
||||
public slots:
|
||||
|
||||
void ApplyChanges(bool bApply);
|
||||
|
||||
protected:
|
||||
QString m_OriginalName;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JBoxObject
|
||||
//
|
||||
|
||||
class JBoxObject : public JIniObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JBoxObject(CBoxObject* pObject, CBoxEngine* pEngine)
|
||||
: JIniObject(pObject, pEngine) {}
|
||||
~JBoxObject() { QMetaObject::invokeMethod(m_pObject, "deleteLater"); }
|
||||
|
||||
Q_INVOKABLE QJSValue getFileRoot(){
|
||||
QString Text;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetFileRoot", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, Text));
|
||||
return Text;
|
||||
}
|
||||
Q_INVOKABLE QJSValue getRegRoot(){
|
||||
QString Text;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetRegRoot", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, Text));
|
||||
return Text;
|
||||
}
|
||||
|
||||
Q_INVOKABLE QJSValue startTask(const QString& Command, const QVariantMap& Options = QVariantMap()){
|
||||
quint32 pid;
|
||||
QMetaObject::invokeMethod(m_pObject, "StartTask", Qt::BlockingQueuedConnection, Q_RETURN_ARG(quint32, pid), Q_ARG(QString, Command), Q_ARG(const QVariantMap&, Options));
|
||||
return pid;
|
||||
}
|
||||
Q_INVOKABLE QJSValue listTasks(){
|
||||
QVariantList List;
|
||||
QMetaObject::invokeMethod(m_pObject, "ListTasks", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariantList, List));
|
||||
return m_pEngine->m_pEngine->toScriptValue(List);
|
||||
}
|
||||
Q_INVOKABLE QJSValue stopTask(quint32 pid){
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "StopTask", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_RETURN_ARG(quint32, pid));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE QJSValue terminate(){
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "Terminate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE QJSValue taskInfo(quint32 pid) {
|
||||
QVariantMap Info;
|
||||
QMetaObject::invokeMethod(m_pObject, "TaskInfo", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariantMap, Info));
|
||||
return m_pEngine->m_pEngine->toScriptValue(Info);
|
||||
}
|
||||
|
||||
Q_INVOKABLE QJSValue deleteContent() {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "DeleteContent", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success));
|
||||
return Success;
|
||||
}
|
||||
|
||||
Q_INVOKABLE QJSValue removeSandbox() {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "RemoveSandbox", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success));
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
Q_INVOKABLE QJSValue makeShortcut(const QString& Target, const QVariantMap& Options = QVariantMap()) {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "MakeShortcut", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_ARG(QString, Target), Q_ARG(const QVariantMap&, Options));
|
||||
return Success;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JSBoxObject - Box Shadow Object
|
||||
//
|
||||
|
||||
class JSBoxObject : public JBoxObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JSBoxObject(CBoxObject* pObject, CBoxEngine* pEngine)
|
||||
: JBoxObject(pObject, pEngine) {}
|
||||
|
||||
Q_INVOKABLE void applyChanges(bool bApply = true) {
|
||||
QMetaObject::invokeMethod(m_pObject, "ApplyChanges", Qt::BlockingQueuedConnection, Q_ARG(bool, bApply));
|
||||
}
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
#include "stdafx.h"
|
||||
#include "IniObject.h"
|
||||
#include "../SandMan.h"
|
||||
#include "../Views/SbieView.h"
|
||||
|
||||
QString CIniObject::getName() const {
|
||||
if (!m_pIni) return ""; // no m_pIni means plus config
|
||||
return m_pIni->GetName();
|
||||
}
|
||||
|
||||
QVariantMap CIniObject::getIniSection(const QVariantMap& Options) {
|
||||
if (!m_pIni) return QVariantMap();
|
||||
|
||||
QMultiMap<QString, QVariant> Map;
|
||||
auto Section = m_pIni->GetIniSection(0,m_WithTemplate || Options["withTemplate"].toBool());
|
||||
for (auto I = Section.begin(); I != Section.end(); ++I)
|
||||
Map.insert(I->first, I->second);
|
||||
|
||||
QVariantMap Data;
|
||||
foreach(const QString & Key, Map.uniqueKeys())
|
||||
Data[Key] = Map.values(Key);
|
||||
return Data;
|
||||
}
|
||||
|
||||
bool CIniObject::setIniValue(const QString& Setting, const QVariant& Value) {
|
||||
if (!m_pIni) return theConf->SetValue(Setting, Value);
|
||||
return !m_pIni->SetText(Setting, Value.toString()).IsError();
|
||||
}
|
||||
|
||||
bool CIniObject::insertIniValue(const QString& Setting, const QString& Value) {
|
||||
if (!m_pIni) return false;
|
||||
return !m_pIni->InsertText(Setting, Value).IsError();
|
||||
}
|
||||
|
||||
bool CIniObject::appendIniValue(const QString& Setting, const QString& Value) {
|
||||
if (!m_pIni) return false;
|
||||
return !m_pIni->AppendText(Setting, Value).IsError();
|
||||
}
|
||||
|
||||
bool CIniObject::delIniValue(const QString& Setting, const QString& Value) {
|
||||
if (!m_pIni) { theConf->DelValue(Setting); return true; }
|
||||
return !m_pIni->DelValue(Setting, Value).IsError();
|
||||
}
|
||||
|
||||
QStringList CIniObject::getIniValues(const QString& Setting, const QVariantMap& Options) {
|
||||
if (!m_pIni) return QStringList();
|
||||
return m_pIni->GetTextList(Setting, m_WithTemplate || Options["withTemplate"].toBool(), Options["expand"].toBool(), Options["withGlobal"].toBool());
|
||||
}
|
||||
|
||||
QVariant CIniObject::getIniValue(const QString& Setting, const QVariantMap& Options) {
|
||||
if (!m_pIni) return theConf->GetValue(Setting);
|
||||
if(Options["type"] == "bool")
|
||||
return m_pIni->GetBool(Setting, Options["default"].toBool(), Options["withGlobal"].toBool(), m_WithTemplate || Options["withTemplate"].toBool());
|
||||
QString Text = m_pIni->GetText(Setting, Options["default"].toString(), Options["withGlobal"].toBool(), !Options["expand"].toBool(), m_WithTemplate || Options["withTemplate"].toBool());
|
||||
if (Options["type"] == "number")
|
||||
return Text.toLongLong();
|
||||
return Text;
|
||||
}
|
||||
|
||||
bool CIniObject::removeSection() {
|
||||
SB_STATUS Status = m_pIni->RemoveSection();
|
||||
return !Status.IsError();
|
||||
}
|
||||
|
||||
|
||||
void CSTmplObject::ApplyChanges(bool bApply) {
|
||||
CWizardEngine* pEngine = qobject_cast<CWizardEngine*>(parent());
|
||||
pEngine->SetApplyShadow(m_OriginalName, bApply);
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
#pragma once
|
||||
#include "BoxEngine.h"
|
||||
#include "../SbiePlusAPI.h"
|
||||
#include "../../MiscHelpers/Common/Settings.h"
|
||||
|
||||
class CIniObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CIniObject(const QSharedPointer<CSbieIni>& pIni, bool WithTemplate, QObject* parent) : QObject(parent), m_pIni(pIni), m_WithTemplate(WithTemplate) {}
|
||||
CIniObject(const QSharedPointer<CSbieIni>& pIni, QObject* parent) : CIniObject(pIni, false, parent) {}
|
||||
|
||||
public slots:
|
||||
|
||||
virtual QString getName() const;
|
||||
|
||||
virtual QVariantMap getIniSection(const QVariantMap& Options = QVariantMap());
|
||||
|
||||
virtual bool setIniValue(const QString& Setting, const QVariant& Value);
|
||||
virtual bool insertIniValue(const QString& Setting, const QString& Value);
|
||||
virtual bool appendIniValue(const QString& Setting, const QString& Value);
|
||||
virtual bool delIniValue(const QString& Setting, const QString& Value = "");
|
||||
virtual QStringList getIniValues(const QString& Setting, const QVariantMap& Options = QVariantMap());
|
||||
virtual QVariant getIniValue(const QString& Setting, const QVariantMap& Options = QVariantMap());
|
||||
|
||||
virtual bool removeSection();
|
||||
|
||||
protected:
|
||||
QSharedPointer<CSbieIni> m_pIni;
|
||||
bool m_WithTemplate;
|
||||
};
|
||||
|
||||
|
||||
class CSTmplObject : public CIniObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CSTmplObject(const QSharedPointer<CSbieIni>& pIni, const QString& OriginalName, QObject* parent)
|
||||
: CIniObject(pIni, parent), m_OriginalName(OriginalName) { }
|
||||
|
||||
public slots:
|
||||
|
||||
void ApplyChanges(bool bApply);
|
||||
|
||||
protected:
|
||||
QString m_OriginalName;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JIniObject
|
||||
//
|
||||
|
||||
class JIniObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JIniObject(CIniObject* pObject, CBoxEngine* pEngine)
|
||||
: m_pObject(pObject), m_pEngine(pEngine) {}
|
||||
~JIniObject() { QMetaObject::invokeMethod(m_pObject, "deleteLater"); }
|
||||
|
||||
Q_INVOKABLE virtual QJSValue getName() const {
|
||||
QString Name;
|
||||
QMetaObject::invokeMethod(m_pObject, "getName", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, Name));
|
||||
return Name;
|
||||
}
|
||||
|
||||
Q_INVOKABLE virtual QJSValue getIniSection(const QVariantMap& Options = QVariantMap()) {
|
||||
QVariantMap Data;
|
||||
QMetaObject::invokeMethod(m_pObject, "getIniSection", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariantMap, Data), Q_ARG(const QVariantMap&, Options));
|
||||
return m_pEngine->m_pEngine->toScriptValue(Data);
|
||||
}
|
||||
|
||||
Q_INVOKABLE virtual bool setIniValue(const QString& Setting, const QVariant& Value) {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "setIniValue", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_ARG(QString, Setting), Q_ARG(QVariant, Value));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE virtual bool insertIniValue(const QString& Setting, const QString& Value) {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "insertIniValue", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_ARG(QString, Setting), Q_ARG(QString, Value));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE virtual bool appendIniValue(const QString& Setting, const QString& Value) {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "appendIniValue", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_ARG(QString, Setting), Q_ARG(QString, Value));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE virtual bool delIniValue(const QString& Setting, const QString& Value = "") {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "delIniValue", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_ARG(QString, Setting), Q_ARG(QString, Value));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE virtual QJSValue getIniValues(const QString& Setting, const QVariantMap& Options = QVariantMap()) {
|
||||
QStringList List;
|
||||
QMetaObject::invokeMethod(m_pObject, "getIniValues", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QStringList, List), Q_ARG(QString, Setting), Q_ARG(const QVariantMap&, Options));
|
||||
return m_pEngine->m_pEngine->toScriptValue(List);
|
||||
}
|
||||
Q_INVOKABLE virtual QJSValue getIniValue(const QString& Setting, const QVariantMap& Options = QVariantMap()) {
|
||||
QVariant Value;
|
||||
QMetaObject::invokeMethod(m_pObject, "getIniValue", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, Value), Q_ARG(QString, Setting), Q_ARG(const QVariantMap&, Options));
|
||||
return m_pEngine->m_pEngine->toScriptValue(Value);
|
||||
}
|
||||
|
||||
Q_INVOKABLE virtual bool removeSection() {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "removeSection", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success));
|
||||
return Success;
|
||||
}
|
||||
|
||||
protected:
|
||||
CBoxEngine* m_pEngine;
|
||||
CIniObject* m_pObject;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JTmplObject
|
||||
//
|
||||
|
||||
class JTmplObject : public JIniObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JTmplObject(CIniObject* pObject, CBoxEngine* pEngine)
|
||||
: JIniObject(pObject, pEngine) {}
|
||||
|
||||
Q_INVOKABLE virtual QJSValue getName() const {
|
||||
QString Name;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetName", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, Name));
|
||||
return Name.mid(9);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JSTmplObject
|
||||
//
|
||||
|
||||
class JSTmplObject : public JTmplObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JSTmplObject(CIniObject* pObject, CBoxEngine* pEngine)
|
||||
: JTmplObject(pObject, pEngine) {}
|
||||
|
||||
Q_INVOKABLE void applyChanges(bool bApply = true) {
|
||||
QMetaObject::invokeMethod(m_pObject, "ApplyChanges", Qt::BlockingQueuedConnection, Q_ARG(bool, bApply));
|
||||
}
|
||||
};
|
|
@ -0,0 +1,120 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 David Xanatos (xanasoft.com) All rights reserved.
|
||||
** Contact: XanatosDavid@gmil.com
|
||||
**
|
||||
**
|
||||
** To use the V4ScriptTools in a commercial project, you must obtain
|
||||
** an appropriate business use license.
|
||||
**
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "JSEngineExt.h"
|
||||
|
||||
#include <private/qv4engine_p.h>
|
||||
#include <private/qv4debugging_p.h>
|
||||
#include <private/qv4objectiterator_p.h>
|
||||
#include <private/qv4string_p.h>
|
||||
#include <private/qv4script_p.h>
|
||||
#include <private/qqmlbuiltinfunctions_p.h>
|
||||
#include <private/qqmldebugservice_p.h>
|
||||
|
||||
static QMutex g_engineMutex;
|
||||
static QMap<void*, CJSEngineExt*> g_engineMap;
|
||||
|
||||
CJSEngineExt* CJSEngineExt::getEngineByHandle(void* handle)
|
||||
{
|
||||
QMutexLocker locker(&g_engineMutex);
|
||||
return g_engineMap.value(handle);
|
||||
}
|
||||
|
||||
static QV4::ReturnedValue printCall(const QV4::FunctionObject* b, const QV4::Value* v, const QV4::Value* argv, int argc);
|
||||
static QV4::ReturnedValue debuggerCall(const QV4::FunctionObject* b, const QV4::Value* v, const QV4::Value* argv, int argc);
|
||||
static QV4::ReturnedValue evalCall(const QV4::FunctionObject* b, const QV4::Value* v, const QV4::Value* argv, int argc);
|
||||
|
||||
CJSEngineExt::CJSEngineExt(QObject* parent)
|
||||
: QJSEngine(parent)
|
||||
{
|
||||
QV4::Scope scope(handle());
|
||||
|
||||
// provide a print function to write to console
|
||||
scope.engine->globalObject->defineDefaultProperty(QStringLiteral("print"), printCall);
|
||||
// provide ability to invoke the debugger
|
||||
scope.engine->globalObject->defineDefaultProperty(QStringLiteral("_debugger"), debuggerCall);
|
||||
// overwrite the eval function with our own copy which traces the scripts
|
||||
scope.engine->globalObject->defineDefaultProperty(QStringLiteral("eval"), evalCall);
|
||||
|
||||
QMutexLocker locker(&g_engineMutex);
|
||||
g_engineMap.insert(handle(), this);
|
||||
}
|
||||
|
||||
CJSEngineExt::~CJSEngineExt()
|
||||
{
|
||||
QMutexLocker locker(&g_engineMutex);
|
||||
g_engineMap.remove(handle());
|
||||
}
|
||||
|
||||
QJSValue CJSEngineExt::evaluateScript(const QString& program, const QString& fileName, int lineNumber)
|
||||
{
|
||||
QJSValue ret = QJSEngine::evaluate(program, trackScript(program, fileName, lineNumber), lineNumber);
|
||||
emit evaluateFinished(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString CJSEngineExt::trackScript(const QString& program, const QString& fileName, int lineNumber)
|
||||
{
|
||||
QString Name = QUrl(fileName).fileName();
|
||||
QString FileName = Name;
|
||||
for (int i = 0; m_ScriptIDs.contains(FileName.toLower());)
|
||||
FileName = Name + " (" + QString::number(++i) + ")";
|
||||
m_ScriptIDs.insert(FileName.toLower(), m_Scripts.count());
|
||||
m_Scripts.append(SScript{ FileName, lineNumber, program });
|
||||
return FileName;
|
||||
}
|
||||
|
||||
QV4::ReturnedValue printCall(const QV4::FunctionObject* b, const QV4::Value* v, const QV4::Value* argv, int argc)
|
||||
{
|
||||
QV4::Scope scope(b);
|
||||
QV4::ExecutionEngine* v4 = scope.engine;
|
||||
|
||||
QString Result;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (i > 0) Result.append(" ");
|
||||
Result.append(argv[i].toQStringNoThrow());
|
||||
}
|
||||
|
||||
QMutexLocker locker(&g_engineMutex);
|
||||
emit g_engineMap.value(v4)->printTrace(Result);
|
||||
|
||||
return QV4::Encode::undefined();
|
||||
}
|
||||
|
||||
QV4::ReturnedValue debuggerCall(const QV4::FunctionObject* b, const QV4::Value* v, const QV4::Value* argv, int argc)
|
||||
{
|
||||
QV4::Scope scope(b);
|
||||
QV4::ExecutionEngine* v4 = scope.engine;
|
||||
|
||||
QMutexLocker locker(&g_engineMutex);
|
||||
emit g_engineMap.value(v4)->invokeDebugger();
|
||||
|
||||
return QV4::Encode::undefined();
|
||||
}
|
||||
|
||||
QV4::ReturnedValue evalCall(const QV4::FunctionObject* b, const QV4::Value* v, const QV4::Value* argv, int argc)
|
||||
{
|
||||
// not implemented
|
||||
|
||||
return QV4::Encode::undefined();
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 David Xanatos (xanasoft.com) All rights reserved.
|
||||
** Contact: XanatosDavid@gmil.com
|
||||
**
|
||||
**
|
||||
** To use the V4ScriptTools in a commercial project, you must obtain
|
||||
** an appropriate business use license.
|
||||
**
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CJSENGINEEXT_H
|
||||
#define CJSENGINEEXT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
#include "V4ScriptDebuggerApi.h"
|
||||
|
||||
class CJSEngineExt : public QJSEngine, public CV4EngineItf
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CJSEngineExt(QObject* parent = NULL);
|
||||
~CJSEngineExt();
|
||||
|
||||
QJSEngine* self() { return this; }
|
||||
|
||||
Q_INVOKABLE QJSValue evaluateScript(const QString& program, const QString& fileName, int lineNumber = 1);
|
||||
|
||||
int getScriptCount() const { return m_Scripts.count(); }
|
||||
QString getScriptName(qint64 scriptId) const { if (scriptId < m_Scripts.size()) return m_Scripts[scriptId].Name; return QString(); }
|
||||
QString getScriptSource(qint64 scriptId) const { if (scriptId < m_Scripts.size()) return m_Scripts[scriptId].Source; return QString(); }
|
||||
int getScriptLineNumber(qint64 scriptId) const { if (scriptId < m_Scripts.size()) return m_Scripts[scriptId].LineNumber; return -1; }
|
||||
qint64 getScriptId(const QString& fileName) const { return m_ScriptIDs.value(fileName.toLower()); }
|
||||
|
||||
QString trackScript(const QString& program, const QString& fileName, int lineNumber = 1);
|
||||
|
||||
static CJSEngineExt* getEngineByHandle(void* handle);
|
||||
|
||||
signals:
|
||||
void evaluateFinished(const QJSValue& ret);
|
||||
void printTrace(const QString& Message);
|
||||
void invokeDebugger();
|
||||
|
||||
protected:
|
||||
struct SScript
|
||||
{
|
||||
QString Name;
|
||||
int LineNumber = 0;
|
||||
QString Source;
|
||||
};
|
||||
QList<SScript> m_Scripts;
|
||||
QMap<QString, qint64> m_ScriptIDs;
|
||||
|
||||
private:
|
||||
QJSValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1) { return QJSValue(); } // dont use this, use evaluateScript instead
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,212 @@
|
|||
#include "stdafx.h"
|
||||
#include "SbieObject.h"
|
||||
#include "../SandMan.h"
|
||||
#include "../Views/SbieView.h"
|
||||
#include "../Windows/SettingsWindow.h"
|
||||
#include "../QSbieAPI/SbieUtils.h"
|
||||
|
||||
QJSValue JSbieObject::getVersion()
|
||||
{
|
||||
return CSandMan::GetVersion();
|
||||
}
|
||||
|
||||
CBoxObject* CSbieObject::GetBox(const QString& Name)
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
return NULL;
|
||||
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(Name);
|
||||
if (!pBox)
|
||||
return NULL;
|
||||
CBoxEngine* pEngine = qobject_cast<CBoxEngine*>(parent());
|
||||
if(pEngine)
|
||||
emit pEngine->BoxUsed(pBox);
|
||||
if (CWizardEngine* pEngine = qobject_cast<CWizardEngine*>(parent())) {
|
||||
QSharedPointer<CSbieIni> pShadow = pEngine->MakeShadow(pBox);
|
||||
return new CSBoxObject(pShadow, pBox->GetName(), parent());
|
||||
}
|
||||
return new CBoxObject(pBox, parent());
|
||||
}
|
||||
|
||||
QStringList CSbieObject::ListBoxes()
|
||||
{
|
||||
QStringList List;
|
||||
QMap<QString, CSandBoxPtr> Boxes = theAPI->GetAllBoxes();
|
||||
foreach(const CSandBoxPtr& pBox, Boxes)
|
||||
List.append(pBox->GetName());
|
||||
return List;
|
||||
}
|
||||
|
||||
CBoxObject* CSbieObject::NewBox(const QString& Name)
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
return NULL;
|
||||
|
||||
QString BoxName = theAPI->MkNewName(Name);
|
||||
SB_STATUS Status = theAPI->CreateBox(BoxName, true);
|
||||
if (Status.IsError())
|
||||
return NULL;
|
||||
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
|
||||
if (!pBox)
|
||||
return NULL;
|
||||
CBoxEngine* pEngine = qobject_cast<CBoxEngine*>(parent());
|
||||
if(pEngine)
|
||||
emit pEngine->BoxUsed(pBox);
|
||||
if (CWizardEngine* pEngine = qobject_cast<CWizardEngine*>(parent())) {
|
||||
pEngine->AddShadow(pBox);
|
||||
return new CSBoxObject(pBox, pBox->GetName(), parent());
|
||||
}
|
||||
return new CBoxObject(pBox, parent());
|
||||
}
|
||||
|
||||
CIniObject* CSbieObject::GetTemplate(const QString& Name)
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
return NULL;
|
||||
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni("Template_" + Name, theAPI));
|
||||
if (Name.left(6) == "Local_") {
|
||||
if (CWizardEngine* pEngine = qobject_cast<CWizardEngine*>(parent())) {
|
||||
QSharedPointer<CSbieIni> pShadow = pEngine->MakeShadow(pTemplate);
|
||||
return new CSTmplObject(pShadow, pTemplate->GetName(), parent());
|
||||
}
|
||||
}
|
||||
return new CIniObject(pTemplate, true, parent());
|
||||
}
|
||||
|
||||
QStringList CSbieObject::ListTemplates()
|
||||
{
|
||||
QStringList List;
|
||||
for (int index = 0; ; index++)
|
||||
{
|
||||
QString Name = theAPI->SbieIniGet2("", "", index, false, true, true);
|
||||
if (Name.isNull())
|
||||
break;
|
||||
|
||||
if (Name.left(9).compare("Template_", Qt::CaseInsensitive) != 0)
|
||||
continue;
|
||||
|
||||
List.append(Name.mid(9));
|
||||
}
|
||||
return List;
|
||||
}
|
||||
|
||||
CIniObject* CSbieObject::NewTemplate(const QString& Name)
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
return NULL;
|
||||
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni("Template_" + Name, theAPI));
|
||||
pTemplate->SetText("Tmpl.Title", Name);
|
||||
pTemplate->SetText("Tmpl.Class", "Local");
|
||||
if (CWizardEngine* pEngine = qobject_cast<CWizardEngine*>(parent())) {
|
||||
pEngine->AddShadow(pTemplate);
|
||||
return new CSTmplObject(pTemplate, pTemplate->GetName(), parent());
|
||||
}
|
||||
return new CIniObject(pTemplate, parent());
|
||||
}
|
||||
|
||||
//CIniObject* CSbieObject::GetSection(const QString& Name)
|
||||
//{
|
||||
// if (!theAPI->IsConnected())
|
||||
// return NULL;
|
||||
// QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni(Name, theAPI));
|
||||
// return pTemplate ? new CIniObject(pTemplate, parent()) : NULL;
|
||||
//}
|
||||
|
||||
CIniObject* CSbieObject::GetGlobal()
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
return NULL;
|
||||
return new CIniObject(theAPI->GetGlobalSettings(), parent());
|
||||
}
|
||||
|
||||
CIniObject* CSbieObject::GetConf()
|
||||
{
|
||||
return new CIniObject(NULL, parent());
|
||||
}
|
||||
|
||||
|
||||
bool CSbieObject::SetupTrace(const QVariantMap& Options)
|
||||
{
|
||||
SB_STATUS Status = theAPI->EnableMonitor(true);
|
||||
return !Status.IsError();
|
||||
}
|
||||
|
||||
QVariantList CSbieObject::ReadTrace(const QVariantMap& Options)
|
||||
{
|
||||
int Start = Options["start"].toInt();
|
||||
int Count = Options["count"].toInt();
|
||||
|
||||
quint32 FilterPid = Options["pid"].toUInt();
|
||||
quint32 FilterTid = Options["tid"].toUInt();
|
||||
//QList<quint32> FilterTypes;
|
||||
void* pCurrentBox = Options.contains("box") ? theAPI->GetBoxByName(Options["box"].toString()).data() : 0;
|
||||
|
||||
QVariantList List;
|
||||
|
||||
const QVector<CTraceEntryPtr> &ResourceLog = theAPI->GetTrace();
|
||||
for (int i = Start; i < ResourceLog.count() && (!Count || Count > ResourceLog.count()); i++)
|
||||
{
|
||||
const CTraceEntryPtr& pEntry = ResourceLog.at(i);
|
||||
|
||||
if (pCurrentBox != NULL && pCurrentBox != pEntry->GetBoxPtr())
|
||||
continue;
|
||||
|
||||
if (FilterPid != 0 && FilterPid != pEntry->GetProcessId())
|
||||
continue;
|
||||
|
||||
if (FilterTid != 0 && FilterTid != pEntry->GetThreadId())
|
||||
continue;
|
||||
|
||||
//if (!FilterTypes.isEmpty() && !FilterTypes.contains(pEntry->GetType()))
|
||||
// continue;
|
||||
|
||||
QVariantMap Entry;
|
||||
Entry["timeStamp"] = pEntry->GetTimeStamp();
|
||||
Entry["process"] = pEntry->GetProcessName();
|
||||
Entry["pid"] = pEntry->GetProcessId();
|
||||
Entry["tid"] = pEntry->GetThreadId();
|
||||
Entry["type"] = pEntry->GetTypeStr();
|
||||
Entry["status"] = pEntry->GetStautsStr();
|
||||
Entry["name"] = pEntry->GetName();
|
||||
Entry["message"] = pEntry->GetMessage();
|
||||
List.append(Entry);
|
||||
}
|
||||
|
||||
return List;
|
||||
}
|
||||
|
||||
void CSbieObject::CleanUp(const QVariantMap& Options)
|
||||
{
|
||||
theAPI->UpdateProcesses(0, theGUI->ShowAllSessions());
|
||||
}
|
||||
|
||||
void CSbieObject::ShellInstall(const QVariantMap& Options)
|
||||
{
|
||||
CSettingsWindow::AddContextMenu(Options["legacy"].toBool());
|
||||
if (Options["runUnBoxed"].toBool()) {
|
||||
CSbieUtils::AddContextMenu2(QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe",
|
||||
tr("Run &Un-Sandboxed"),
|
||||
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
|
||||
}
|
||||
}
|
||||
|
||||
void CSbieObject::ShellRemove()
|
||||
{
|
||||
CSettingsWindow::RemoveContextMenu();
|
||||
CSbieUtils::RemoveContextMenu2();
|
||||
}
|
||||
|
||||
void CSbieObject::LogMessage(const QVariant& Message, bool bNotify)
|
||||
{
|
||||
if (Message.type() == QVariant::Map) {
|
||||
QVariantMap Data = Message.toMap();
|
||||
theGUI->OnLogSbieMessage(Data["sbiemsg"].toInt(), Data["params"].toStringList(), 4);
|
||||
} else
|
||||
theGUI->OnLogMessage(Message.toString(), bNotify);
|
||||
}
|
||||
|
||||
bool JSbieObject::isCertValid()
|
||||
{
|
||||
return g_CertInfo.valid;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
#pragma once
|
||||
#include "BoxEngine.h"
|
||||
#include "BoxObject.h"
|
||||
|
||||
class CSbieObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CSbieObject(QObject* parent) : QObject(parent) {}
|
||||
|
||||
public slots:
|
||||
CBoxObject* GetBox(const QString& Name);
|
||||
QStringList ListBoxes();
|
||||
CBoxObject* NewBox(const QString& Name);
|
||||
|
||||
CIniObject* GetTemplate(const QString& Name);
|
||||
QStringList ListTemplates();
|
||||
CIniObject* NewTemplate(const QString& Name);
|
||||
|
||||
//CIniObject* GetSection(const QString& Name);
|
||||
|
||||
CIniObject* GetGlobal();
|
||||
CIniObject* GetConf();
|
||||
|
||||
bool SetupTrace(const QVariantMap& Options);
|
||||
QVariantList ReadTrace(const QVariantMap& Options);
|
||||
|
||||
void CleanUp(const QVariantMap& Options);
|
||||
|
||||
void ShellInstall(const QVariantMap& Options);
|
||||
void ShellRemove();
|
||||
|
||||
void LogMessage(const QVariant& Message, bool bNotify);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JSbieObject
|
||||
//
|
||||
|
||||
class JSbieObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JSbieObject(CSbieObject* pObject, CBoxEngine* pEngine)
|
||||
: m_pObject(pObject), m_pEngine(pEngine) {}
|
||||
~JSbieObject() { QMetaObject::invokeMethod(m_pObject, "deleteLater"); }
|
||||
|
||||
Q_INVOKABLE QJSValue getVersion();
|
||||
|
||||
static QJSValue makeShadow(QJSValueList args) {
|
||||
QString result = "Hello, ";
|
||||
|
||||
// Access arguments passed from JavaScript
|
||||
if (args.length() > 0 && args[0].isString()) {
|
||||
QString name = args[0].toString();
|
||||
result += name;
|
||||
}
|
||||
|
||||
return QJSValue(result);
|
||||
}
|
||||
|
||||
Q_INVOKABLE QJSValue getBox(const QString& Name) {
|
||||
CBoxObject* pObj = NULL;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetBox", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CBoxObject*, pObj), Q_ARG(QString, Name));
|
||||
if(!pObj)
|
||||
return QJSValue(QJSValue::NullValue);
|
||||
if(m_pEngine->inherits("CWizardEngine"))
|
||||
return m_pEngine->m_pEngine->newQObject(new JSBoxObject(pObj, m_pEngine));
|
||||
return m_pEngine->m_pEngine->newQObject(new JBoxObject(pObj, m_pEngine));
|
||||
|
||||
}
|
||||
Q_INVOKABLE QJSValue listBoxes() {
|
||||
QStringList List;
|
||||
QMetaObject::invokeMethod(m_pObject, "ListBoxes", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QStringList, List));
|
||||
return m_pEngine->m_pEngine->toScriptValue(List);
|
||||
}
|
||||
Q_INVOKABLE QJSValue newBox(const QString& Name) {
|
||||
CBoxObject* pObj = NULL;
|
||||
QMetaObject::invokeMethod(m_pObject, "NewBox", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CBoxObject*, pObj), Q_ARG(QString, Name));
|
||||
return pObj ? m_pEngine->m_pEngine->newQObject(new JBoxObject(pObj, m_pEngine)) : QJSValue(QJSValue::NullValue);
|
||||
}
|
||||
|
||||
Q_INVOKABLE QJSValue getTemplate(const QString& Name) {
|
||||
if (Name.left(6) != "Local_") {
|
||||
// shortcut for non user defined templates
|
||||
QSharedPointer<CSbieIni> pTemplate = QSharedPointer<CSbieIni>(new CSbieIni("Template_" + Name, theAPI));
|
||||
return m_pEngine->m_pEngine->newQObject(new CIniObject(pTemplate, true, m_pEngine->m_pEngine));
|
||||
}
|
||||
CIniObject* pObj = NULL;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetTemplate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CIniObject*, pObj), Q_ARG(QString, Name));
|
||||
if(!pObj)
|
||||
return QJSValue::NullValue;
|
||||
if(m_pEngine->inherits("CWizardEngine"))
|
||||
return m_pEngine->m_pEngine->newQObject(new JSTmplObject(pObj, m_pEngine));
|
||||
return m_pEngine->m_pEngine->newQObject(new JTmplObject(pObj, m_pEngine));
|
||||
}
|
||||
Q_INVOKABLE QJSValue listTemplates() {
|
||||
QStringList List;
|
||||
QMetaObject::invokeMethod(m_pObject, "ListTemplates", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QStringList, List));
|
||||
return m_pEngine->m_pEngine->toScriptValue(List);
|
||||
}
|
||||
Q_INVOKABLE QJSValue newTemplate(const QString& Name) {
|
||||
CIniObject* pObj = NULL;
|
||||
QMetaObject::invokeMethod(m_pObject, "NewTemplate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CIniObject*, pObj), Q_ARG(QString, Name));
|
||||
return pObj ? m_pEngine->m_pEngine->newQObject(new JTmplObject(pObj, m_pEngine)) : QJSValue(QJSValue::NullValue);
|
||||
}
|
||||
|
||||
//Q_INVOKABLE QJSValue GetSection(const QString& Name) {
|
||||
// CIniObject* pObj = NULL;
|
||||
// QMetaObject::invokeMethod(m_pObject, "getSection", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CIniObject*, pObj), Q_ARG(QString, Name));
|
||||
// return pObj ? m_pEngine->m_pEngine->newQObject(new JIniObject(pObj, m_pEngine)) : QJSValue(QJSValue::NullValue);
|
||||
//}
|
||||
|
||||
Q_INVOKABLE QJSValue getGlobal() {
|
||||
CIniObject* pObj = NULL;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetGlobal", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CIniObject*, pObj));
|
||||
return pObj ? m_pEngine->m_pEngine->newQObject(new JIniObject(pObj, m_pEngine)) : QJSValue(QJSValue::NullValue);
|
||||
}
|
||||
Q_INVOKABLE QJSValue getConf() {
|
||||
CIniObject* pObj = NULL;
|
||||
QMetaObject::invokeMethod(m_pObject, "GetConf", Qt::BlockingQueuedConnection, Q_RETURN_ARG(CIniObject*, pObj));
|
||||
return pObj ? m_pEngine->m_pEngine->newQObject(new JIniObject(pObj, m_pEngine)) : QJSValue(QJSValue::NullValue);
|
||||
}
|
||||
|
||||
|
||||
Q_INVOKABLE QJSValue setupTrace(const QVariantMap& Options = QVariantMap()) {
|
||||
bool Success;
|
||||
QMetaObject::invokeMethod(m_pObject, "SetupTrace", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, Success), Q_ARG(const QVariantMap&, Options));
|
||||
return Success;
|
||||
}
|
||||
Q_INVOKABLE QJSValue readTrace(const QVariantMap& Options = QVariantMap()) {
|
||||
QVariantList List;
|
||||
QMetaObject::invokeMethod(m_pObject, "ReadTrace", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariantList, List), Q_ARG(const QVariantMap&, Options));
|
||||
return m_pEngine->m_pEngine->toScriptValue(List);
|
||||
}
|
||||
|
||||
|
||||
Q_INVOKABLE void cleanUp(const QVariantMap& Options = QVariantMap()) {
|
||||
QMetaObject::invokeMethod(m_pObject, "CleanUp", Qt::BlockingQueuedConnection, Q_ARG(const QVariantMap&, Options));
|
||||
}
|
||||
|
||||
|
||||
Q_INVOKABLE void shellInstall(const QVariantMap& Options = QVariantMap()) {
|
||||
QMetaObject::invokeMethod(m_pObject, "ShellInstall", Qt::BlockingQueuedConnection, Q_ARG(const QVariantMap&, Options));
|
||||
}
|
||||
|
||||
Q_INVOKABLE void shellRemove() {
|
||||
QMetaObject::invokeMethod(m_pObject, "ShellRemove", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
Q_INVOKABLE void logMessage(const QVariant& Message, bool bNotify = false) {
|
||||
QMetaObject::invokeMethod(m_pObject, "LogMessage", Qt::BlockingQueuedConnection, Q_ARG(const QVariant&, Message), Q_ARG(bool, bNotify));
|
||||
}
|
||||
|
||||
Q_INVOKABLE bool isCertValid();
|
||||
|
||||
protected:
|
||||
CBoxEngine* m_pEngine;
|
||||
CSbieObject* m_pObject;
|
||||
};
|
|
@ -0,0 +1,668 @@
|
|||
#include "stdafx.h"
|
||||
#include "SysObject.h"
|
||||
#include "../SandMan.h"
|
||||
#include "../QSbieAPI/Sandboxie/SbieTemplates.h"
|
||||
|
||||
#include "..\..\MiscHelpers\Common\Common.h"
|
||||
#include "..\..\MiscHelpers\Common\OtherFunctions.h"
|
||||
|
||||
#include <ntstatus.h>
|
||||
#define WIN32_NO_STATUS
|
||||
typedef long NTSTATUS;
|
||||
#include <Windows.h>
|
||||
//#include <Winternl.h>
|
||||
|
||||
#include "..\..\Sandboxie\common\win32_ntddk.h"
|
||||
|
||||
#define MAX_KEY_NAME 255
|
||||
#define MAX_VALUE_NAME 16383
|
||||
#define MAX_VALUE_DATA 1024000
|
||||
|
||||
#include <comdef.h>
|
||||
#include <wuapi.h>
|
||||
|
||||
JSysObject::JSysObject(CBoxEngine* pEngine)
|
||||
: m_pEngine(pEngine)
|
||||
{
|
||||
}
|
||||
|
||||
void JSysObject::log(const QString& line)
|
||||
{
|
||||
m_pEngine->AppendLog(line);
|
||||
}
|
||||
|
||||
void JSysObject::sleep(qint64 ms)
|
||||
{
|
||||
for (qint64 i = 0; i < ms && m_pEngine->TestRunning(); i += 10)
|
||||
QThread::msleep(10);
|
||||
}
|
||||
|
||||
|
||||
// FS
|
||||
HANDLE openFile(const QString& Path, bool bDir, bool bWrite = false)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
|
||||
std::wstring path = Path.toStdWString();
|
||||
if (path.substr(0, 1) != L"\\") // not nt path
|
||||
path = L"\\??\\" + path; // dos path
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING uni;
|
||||
|
||||
RtlInitUnicodeString(&uni, path.c_str());
|
||||
InitializeObjectAttributes(&objattrs, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
HANDLE handle = NULL;
|
||||
if (bWrite)
|
||||
NtCreateFile(&handle, GENERIC_ALL | SYNCHRONIZE, &objattrs, &Iosb, NULL, 0, FILE_SHARE_READ, FILE_OPEN_IF, (bDir ? FILE_DIRECTORY_FILE : 0) | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
|
||||
else
|
||||
NtOpenFile(&handle, GENERIC_READ | SYNCHRONIZE, &objattrs, &Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, (bDir ? FILE_DIRECTORY_FILE : 0) | FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::listDir(const QString& Path, const QStringList& filter, bool bSubDirs)
|
||||
{
|
||||
QVariantList entries;
|
||||
|
||||
HANDLE handle = openFile(Path, false);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
PFILE_BOTH_DIRECTORY_INFORMATION Info = (PFILE_BOTH_DIRECTORY_INFORMATION)malloc(PAGE_SIZE);
|
||||
|
||||
for (NTSTATUS status = STATUS_SUCCESS ; status == STATUS_SUCCESS; )
|
||||
{
|
||||
HANDLE Event;
|
||||
NtCreateEvent(&Event, GENERIC_ALL, 0, NotificationEvent, FALSE);
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
status = NtQueryDirectoryFile(handle, Event, 0, 0, &Iosb, Info, PAGE_SIZE, FileBothDirectoryInformation, TRUE, NULL, FALSE);
|
||||
if (status == STATUS_PENDING){
|
||||
NtWaitForSingleObject(Event, TRUE, 0);
|
||||
status = Iosb.Status;
|
||||
}
|
||||
NtClose(Event);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
if(status == STATUS_NO_MORE_FILES)
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
QString FileName = QString::fromWCharArray(Info->FileName, Info->FileNameLength / sizeof(wchar_t));
|
||||
if (FileName == "." || FileName == "..")
|
||||
continue;
|
||||
|
||||
QVariantMap entry;
|
||||
entry["isDir"] = (Info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
|
||||
entry["name"] = FileName;
|
||||
entry["path"] = Path + (Path.right(1) != "\\" ? "\\" : "") + FileName;
|
||||
entries.append(entry);
|
||||
}
|
||||
|
||||
free(Info);
|
||||
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
return m_pEngine->m_pEngine->toScriptValue(entries);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::mkDir(const QString& Path)
|
||||
{
|
||||
HANDLE handle = openFile(Path, true, true);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(handle);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::remove(const QString& Path)
|
||||
{
|
||||
std::wstring path = Path.toStdWString();
|
||||
if (path.substr(0, 1) != L"\\") // not nt path
|
||||
path = L"\\??\\" + path; // dos path
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING uni;
|
||||
|
||||
RtlInitUnicodeString(&uni, path.c_str());
|
||||
InitializeObjectAttributes(&objattrs, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
return NT_SUCCESS(NtDeleteFile(&objattrs));
|
||||
}
|
||||
|
||||
QJSValue JSysObject::exists(const QString& Path)
|
||||
{
|
||||
HANDLE handle = openFile(Path, false);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(handle);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::readFile(const QString& Path, quint64 pos, quint64 length)
|
||||
{
|
||||
HANDLE handle = openFile(Path, false);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
QByteArray Data;
|
||||
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
if (length == -1) {
|
||||
FILE_STANDARD_INFORMATION standardInfo;
|
||||
if (NT_SUCCESS(NtQueryInformationFile(handle, &Iosb, &standardInfo, sizeof(standardInfo), FileStandardInformation))) {
|
||||
length = standardInfo.EndOfFile.QuadPart;
|
||||
}
|
||||
}
|
||||
|
||||
Data.resize(length);
|
||||
LARGE_INTEGER offset;
|
||||
offset.QuadPart = pos;
|
||||
NtReadFile(handle, NULL, NULL, NULL, &Iosb, Data.data(), length, &offset, NULL);
|
||||
|
||||
CloseHandle(handle);
|
||||
return m_pEngine->m_pEngine->toScriptValue(Data);
|
||||
|
||||
}
|
||||
return QJSValue::NullValue;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::writeFile(const QString& Path, const QByteArray& Data, quint64 pos)
|
||||
{
|
||||
HANDLE handle = openFile(Path, false, true);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
if (pos == -1) { // trim
|
||||
FILE_END_OF_FILE_INFORMATION endOfFileInfo;
|
||||
endOfFileInfo.EndOfFile.QuadPart = 0;
|
||||
NtSetInformationFile(handle, &Iosb, &endOfFileInfo, sizeof(endOfFileInfo), FileEndOfFileInformation);
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
LARGE_INTEGER offset;
|
||||
offset.QuadPart = pos;
|
||||
NtWriteFile(handle, NULL, NULL, NULL, &Iosb, (PVOID)Data.data(), Data.size(), &offset, NULL);
|
||||
|
||||
CloseHandle(handle);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::getFileInfo(const QString& Path)
|
||||
{
|
||||
QVariantMap data;
|
||||
HANDLE handle = openFile(Path, false);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE) {
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
FILE_STANDARD_INFORMATION standardInfo;
|
||||
if (NT_SUCCESS(NtQueryInformationFile(handle, &Iosb, &standardInfo, sizeof(standardInfo), FileStandardInformation))) {
|
||||
data["path"] = Path;
|
||||
data["isDir"] = standardInfo.Directory;
|
||||
data["size"] = standardInfo.EndOfFile.QuadPart;
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return m_pEngine->m_pEngine->toScriptValue(data);
|
||||
}
|
||||
|
||||
|
||||
// REG
|
||||
HANDLE openRegKey(const QString& Key, bool bWrite = false)
|
||||
{
|
||||
QString Path = Key;
|
||||
if (Path.left(1) == "\\")
|
||||
Path.remove(0, 1);
|
||||
StrPair RootPath = Split2(Path, "\\");
|
||||
|
||||
HANDLE handle = NULL;
|
||||
if (RootPath.first.left(5).compare("HKEY_", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
HKEY hRoot = NULL;
|
||||
if (RootPath.first == "HKEY_CLASSES_ROOT") hRoot = HKEY_CLASSES_ROOT;
|
||||
else if (RootPath.first == "HKEY_CURRENT_USER") hRoot = HKEY_CURRENT_USER;
|
||||
else if (RootPath.first == "HKEY_LOCAL_MACHINE") hRoot = HKEY_LOCAL_MACHINE;
|
||||
else if (RootPath.first == "HKEY_USERS") hRoot = HKEY_USERS;
|
||||
else if (RootPath.first == "HKEY_PERFORMANCE_DATA") hRoot = HKEY_PERFORMANCE_DATA;
|
||||
else if (RootPath.first == "HKEY_CURRENT_CONFIG") hRoot = HKEY_CURRENT_CONFIG;
|
||||
|
||||
if (bWrite)
|
||||
RegCreateKeyEx(hRoot, RootPath.second.toStdWString().c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, (PHKEY)&handle, NULL);
|
||||
else
|
||||
RegOpenKeyEx(hRoot, RootPath.second.toStdWString().c_str(), REG_OPTION_NON_VOLATILE, KEY_READ, (PHKEY)&handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring key = Key.toStdWString();
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
UNICODE_STRING uni;
|
||||
|
||||
RtlInitUnicodeString(&uni, key.c_str());
|
||||
InitializeObjectAttributes(&objattrs, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||
|
||||
if (bWrite) {
|
||||
ULONG disposition;
|
||||
NtCreateKey(&handle, KEY_ALL_ACCESS, &objattrs, 0, NULL, 0, &disposition);
|
||||
} else
|
||||
NtOpenKey(&handle, KEY_READ, &objattrs);
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::listRegKey(const QString& Key)
|
||||
{
|
||||
QVariantList entries;
|
||||
HANDLE handle = openRegKey(Key);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
WCHAR szSubKeyName[MAX_KEY_NAME];
|
||||
DWORD dwSubKeyNameSize;
|
||||
FILETIME ftLastWriteTime;
|
||||
|
||||
for (DWORD dwIndex = 0; ; dwIndex++)
|
||||
{
|
||||
dwSubKeyNameSize = ARRAYSIZE(szSubKeyName);
|
||||
if (RegEnumKeyEx((HKEY)handle, dwIndex, szSubKeyName, &dwSubKeyNameSize, NULL, NULL, NULL, &ftLastWriteTime) != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
QVariantMap entry;
|
||||
entry["type"] = "REG_KEY";
|
||||
entry["name"] = QString::fromWCharArray(szSubKeyName);
|
||||
entries.append(entry);
|
||||
}
|
||||
|
||||
WCHAR szValueName[MAX_VALUE_NAME];
|
||||
DWORD dwValueNameSize;
|
||||
DWORD dwType;
|
||||
std::vector<BYTE> Buff;
|
||||
Buff.reserve(MAX_VALUE_DATA);
|
||||
BYTE* lpData = Buff.data();
|
||||
DWORD dwDataSize;
|
||||
|
||||
for (DWORD dwIndex = 0; ; dwIndex++)
|
||||
{
|
||||
dwValueNameSize = MAX_VALUE_NAME;
|
||||
dwDataSize = MAX_VALUE_DATA;
|
||||
if (RegEnumValue((HKEY)handle, dwIndex, szValueName, &dwValueNameSize, NULL, &dwType, lpData, &dwDataSize) != ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
QVariantMap entry;
|
||||
entry["name"] = QString::fromWCharArray(szValueName);
|
||||
switch (dwType)
|
||||
{
|
||||
case REG_NONE: entry["type"] = "REG_NONE"; break;
|
||||
case REG_SZ: entry["type"] = "REG_SZ"; entry["value"] = QString::fromStdWString((wchar_t*)lpData); break;
|
||||
case REG_EXPAND_SZ: entry["type"] = "REG_EXPAND_SZ"; entry["value"] = QString::fromStdWString((wchar_t*)lpData); break;
|
||||
case REG_BINARY: entry["type"] = "REG_BINARY"; entry["value"] = QByteArray((char*)lpData, dwDataSize); break;
|
||||
case REG_DWORD: entry["type"] = "REG_DWORD"; entry["value"] = *(quint32*)lpData; break;
|
||||
//case REG_DWORD_BIG_ENDIAN: break;
|
||||
case REG_MULTI_SZ: {entry["type"] = "REG_MULTI_SZ";
|
||||
QStringList List;
|
||||
for (wchar_t* pStr = (wchar_t*)lpData; *pStr; pStr += wcslen(pStr) + 1)
|
||||
List.append(QString::fromStdWString((wchar_t*)pStr));
|
||||
entry["value"] = List;
|
||||
break; }
|
||||
case REG_QWORD: entry["type"] = "REG_QWORD"; entry["value"] = *(quint64*)lpData;
|
||||
//case REG_LINK: break;
|
||||
//case REG_RESOURCE_LIST: break;
|
||||
//case REG_FULL_RESOURCE_DESCRIPTOR: break;
|
||||
default: entry["type"] = "REG_UNKNOWN";
|
||||
}
|
||||
entries.append(entry);
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return m_pEngine->m_pEngine->toScriptValue(entries);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::setRegValue(const QString& Key, const QString& Name, const QVariant& Value, const QString& Type)
|
||||
{
|
||||
bool bRet = false;
|
||||
HANDLE handle = openRegKey(Key, true);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD dwType = REG_NONE;
|
||||
std::vector<BYTE> Buff;
|
||||
Buff.reserve(MAX_VALUE_DATA);
|
||||
BYTE* lpData = Buff.data();
|
||||
DWORD dwDataSize = 0;
|
||||
|
||||
if (Type.isEmpty()) {
|
||||
switch (Value.type()) {
|
||||
case QVariant::String: dwType = REG_SZ; break;
|
||||
case QVariant::StringList: dwType = REG_MULTI_SZ; break;
|
||||
case QVariant::ByteArray: dwType = REG_BINARY; break;
|
||||
case QVariant::Int:
|
||||
case QVariant::UInt: dwType = REG_DWORD; break;
|
||||
case QVariant::Double: // lets cast double to QDWORD
|
||||
case QVariant::ULongLong:
|
||||
case QVariant::LongLong: dwType = REG_QWORD; break;
|
||||
}
|
||||
}
|
||||
else if (Type.compare("REG_NONE", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_NONE;
|
||||
else if (Type.compare("REG_SZ", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_SZ;
|
||||
else if (Type.compare("REG_EXPAND_SZ", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_EXPAND_SZ;
|
||||
else if (Type.compare("REG_BINARY", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_BINARY;
|
||||
else if (Type.compare("REG_DWORD", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_DWORD;
|
||||
else if (Type.compare("REG_MULTI_SZ", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_MULTI_SZ;
|
||||
else if (Type.compare("REG_QWORD", Qt::CaseInsensitive) == 0)
|
||||
dwType = REG_QWORD;
|
||||
|
||||
switch (dwType)
|
||||
{
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ: {QString str = Value.toString(); str.toWCharArray((wchar_t*)lpData); dwDataSize = (str.size() + 1) * sizeof(wchar_t); break; }
|
||||
case REG_BINARY: {QByteArray arr = Value.toByteArray(); memcpy(lpData, arr.data(), arr.size()); dwDataSize = arr.size(); break; }
|
||||
case REG_DWORD: *(quint32*)lpData = Value.toInt(); dwDataSize = sizeof(qint32); break;
|
||||
//case REG_DWORD_BIG_ENDIAN: break;
|
||||
case REG_MULTI_SZ: {BYTE* ptr = lpData;
|
||||
foreach(const QString& str, Value.toStringList()){
|
||||
str.toWCharArray((wchar_t*)ptr);
|
||||
DWORD len = (str.size() + 1) * sizeof(wchar_t);
|
||||
ptr += len;
|
||||
dwDataSize += len;
|
||||
}
|
||||
*(wchar_t*)ptr = 0;
|
||||
dwDataSize += sizeof(wchar_t);
|
||||
break; }
|
||||
case REG_QWORD: *(quint32*)lpData = Value.toLongLong(); dwDataSize = sizeof(qint64); break;
|
||||
//case REG_LINK: break;
|
||||
//case REG_RESOURCE_LIST: break;
|
||||
//case REG_FULL_RESOURCE_DESCRIPTOR: break;
|
||||
}
|
||||
|
||||
bRet = RegSetKeyValue((HKEY)handle, L"", Name.toStdWString().c_str(), dwType, lpData, dwDataSize);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::getRegValue(const QString& Key, const QString& Name)
|
||||
{
|
||||
QVariant value;
|
||||
HANDLE handle = openRegKey(Key, true);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD dwType;
|
||||
std::vector<BYTE> Buff;
|
||||
Buff.reserve(MAX_VALUE_DATA);
|
||||
BYTE* lpData = Buff.data();
|
||||
DWORD dwDataSize = MAX_VALUE_DATA;
|
||||
|
||||
if (RegQueryValueEx((HKEY)handle, Name.toStdWString().c_str(), 0, &dwType, lpData, &dwDataSize)) {
|
||||
switch (dwType)
|
||||
{
|
||||
case REG_SZ: value = QString::fromStdWString((wchar_t*)lpData); break;
|
||||
case REG_EXPAND_SZ: value = QString::fromStdWString((wchar_t*)lpData); break;
|
||||
case REG_BINARY: value = QByteArray((char*)lpData, dwDataSize); break;
|
||||
case REG_DWORD: value = *(quint32*)lpData; break;
|
||||
//case REG_DWORD_BIG_ENDIAN: break;
|
||||
case REG_MULTI_SZ: {QStringList List;
|
||||
for (wchar_t* pStr = (wchar_t*)lpData; *pStr; pStr += wcslen(pStr) + 1)
|
||||
List.append(QString::fromStdWString((wchar_t*)pStr));
|
||||
value = List;
|
||||
break; }
|
||||
case REG_QWORD: value = *(quint64*)lpData;
|
||||
//case REG_LINK: break;
|
||||
//case REG_RESOURCE_LIST: break;
|
||||
//case REG_FULL_RESOURCE_DESCRIPTOR: break;
|
||||
}
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return m_pEngine->m_pEngine->toScriptValue(value);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::removeRegKey(const QString& Key)
|
||||
{
|
||||
HANDLE handle = openRegKey(Key, true);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
NtDeleteKey(handle);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return QJSValue();
|
||||
}
|
||||
|
||||
QJSValue JSysObject::removeRegValue(const QString& Key, const QString& Name)
|
||||
{
|
||||
HANDLE handle = openRegKey(Key, true);
|
||||
if (handle && handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
RegDeleteValue((HKEY)handle, Name.toStdWString().c_str());
|
||||
CloseHandle(handle);
|
||||
}
|
||||
return QJSValue();
|
||||
}
|
||||
|
||||
|
||||
// SYS
|
||||
QJSValue JSysObject::execute(const QString& Path, const QStringList& Arguments, const QVariantMap& Options)
|
||||
{
|
||||
QProcess Process;
|
||||
if (Options.contains("workingDirectory")) Process.setWorkingDirectory(Options.value("workingDirectory").toString());
|
||||
Process.start(Path, Arguments);
|
||||
while (Process.state() != QProcess::NotRunning && m_pEngine->TestRunning()) {
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
return Process.exitCode();
|
||||
}
|
||||
|
||||
QJSValue JSysObject::expand(const QString& name)
|
||||
{
|
||||
return QProcessEnvironment::systemEnvironment().value(name);
|
||||
}
|
||||
|
||||
// OS
|
||||
QVariantMap JSysObject::GetOSVersion()
|
||||
{
|
||||
// todo improve this
|
||||
|
||||
RTL_OSVERSIONINFOEXW versionInfo;
|
||||
memset(&versionInfo, 0, sizeof(RTL_OSVERSIONINFOEXW));
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||
NTSTATUS(WINAPI *RtlGetVersion)(PRTL_OSVERSIONINFOEXW);
|
||||
*(void**)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlGetVersion");
|
||||
if (RtlGetVersion != NULL)
|
||||
RtlGetVersion(&versionInfo);
|
||||
else
|
||||
GetVersionExW((LPOSVERSIONINFOW)&versionInfo); // since windows 10 this one is lying
|
||||
RtlGetVersion(&versionInfo);
|
||||
|
||||
if (versionInfo.dwMajorVersion == 10 && versionInfo.dwBuildNumber > 22000)
|
||||
versionInfo.dwMajorVersion = 11;
|
||||
|
||||
QVariantMap ver;
|
||||
ver["major"] = (quint32)versionInfo.dwMajorVersion;
|
||||
ver["minor"] = (quint32)versionInfo.dwMinorVersion;
|
||||
ver["build"] = (quint32)versionInfo.dwBuildNumber;
|
||||
ver["platform"] = (quint32)versionInfo.dwPlatformId;
|
||||
return ver;
|
||||
}
|
||||
|
||||
QJSValue JSysObject::version()
|
||||
{
|
||||
return m_pEngine->m_pEngine->toScriptValue(GetOSVersion());
|
||||
}
|
||||
|
||||
QJSValue JSysObject::enumUpdates()
|
||||
{
|
||||
QVariantMap out;
|
||||
|
||||
IUpdateSession *updateSession = NULL;
|
||||
IUpdateSearcher *updateSearcher = NULL;
|
||||
ISearchResult *searchResult = NULL;
|
||||
IUpdateCollection *updates = NULL;
|
||||
HRESULT res;
|
||||
int ret = 1;
|
||||
|
||||
res = CoInitializeEx(NULL, 0);
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to initialize COM";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
res = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID *)&updateSession);
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to create update session";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
res = updateSession->CreateUpdateSearcher(&updateSearcher);
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to create update searcher";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
res = updateSearcher->put_IncludePotentiallySupersededUpdates(VARIANT_TRUE);
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to set search options";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
{BSTR criteria = SysAllocString(L"IsInstalled=1"); // or IsHidden=1
|
||||
res = updateSearcher->Search(criteria, &searchResult);
|
||||
SysFreeString(criteria);}
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to search for updates";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
res = searchResult->get_Updates(&updates);
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to retrieve update list from search result";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
LONG updateCount;
|
||||
res = updates->get_Count(&updateCount);
|
||||
if (FAILED(res)) {
|
||||
out["error"] = "Failed to get update count";
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
{QVariantList list;
|
||||
for (LONG i = 0L; i < updateCount; ++i)
|
||||
{
|
||||
QVariantMap entry;
|
||||
|
||||
IUpdate* update = NULL;
|
||||
res = updates->get_Item(i, &update);
|
||||
if (FAILED(res))
|
||||
entry["error"] = "Failed to get update item";
|
||||
else
|
||||
{
|
||||
IStringCollection* updateKBIDs = NULL;
|
||||
res = update->get_KBArticleIDs(&updateKBIDs);
|
||||
if (SUCCEEDED(res)) {
|
||||
LONG kbIDCount;
|
||||
res = updateKBIDs->get_Count(&kbIDCount);
|
||||
if (SUCCEEDED(res)) {
|
||||
QVariantList kb;
|
||||
for (LONG j = 0L; j < kbIDCount; ++j) {
|
||||
BSTR kbID;
|
||||
res = updateKBIDs->get_Item(j, &kbID);
|
||||
if (FAILED(res))
|
||||
continue;
|
||||
kb.append("KB" + QString::fromWCharArray(kbID));
|
||||
SysFreeString(kbID);
|
||||
}
|
||||
entry["kb"] = kb;
|
||||
}
|
||||
updateKBIDs->Release();
|
||||
}
|
||||
|
||||
BSTR updateTitle;
|
||||
res = update->get_Title(&updateTitle);
|
||||
if (FAILED(res))
|
||||
entry["error"] = "Failed to get update title";
|
||||
else {
|
||||
entry["title"] = QString::fromWCharArray(updateTitle);
|
||||
SysFreeString(updateTitle);
|
||||
}
|
||||
|
||||
update->Release();
|
||||
}
|
||||
list.append(entry);
|
||||
}
|
||||
out["list"] = list;}
|
||||
|
||||
cleanup:
|
||||
if (updates != NULL) updates->Release();
|
||||
if (searchResult != NULL) searchResult->Release();
|
||||
if (updateSearcher != NULL) updateSearcher->Release();
|
||||
if (updateSession != NULL) updateSession->Release();
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return m_pEngine->m_pEngine->toScriptValue(out);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
// todo: add sync to usage of GetCompat()
|
||||
|
||||
QJSValue JSysObject::enumClasses()
|
||||
{
|
||||
return m_pEngine->m_pEngine->toScriptValue(theGUI->GetCompat()->GetClasses());
|
||||
}
|
||||
|
||||
QJSValue JSysObject::enumServices()
|
||||
{
|
||||
return m_pEngine->m_pEngine->toScriptValue(theGUI->GetCompat()->GetServices());
|
||||
}
|
||||
|
||||
QJSValue JSysObject::enumProducts()
|
||||
{
|
||||
return m_pEngine->m_pEngine->toScriptValue(theGUI->GetCompat()->GetProducts());
|
||||
}
|
||||
|
||||
QJSValue JSysObject::enumObjects()
|
||||
{
|
||||
return m_pEngine->m_pEngine->toScriptValue(theGUI->GetCompat()->GetObjects());
|
||||
}
|
||||
|
||||
|
||||
QJSValue JSysObject::expandPath(const QString& path)
|
||||
{
|
||||
return theGUI->GetCompat()->ExpandPath(path);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::checkFile(const QString& value)
|
||||
{
|
||||
return theGUI->GetCompat()->CheckFile(value);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::checkRegKey(const QString& value)
|
||||
{
|
||||
return theGUI->GetCompat()->CheckRegistryKey(value);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::checkClasses(const QString& value)
|
||||
{
|
||||
return theGUI->GetCompat()->CheckClasses(value);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::checkServices(const QString& value)
|
||||
{
|
||||
return theGUI->GetCompat()->CheckServices(value);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::checkProducts(const QString& value)
|
||||
{
|
||||
return theGUI->GetCompat()->CheckProducts(value);
|
||||
}
|
||||
|
||||
QJSValue JSysObject::checkObjects(const QString& value)
|
||||
{
|
||||
return theGUI->GetCompat()->CheckObjects(value);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
#include "BoxEngine.h"
|
||||
|
||||
class JSysObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JSysObject(CBoxEngine* pEngine);
|
||||
|
||||
Q_INVOKABLE void log(const QString& line);
|
||||
Q_INVOKABLE void sleep(qint64 ms);
|
||||
|
||||
// FS
|
||||
Q_INVOKABLE QJSValue listDir(const QString& Path, const QStringList& filter = QStringList(), bool bSubDirs = false);
|
||||
Q_INVOKABLE QJSValue mkDir(const QString& Path);
|
||||
Q_INVOKABLE QJSValue remove(const QString& Path);
|
||||
Q_INVOKABLE QJSValue exists(const QString& Path);
|
||||
Q_INVOKABLE QJSValue readFile(const QString& Path, quint64 pos = 0, quint64 length = -1);
|
||||
Q_INVOKABLE QJSValue writeFile(const QString& Path, const QByteArray& Data, quint64 pos = -1);
|
||||
Q_INVOKABLE QJSValue getFileInfo(const QString& Path);
|
||||
|
||||
|
||||
// REG
|
||||
Q_INVOKABLE QJSValue listRegKey(const QString& Key);
|
||||
Q_INVOKABLE QJSValue setRegValue(const QString& Key, const QString& Name, const QVariant& Value, const QString& Type = QString());
|
||||
Q_INVOKABLE QJSValue getRegValue(const QString& Key, const QString& Name);
|
||||
Q_INVOKABLE QJSValue removeRegKey(const QString& Key);
|
||||
Q_INVOKABLE QJSValue removeRegValue(const QString& Key, const QString& Name);
|
||||
|
||||
// SYS
|
||||
Q_INVOKABLE QJSValue execute(const QString& Path, const QStringList& Arguments, const QVariantMap& Options = QVariantMap());
|
||||
Q_INVOKABLE QJSValue expand(const QString& name);
|
||||
|
||||
// OS
|
||||
static QVariantMap GetOSVersion();
|
||||
Q_INVOKABLE QJSValue version();
|
||||
Q_INVOKABLE QJSValue enumUpdates(); // this can take quite a while
|
||||
|
||||
//
|
||||
Q_INVOKABLE QJSValue enumClasses();
|
||||
Q_INVOKABLE QJSValue enumServices();
|
||||
Q_INVOKABLE QJSValue enumProducts();
|
||||
Q_INVOKABLE QJSValue enumObjects();
|
||||
|
||||
Q_INVOKABLE QJSValue expandPath(const QString& path);
|
||||
Q_INVOKABLE QJSValue checkFile(const QString& value);
|
||||
Q_INVOKABLE QJSValue checkRegKey(const QString& value);
|
||||
Q_INVOKABLE QJSValue checkClasses(const QString& value);
|
||||
Q_INVOKABLE QJSValue checkServices(const QString& value);
|
||||
Q_INVOKABLE QJSValue checkProducts(const QString& value);
|
||||
Q_INVOKABLE QJSValue checkObjects(const QString& value);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
CBoxEngine* m_pEngine;
|
||||
};
|
|
@ -0,0 +1,83 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2023 David Xanatos (xanasoft.com) All rights reserved.
|
||||
** Contact: XanatosDavid@gmil.com
|
||||
**
|
||||
**
|
||||
** To use the V4ScriptTools in a commercial project, you must obtain
|
||||
** an appropriate business use license.
|
||||
**
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CV4SCRIPTDEBUGGERAPI_H
|
||||
#define CV4SCRIPTDEBUGGERAPI_H
|
||||
|
||||
#include <QJSEngine>
|
||||
#include <QMainWindow>
|
||||
#include <QLibrary>
|
||||
|
||||
class CV4EngineItf
|
||||
{
|
||||
public:
|
||||
virtual QJSEngine* self() = 0;
|
||||
|
||||
virtual int getScriptCount() const = 0;
|
||||
virtual QString getScriptName(qint64 scriptId) const = 0;
|
||||
virtual QString getScriptSource(qint64 scriptId) const = 0;
|
||||
virtual int getScriptLineNumber(qint64 scriptId) const = 0;
|
||||
virtual qint64 getScriptId(const QString& fileName) const = 0;
|
||||
|
||||
//
|
||||
// Note: the implementation of this interface must be derived from
|
||||
// QObject and include the following signals and slots:
|
||||
//
|
||||
|
||||
//slots:
|
||||
// QJSValue evaluateScript(const QString& program, const QString& fileName, int lineNumber = 1);
|
||||
//
|
||||
//signals:
|
||||
// void evaluateFinished(const QJSValue& ret);
|
||||
// void printTrace(const QString& Message);
|
||||
// void invokeDebugger();
|
||||
};
|
||||
|
||||
typedef QObject* (*pNewV4ScriptDebuggerBackend)(CV4EngineItf* engine);
|
||||
typedef QObject* (*pNewJSScriptDebuggerFrontend)();
|
||||
typedef QMainWindow* (*pNewJSScriptDebugger)(QObject* frontend, QWidget *parent, Qt::WindowFlags flags);
|
||||
|
||||
__forceinline QObject* newV4ScriptDebuggerBackendDynamic(CV4EngineItf* engine)
|
||||
{
|
||||
pNewV4ScriptDebuggerBackend myNewV4ScriptDebuggerBackend = (pNewV4ScriptDebuggerBackend)QLibrary::resolve("V4ScriptDebugger", "newV4ScriptDebuggerBackend");
|
||||
if (myNewV4ScriptDebuggerBackend)
|
||||
return myNewV4ScriptDebuggerBackend(engine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__forceinline QObject* newJSScriptDebuggerFrontendDynamic()
|
||||
{
|
||||
pNewJSScriptDebuggerFrontend myNewJSScriptDebuggerFrontend = (pNewJSScriptDebuggerFrontend)QLibrary::resolve("V4ScriptDebugger", "newJSScriptDebuggerFrontend");
|
||||
if (myNewJSScriptDebuggerFrontend)
|
||||
return myNewJSScriptDebuggerFrontend();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__forceinline QMainWindow* newJSScriptDebuggerDynamic(QObject* frontend, QWidget *parent = nullptr, Qt::WindowFlags flags = {})
|
||||
{
|
||||
pNewJSScriptDebugger myNewJSScriptDebugger = (pNewJSScriptDebugger)QLibrary::resolve("V4ScriptDebugger", "newJSScriptDebugger");
|
||||
if (myNewJSScriptDebugger)
|
||||
return myNewJSScriptDebugger(frontend, parent, flags);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
#pragma once
|
||||
#include "BoxEngine.h"
|
||||
|
||||
class JWizardObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JWizardObject(CWizardEngine* pEngine) : m_pEngine(pEngine) {}
|
||||
|
||||
/*Q_INVOKABLE QJSValue showMessageBox(const QString& Type, const QString& Text){
|
||||
|
||||
//Type = "info_yes_NO_cancel";
|
||||
|
||||
return "cancel";
|
||||
}*/
|
||||
|
||||
Q_INVOKABLE QJSValue showForm(const QJSValue& form, const QString& Text = ""){
|
||||
|
||||
QMutexLocker Locker(&m_pEngine->m_Mutex);
|
||||
if (!m_pEngine->TestRunning()) return QJSValue();
|
||||
|
||||
QVariantMap Data;
|
||||
Data["type"] = "form";
|
||||
Data["form"] = form.toVariant().toList();
|
||||
Data["text"] = Text;
|
||||
m_pEngine->m_Data = Data;
|
||||
|
||||
m_pEngine->SetState(CBoxEngine::eQuery);
|
||||
if (!m_pEngine->WaitLocked()) return QJSValue();
|
||||
|
||||
return m_pEngine->m_pEngine->toScriptValue(m_pEngine->m_Data);
|
||||
}
|
||||
|
||||
Q_INVOKABLE void showStatus(const QString& Text, bool bWait = false){
|
||||
|
||||
QMutexLocker Locker(&m_pEngine->m_Mutex);
|
||||
if (!m_pEngine->TestRunning()) return;
|
||||
|
||||
m_pEngine->SetState(bWait ? CBoxEngine::eReady : CBoxEngine::eRunningAsync, Text);
|
||||
if(bWait) m_pEngine->WaitLocked();
|
||||
}
|
||||
|
||||
Q_INVOKABLE void setResult(bool bSuccess, const QString& Text = "") {
|
||||
|
||||
QMutexLocker Locker(&m_pEngine->m_Mutex);
|
||||
if (!m_pEngine->TestRunning()) return;
|
||||
|
||||
if(bSuccess) m_pEngine->SetState(CBoxEngine::eSuccess, Text);
|
||||
else m_pEngine->SetState(CBoxEngine::eFailed, Text);
|
||||
}
|
||||
|
||||
Q_INVOKABLE void reportAdd(const QString& name, const QString& value) {
|
||||
m_pEngine->m_Report[name] = value;
|
||||
}
|
||||
|
||||
protected:
|
||||
CWizardEngine* m_pEngine;
|
||||
};
|
|
@ -1,120 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>NewBoxWindow</class>
|
||||
<widget class="QWidget" name="NewBoxWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>750</width>
|
||||
<height>600</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>SandboxiePlus new box</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="txtName">
|
||||
<property name="maxLength">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Box Type Preset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Sandbox Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="cmbBoxType"/>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="5">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="5">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>A sandbox isolates your host system from processes running within the box, it prevents them from making permanent changes to other programs and data in your computer. The level of isolation impacts your security as well as the compatibility with applications, hence there will be a different level of isolation depending on the selected Box Type. Sandboxie can also protect your personal data from being accessed by processes running under its supervision.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="3">
|
||||
<widget class="QLabel" name="lblBoxInfo">
|
||||
<property name="text">
|
||||
<string>Box info</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>txtName</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -57,7 +57,7 @@ int RunElevated(const std::wstring& binaryPath, const std::wstring& Params, quin
|
|||
success = GetExitCodeProcess(sei.hProcess, &ExitCode);
|
||||
}
|
||||
CloseHandle(sei.hProcess);
|
||||
return success ? ExitCode : -103;
|
||||
return success ? ExitCode : STATUS_PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ QList<QVariant> CSbieModel::Sync(const QMap<QString, CSandBoxPtr>& BoxList, cons
|
|||
|
||||
foreach (const CSandBoxPtr& pBox, BoxList)
|
||||
{
|
||||
if (!ShowHidden && !pBox->IsEnabled())
|
||||
if (!ShowHidden && (!pBox->IsEnabled() /*|| pBox->GetBool("IsShadow")*/))
|
||||
continue;
|
||||
|
||||
QVariant ID = pBox->GetName();
|
||||
|
@ -220,8 +220,7 @@ QList<QVariant> CSbieModel::Sync(const QMap<QString, CSandBoxPtr>& BoxList, cons
|
|||
QMap<quint32, CBoxedProcessPtr> ProcessList = pBox->GetProcessList();
|
||||
|
||||
bool inUse = Sync(pBox, pNode->Path, ProcessList, New, Old, Added);
|
||||
bool bOpen = pBoxEx->IsOpen();
|
||||
bool Busy = pBoxEx->IsBusy();
|
||||
bool Busy = pBoxEx->IsBoxBusy();
|
||||
int boxType = pBoxEx->GetType();
|
||||
bool boxDel = pBoxEx->IsAutoDelete();
|
||||
bool boxNoForce = pBoxEx->IsForceDisabled();
|
||||
|
@ -241,10 +240,16 @@ QList<QVariant> CSbieModel::Sync(const QMap<QString, CSandBoxPtr>& BoxList, cons
|
|||
pNode->BoxIcon = BoxIcon;
|
||||
}
|
||||
}
|
||||
else if (pNode->inUse != inUse || pNode->bOpen != bOpen || (pNode->busyState || Busy) || pNode->boxType != boxType || pNode->boxColor != boxColor || pNode->boxDel != boxDel || pNode->boxNoForce != boxNoForce || !pNode->BoxIcon.isEmpty())
|
||||
else if (pNode->inUse != inUse ||
|
||||
(pNode->busyState || Busy) ||
|
||||
pNode->boxType != boxType ||
|
||||
pNode->boxColor != boxColor ||
|
||||
pNode->boxDel != boxDel ||
|
||||
pNode->boxNoForce != boxNoForce ||
|
||||
!pNode->BoxIcon.isEmpty()
|
||||
)
|
||||
{
|
||||
pNode->inUse = inUse;
|
||||
pNode->bOpen = bOpen;
|
||||
pNode->boxType = boxType;
|
||||
pNode->boxColor = boxColor;
|
||||
pNode->boxDel = boxDel;
|
||||
|
@ -398,13 +403,13 @@ bool CSbieModel::Sync(const CSandBoxPtr& pBox, const QList<QVariant>& Path, cons
|
|||
|
||||
if (OverlayIcons) {
|
||||
if (pProcess->HasSystemToken())
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/SystemShield.png", 20);
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/SystemShield.png");
|
||||
else if (pProcess->HasElevatedToken())
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/AdminShield.png", 20);
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/AdminShield.png");
|
||||
else if (pProcess->HasAppContainerToken())
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/AppContainer.png", 20); // AppContainer is also Restricted
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/AppContainer.png"); // AppContainer is also Restricted
|
||||
else if (pProcess->HasRestrictedToken())
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/Restricted.png", 20);
|
||||
Icon = theGUI->IconAddOverlay(Icon, ":/Actions/Restricted.png");
|
||||
}
|
||||
|
||||
pNode->Icon = Icon;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <QCryptographicHash>
|
||||
#include "Helpers/WinAdmin.h"
|
||||
#include <windows.h>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
|
@ -21,9 +22,9 @@
|
|||
#undef VERSION_MJR
|
||||
#define VERSION_MJR 1
|
||||
#undef VERSION_MIN
|
||||
#define VERSION_MIN 5
|
||||
#define VERSION_MIN 9
|
||||
#undef VERSION_REV
|
||||
#define VERSION_REV 3
|
||||
#define VERSION_REV 8
|
||||
#undef VERSION_UPD
|
||||
#define VERSION_UPD 0
|
||||
|
||||
|
@ -90,7 +91,7 @@ void COnlineUpdater::Process()
|
|||
{
|
||||
time_t NextUpdateCheck = theConf->GetUInt64("Options/NextCheckForUpdates", 0);
|
||||
if (NextUpdateCheck == 0)
|
||||
theConf->SetValue("Options/NextCheckForUpdates", QDateTime::currentDateTime().addDays(7).toSecsSinceEpoch());
|
||||
theConf->SetValue("Options/NextCheckForUpdates", QDateTime::currentDateTime().addDays(3).toSecsSinceEpoch());
|
||||
else if(QDateTime::currentDateTime().toSecsSinceEpoch() >= NextUpdateCheck)
|
||||
{
|
||||
if (iCheckUpdates == 2)
|
||||
|
@ -160,14 +161,33 @@ void COnlineUpdater::GetUpdates(QObject* receiver, const char* member, const QVa
|
|||
// Query.addQueryItem("branch", Branch);
|
||||
//Query.addQueryItem("version", theGUI->GetVersion());
|
||||
//Query.addQueryItem("version", QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV) + "." + QString::number(VERSION_UPD));
|
||||
#ifdef INSIDER_BUILD
|
||||
Query.addQueryItem("version", QString(__DATE__));
|
||||
#else
|
||||
Query.addQueryItem("version", QString::number(VERSION_MJR) + "." + QString::number(VERSION_MIN) + "." + QString::number(VERSION_REV));
|
||||
#endif
|
||||
Query.addQueryItem("system", "windows-" + QSysInfo::kernelVersion() + "-" + QSysInfo::currentCpuArchitecture());
|
||||
Query.addQueryItem("language", QLocale::system().name());
|
||||
|
||||
QString UpdateKey = GetArguments(g_Certificate, L'\n', L':').value("UPDATEKEY");
|
||||
if (UpdateKey.isEmpty())
|
||||
UpdateKey = theAPI->GetGlobalSettings()->GetText("UpdateKey"); // theConf->GetString("Options/UpdateKey");
|
||||
//if (UpdateKey.isEmpty())
|
||||
// UpdateKey = "00000000000000000000000000000000";
|
||||
if (!UpdateKey.isEmpty())
|
||||
UpdateKey += "-";
|
||||
|
||||
quint64 RandID = 0;
|
||||
theAPI->GetSecureParam("RandID", &RandID, sizeof(RandID));
|
||||
if (!RandID) {
|
||||
RandID = QRandomGenerator64::global()->generate();
|
||||
theAPI->SetSecureParam("RandID", &RandID, sizeof(RandID));
|
||||
}
|
||||
|
||||
quint32 Hash = theAPI->GetUserSettings()->GetName().mid(13).toInt(NULL, 16);
|
||||
quint64 HashID = RandID ^ (quint64((Hash & 0xFFFF) ^ ((Hash >> 16) & 0xFFFF)) << 48); // fold the hash in half and xor it with the first 16 bit of RandID
|
||||
|
||||
UpdateKey += QString::number(HashID, 16).rightJustified(16, '0').toUpper();
|
||||
Query.addQueryItem("update_key", UpdateKey);
|
||||
|
||||
if (Params.contains("channel"))
|
||||
|
@ -179,7 +199,9 @@ void COnlineUpdater::GetUpdates(QObject* receiver, const char* member, const QVa
|
|||
|
||||
Query.addQueryItem("auto", Params["manual"].toBool() ? "0" : "1");
|
||||
|
||||
//QString Test = Query.toString();
|
||||
#ifdef _DEBUG
|
||||
QString Test = Query.toString();
|
||||
#endif
|
||||
|
||||
QUrl Url("https://sandboxie-plus.com/update.php");
|
||||
Url.setQuery(Query);
|
||||
|
@ -204,9 +226,11 @@ void COnlineUpdater::CheckForUpdates(bool bManual)
|
|||
bManual = false;
|
||||
#endif
|
||||
|
||||
if (bManual) {
|
||||
m_pUpdateProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
theGUI->AddAsyncOp(m_pUpdateProgress);
|
||||
m_pUpdateProgress->ShowMessage(tr("Checking for updates..."));
|
||||
}
|
||||
|
||||
// clean up old check result
|
||||
m_UpdateData.clear();
|
||||
|
@ -681,6 +705,72 @@ bool COnlineUpdater::RunUpdater(const QStringList& Params, bool bSilent, bool Wa
|
|||
return RunElevated(wFile, wParams, Wait ? INFINITE : 0) == 0;
|
||||
}
|
||||
|
||||
void COnlineUpdater::DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params)
|
||||
{
|
||||
CGetUpdatesJob* pJob = new CGetUpdatesJob(Params, this);
|
||||
QObject::connect(pJob, SIGNAL(Download(const QString&, const QVariantMap&)), receiver, member, Qt::QueuedConnection);
|
||||
|
||||
if (m_RequestManager == NULL)
|
||||
m_RequestManager = new CNetworkAccessManager(30 * 1000, this);
|
||||
|
||||
QNetworkRequest Request = QNetworkRequest(Url);
|
||||
//Request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
Request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
//Request.setRawHeader("Accept-Encoding", "gzip");
|
||||
QNetworkReply* pReply = m_RequestManager->get(Request);
|
||||
connect(pReply, SIGNAL(finished()), this, SLOT(OnFileDownload()));
|
||||
connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(OnDownloadProgress(qint64, qint64)));
|
||||
|
||||
m_JobQueue.insert(pReply, pJob);
|
||||
}
|
||||
|
||||
void COnlineUpdater::OnFileDownload()
|
||||
{
|
||||
if(!m_pUpdateProgress.isNull())
|
||||
m_pUpdateProgress->Progress(-1);
|
||||
|
||||
QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());
|
||||
quint64 Size = pReply->bytesAvailable();
|
||||
|
||||
CGetUpdatesJob* pJob = m_JobQueue.take(pReply);
|
||||
if (!pJob)
|
||||
return;
|
||||
|
||||
QString FilePath = pJob->m_Params["path"].toString();
|
||||
if (FilePath.isEmpty()) {
|
||||
QString Name = pReply->request().url().fileName();
|
||||
if (Name.isEmpty() || Name.right(4).compare(".exe", Qt::CaseInsensitive) != 0)
|
||||
Name = "Sandboxie-Plus-Install.exe";
|
||||
FilePath = GetUpdateDir(true) + "/" + Name;
|
||||
}
|
||||
|
||||
QFile File(FilePath);
|
||||
if (File.open(QFile::WriteOnly)) {
|
||||
while (pReply->bytesAvailable() > 0)
|
||||
File.write(pReply->read(4096));
|
||||
File.flush();
|
||||
QDateTime Date = pJob->m_Params["setDate"].toDateTime();
|
||||
if(Date.isValid())
|
||||
File.setFileTime(Date, QFileDevice::FileModificationTime);
|
||||
File.close();
|
||||
}
|
||||
|
||||
pReply->deleteLater();
|
||||
|
||||
if (!m_pUpdateProgress.isNull()) {
|
||||
m_pUpdateProgress->Finish(SB_OK);
|
||||
m_pUpdateProgress.clear();
|
||||
}
|
||||
|
||||
if (File.size() != Size) {
|
||||
QMessageBox::critical(theGUI, "Sandboxie-Plus", tr("Failed to download file from: %1").arg(pReply->request().url().toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
emit pJob->Download(FilePath, pJob->m_Params);
|
||||
pJob->deleteLater();
|
||||
}
|
||||
|
||||
bool COnlineUpdater::DownloadInstaller(const QVariantMap& Release, bool bAndRun)
|
||||
{
|
||||
if (m_RequestManager == NULL)
|
||||
|
@ -699,16 +789,11 @@ bool COnlineUpdater::DownloadInstaller(const QVariantMap& Release, bool bAndRun)
|
|||
theConf->DelValue("Updater/InstallerPath");
|
||||
}
|
||||
|
||||
QNetworkRequest Request = QNetworkRequest(DownloadUrl);
|
||||
//Request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
Request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
//Request.setRawHeader("Accept-Encoding", "gzip");
|
||||
QNetworkReply* pReply = m_RequestManager->get(Request);
|
||||
pReply->setProperty("run", bAndRun);
|
||||
pReply->setProperty("version", MakeVersionStr(Release));
|
||||
pReply->setProperty("signature", Installer["signature"]);
|
||||
connect(pReply, SIGNAL(finished()), this, SLOT(OnInstallerDownload()));
|
||||
connect(pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(OnDownloadProgress(qint64, qint64)));
|
||||
QVariantMap Params;
|
||||
Params["run"] = bAndRun;
|
||||
Params["version"] = MakeVersionStr(Release);
|
||||
Params["signature"] = Installer["signature"];
|
||||
DownloadFile(DownloadUrl, this, SLOT(OnInstallerDownload(const QString&, const QVariantMap&)), Params);
|
||||
|
||||
m_pUpdateProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
theGUI->AddAsyncOp(m_pUpdateProgress);
|
||||
|
@ -717,49 +802,20 @@ bool COnlineUpdater::DownloadInstaller(const QVariantMap& Release, bool bAndRun)
|
|||
return true;
|
||||
}
|
||||
|
||||
void COnlineUpdater::OnInstallerDownload()
|
||||
void COnlineUpdater::OnInstallerDownload(const QString& Path, const QVariantMap& Params)
|
||||
{
|
||||
if (m_pUpdateProgress.isNull())
|
||||
return;
|
||||
bool bAndRun = Params["run"].toBool();
|
||||
QString VersionStr = Params["version"].toString();
|
||||
QByteArray Signature = Params["signature"].toByteArray();
|
||||
|
||||
m_pUpdateProgress->Progress(-1);
|
||||
|
||||
QNetworkReply* pReply = qobject_cast<QNetworkReply*>(sender());
|
||||
bool bAndRun = pReply->property("run").toBool();
|
||||
QString VersionStr = pReply->property("version").toString();
|
||||
QByteArray Signature = pReply->property("signature").toByteArray();
|
||||
quint64 Size = pReply->bytesAvailable();
|
||||
QString Name = pReply->request().url().fileName();
|
||||
if (Name.isEmpty() || Name.right(4).compare(".exe", Qt::CaseInsensitive) != 0)
|
||||
Name = "Sandboxie-Plus-Install.exe";
|
||||
|
||||
QString FilePath = GetUpdateDir(true) + "/" + Name;
|
||||
|
||||
QFile File(FilePath);
|
||||
if (File.open(QFile::WriteOnly)) {
|
||||
while (pReply->bytesAvailable() > 0)
|
||||
File.write(pReply->read(4096));
|
||||
File.close();
|
||||
}
|
||||
|
||||
QFile SigFile(FilePath + ".sig");
|
||||
QFile SigFile(Path + ".sig");
|
||||
if (SigFile.open(QFile::WriteOnly)) {
|
||||
SigFile.write(QByteArray::fromBase64(Signature));
|
||||
SigFile.close();
|
||||
}
|
||||
|
||||
pReply->deleteLater();
|
||||
|
||||
m_pUpdateProgress->Finish(SB_OK);
|
||||
m_pUpdateProgress.clear();
|
||||
|
||||
if (File.size() != Size) {
|
||||
QMessageBox::critical(theGUI, "Sandboxie-Plus", tr("Failed to download installer from: %1").arg(pReply->request().url().toString()));
|
||||
return;
|
||||
}
|
||||
|
||||
theConf->SetValue("Updater/InstallerVersion", VersionStr);
|
||||
theConf->SetValue("Updater/InstallerPath", FilePath);
|
||||
theConf->SetValue("Updater/InstallerPath", Path);
|
||||
|
||||
if (bAndRun)
|
||||
RunInstaller(false);
|
||||
|
@ -811,7 +867,7 @@ bool COnlineUpdater::RunInstaller2(const QString& FilePath, bool bSilent)
|
|||
QStringList Params;
|
||||
Params.append("run_setup");
|
||||
Params.append(QString(FilePath).replace("/", "\\"));
|
||||
#ifndef _DEBUG
|
||||
#ifndef _DEBUG_
|
||||
Params.append("/embedded");
|
||||
#else
|
||||
Params.append("/pause");
|
||||
|
@ -925,21 +981,41 @@ int COnlineUpdater::GetCurrentUpdate()
|
|||
return iUpdate;
|
||||
}
|
||||
|
||||
quint32 COnlineUpdater::CurrentVersion()
|
||||
{
|
||||
//quint8 myVersion[4] = { VERSION_UPD, VERSION_REV, VERSION_MIN, VERSION_MJR }; // ntohl
|
||||
quint8 myVersion[4] = { 0, VERSION_REV, VERSION_MIN, VERSION_MJR }; // ntohl
|
||||
quint32 MyVersion = *(quint32*)&myVersion;
|
||||
return MyVersion;
|
||||
}
|
||||
|
||||
quint32 COnlineUpdater::VersionToInt(const QString& VersionStr)
|
||||
{
|
||||
quint32 Version = 0;
|
||||
QStringList Nums = VersionStr.split(".");
|
||||
for (int i = 0, Bits = 24; i < Nums.count() && Bits >= 0; i++, Bits -= 8)
|
||||
Version |= (Nums[i].toInt() & 0xFF) << Bits;
|
||||
return Version;
|
||||
}
|
||||
|
||||
bool COnlineUpdater::IsVersionNewer(const QString& VersionStr)
|
||||
{
|
||||
if (VersionStr.isEmpty())
|
||||
return false;
|
||||
|
||||
//quint8 myVersion[4] = { VERSION_UPD, VERSION_REV, VERSION_MIN, VERSION_MJR }; // ntohl
|
||||
quint8 myVersion[4] = { 0, VERSION_REV, VERSION_MIN, VERSION_MJR }; // ntohl
|
||||
quint32 MyVersion = *(quint32*)&myVersion;
|
||||
#ifdef INSIDER_BUILD
|
||||
QString sVersion = VersionStr;
|
||||
if (sVersion[4] == ' ') sVersion[4] = '0';
|
||||
QDateTime VersionDate = QDateTime::fromString(sVersion, "MMM dd yyyy");
|
||||
|
||||
quint32 Version = 0;
|
||||
QStringList Nums = VersionStr.split(".");
|
||||
for (int i = 0, Bits = 24; i < Nums.count() && Bits >= 0; i++, Bits -= 8)
|
||||
Version |= (Nums[i].toInt() & 0xFF) << Bits;
|
||||
sVersion = QString(__DATE__);
|
||||
if (sVersion[4] == ' ') sVersion[4] = '0';
|
||||
QDateTime BuildDate = QDateTime::fromString(sVersion, "MMM dd yyyy");
|
||||
|
||||
return (Version > MyVersion);
|
||||
return (VersionDate > BuildDate);
|
||||
#else
|
||||
return VersionToInt(VersionStr) > CurrentVersion();
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -19,6 +19,7 @@ protected:
|
|||
|
||||
signals:
|
||||
void UpdateData(const QVariantMap& Data, const QVariantMap& Params);
|
||||
void Download(const QString& Path, const QVariantMap& Params);
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,6 +32,7 @@ public:
|
|||
void Process();
|
||||
|
||||
void GetUpdates(QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
|
||||
void DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params = QVariantMap());
|
||||
|
||||
void UpdateCert(bool bWait = false);
|
||||
|
||||
|
@ -50,15 +52,19 @@ public:
|
|||
|
||||
QString GetUpdateDir(bool bCreate = false);
|
||||
|
||||
static quint32 CurrentVersion();
|
||||
static quint32 VersionToInt(const QString& VersionStr);
|
||||
|
||||
private slots:
|
||||
void OnUpdateCheck();
|
||||
|
||||
void OnFileDownload();
|
||||
|
||||
void OnDownloadProgress(qint64 bytes, qint64 bytesTotal);
|
||||
void OnInstallerDownload(const QString& Path, const QVariantMap& Params);
|
||||
|
||||
void OnUpdateData(const QVariantMap& Data, const QVariantMap& Params);
|
||||
|
||||
void OnInstallerDownload();
|
||||
|
||||
void OnPrepareOutput();
|
||||
void OnPrepareError();
|
||||
void OnPrepareFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
|
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 791 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 722 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
|
@ -150,10 +150,31 @@
|
|||
<file>Actions/Windows.png</file>
|
||||
<file>Actions/Interface.png</file>
|
||||
<file>Actions/Notification.png</file>
|
||||
<file>Actions/Network2.png</file>
|
||||
<file>Actions/NetworkMgr.png</file>
|
||||
<file>Actions/EthSocket.png</file>
|
||||
<file>Actions/EthSocket2.png</file>
|
||||
<file>Actions/NetCard.png</file>
|
||||
<file>Actions/EthCable.png</file>
|
||||
<file>Actions/EthPlug.png</file>
|
||||
<file>Actions/Network3.png</file>
|
||||
<file>Actions/LockOpen.png</file>
|
||||
<file>Actions/LockClosed.png</file>
|
||||
<file>Actions/RamDisk.png</file>
|
||||
<file>Actions/BoxConfig.png</file>
|
||||
<file>Actions/FirstAid.png</file>
|
||||
<file>Actions/Forum.png</file>
|
||||
<file>Actions/Help.png</file>
|
||||
<file>Actions/Stack.png</file>
|
||||
<file>Actions/Warning.png</file>
|
||||
<file>Actions/PauseForce.png</file>
|
||||
<file>Actions/DisableMessagePopup.png</file>
|
||||
<file>Actions/DisableRecovery.png</file>
|
||||
<file>Actions/Plugin.png</file>
|
||||
<file>Actions/Plugins.png</file>
|
||||
<file>Actions/AntiVir.png</file>
|
||||
<file>Actions/SourceCode.png</file>
|
||||
<file>Actions/Qube.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/Boxes">
|
||||
<file alias="Empty3">Boxes/sandbox-b-empty.png</file>
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#include "Helpers/FullScreen.h"
|
||||
#include "Helpers/WinHelper.h"
|
||||
#include "../QSbieAPI/Helpers/DbgHelper.h"
|
||||
#include "Wizards/BoxAssistant.h"
|
||||
#include "Engine/BoxEngine.h"
|
||||
#include "AddonManager.h"
|
||||
|
||||
CSbiePlusAPI* theAPI = NULL;
|
||||
|
||||
|
@ -174,7 +177,12 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
connect(theAPI, SIGNAL(BoxClosed(const CSandBoxPtr&)), this, SLOT(OnBoxClosed(const CSandBoxPtr&)));
|
||||
connect(theAPI, SIGNAL(BoxCleaned(CSandBoxPlus*)), this, SLOT(OnBoxCleaned(CSandBoxPlus*)));
|
||||
|
||||
|
||||
#ifdef INSIDER_BUILD
|
||||
QString appTitle = tr("Sandboxie-Plus Insider [%1]").arg(QString(__DATE__));
|
||||
#else
|
||||
QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion());
|
||||
#endif
|
||||
|
||||
this->setWindowTitle(appTitle);
|
||||
|
||||
|
@ -185,12 +193,15 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
m_SbieTemplates = new CSbieTemplates(theAPI, this);
|
||||
|
||||
|
||||
|
||||
m_bConnectPending = false;
|
||||
m_bStopPending = false;
|
||||
|
||||
|
||||
m_pUpdater = new COnlineUpdater(this);
|
||||
|
||||
m_AddonManager = new CAddonManager(this);
|
||||
|
||||
|
||||
m_pMainWidget = new QWidget(this);
|
||||
|
||||
|
@ -277,6 +288,8 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
HandleMaintenance(Status);
|
||||
}
|
||||
|
||||
connect(CSymbolProvider::Instance(), SIGNAL(StatusChanged(const QString&)), this, SLOT(OnSymbolStatus(const QString&)));
|
||||
|
||||
//qApp->setWindowIcon(GetIcon("IconEmptyDC", false));
|
||||
}
|
||||
|
||||
|
@ -452,8 +465,9 @@ void CSandMan::CreateHelpMenu(bool bAdvanced)
|
|||
// m_pMenuBar->addAction(m_pSupport);
|
||||
//}
|
||||
m_pContribution = m_pMenuHelp->addAction(CSandMan::GetIcon("Support"), tr("Contribute to Sandboxie-Plus"), this, SLOT(OnHelp()));
|
||||
m_pManual = m_pMenuHelp->addAction(tr("Online Documentation"), this, SLOT(OnHelp()));
|
||||
m_pForum = m_pMenuHelp->addAction(tr("Visit Support Forum"), this, SLOT(OnHelp()));
|
||||
m_pBoxAssistant = m_pMenuHelp->addAction(CSandMan::GetIcon("FirstAid"), tr("Troubleshooting Wizard"), this, SLOT(OnBoxAssistant()));
|
||||
m_pManual = m_pMenuHelp->addAction(CSandMan::GetIcon("Help"), tr("Online Documentation"), this, SLOT(OnHelp()));
|
||||
m_pForum = m_pMenuHelp->addAction(CSandMan::GetIcon("Forum"), tr("Visit Support Forum"), this, SLOT(OnHelp()));
|
||||
m_pMenuHelp->addSeparator();
|
||||
m_pUpdate = m_pMenuHelp->addAction(CSandMan::GetIcon("Update"), tr("Check for Updates"), this, SLOT(CheckForUpdates()));
|
||||
m_pMenuHelp->addSeparator();
|
||||
|
@ -1476,6 +1490,13 @@ bool CSandMan::IsFullyPortable()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CSandMan::KeepTerminated()
|
||||
{
|
||||
if (CBoxEngine::GetInstanceCount() > 0)
|
||||
return true;
|
||||
return m_pKeepTerminated && m_pKeepTerminated->isChecked();
|
||||
}
|
||||
|
||||
bool CSandMan::IsSilentMode()
|
||||
{
|
||||
if (!theConf->GetBool("Options/CheckSilentMode", true))
|
||||
|
@ -1528,11 +1549,20 @@ void CSandMan::OnMessage(const QString& MsgData)
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i < Messages.length(); i++) {
|
||||
if (Messages[i].left(3) == "In:") {
|
||||
BoxName = Messages[i].mid(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CSupportDialog::CheckSupport(true);
|
||||
|
||||
if (theConf->GetBool("Options/RunInDefaultBox", false) && (QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) == 0) {
|
||||
theAPI->RunStart(theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox"), CmdLine, false, WrkDir);
|
||||
}
|
||||
if (BoxName.isEmpty() && theConf->GetBool("Options/RunInDefaultBox", false) && (QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) == 0)
|
||||
BoxName = theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox");
|
||||
|
||||
if (!BoxName.isEmpty())
|
||||
RunStart(BoxName, CmdLine, false, WrkDir);
|
||||
else
|
||||
RunSandboxed(QStringList(CmdLine), BoxName, WrkDir);
|
||||
}
|
||||
|
@ -1567,12 +1597,19 @@ bool CSandMan::RunSandboxed(const QStringList& Commands, QString BoxName, const
|
|||
{
|
||||
if (BoxName.isEmpty())
|
||||
BoxName = theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox");
|
||||
CSelectBoxWindow* pSelectBoxWindow = new CSelectBoxWindow(Commands, BoxName, WrkDir);
|
||||
CSelectBoxWindow* pSelectBoxWindow = new CSelectBoxWindow(Commands, BoxName, WrkDir, g_GUIParent);
|
||||
connect(this, SIGNAL(Closed()), pSelectBoxWindow, SLOT(close()));
|
||||
//pSelectBoxWindow->show();
|
||||
return SafeExec(pSelectBoxWindow) == 1;
|
||||
}
|
||||
|
||||
SB_RESULT(quint32) CSandMan::RunStart(const QString& BoxName, const QString& Command, bool Elevated, const QString& WorkingDir, QProcess* pProcess)
|
||||
{
|
||||
auto pBoxEx = theAPI->GetBoxByName(BoxName).objectCast<CSandBoxPlus>();
|
||||
|
||||
return theAPI->RunStart(BoxName, Command, Elevated, WorkingDir, pProcess);
|
||||
}
|
||||
|
||||
void CSandMan::dropEvent(QDropEvent* e)
|
||||
{
|
||||
QStringList Commands;
|
||||
|
@ -1602,7 +1639,7 @@ void CSandMan::timerEvent(QTimerEvent* pEvent)
|
|||
{
|
||||
SB_STATUS Status = theAPI->ReloadBoxes();
|
||||
|
||||
theAPI->UpdateProcesses(KeepTerminated(), ShowAllSessions());
|
||||
UpdateProcesses();
|
||||
|
||||
bForceProcessDisabled = theAPI->AreForceProcessDisabled();
|
||||
m_pDisableForce->setChecked(bForceProcessDisabled);
|
||||
|
@ -1746,16 +1783,33 @@ void CSandMan::OnBoxSelected()
|
|||
SB_STATUS CSandMan::DeleteBoxContent(const CSandBoxPtr& pBox, EDelMode Mode, bool DeleteSnapshots)
|
||||
{
|
||||
SB_STATUS Ret = SB_OK;
|
||||
m_iDeletingContent++;
|
||||
|
||||
if (Mode != eAuto) {
|
||||
Ret = pBox->TerminateAll();
|
||||
theAPI->UpdateProcesses(KeepTerminated(), ShowAllSessions());
|
||||
if (Ret.IsError())
|
||||
goto finish;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
|
||||
|
||||
if (Mode != eForDelete) {
|
||||
|
||||
//
|
||||
// shedule async OnBoxDelete triggers and clean up
|
||||
//
|
||||
|
||||
if (theConf->GetBool("Options/UseAsyncBoxOps", false) || theGUI->IsSilentMode())
|
||||
return pBoxEx->DeleteContentAsync(DeleteSnapshots);
|
||||
}
|
||||
|
||||
m_iDeletingContent++;
|
||||
|
||||
if (Mode != eForDelete) {
|
||||
|
||||
//
|
||||
// execute OnBoxDelete triggers
|
||||
//
|
||||
|
||||
foreach(const QString & Value, pBox->GetTextList("OnBoxDelete", true, false, true)) {
|
||||
QString Value2 = pBox->Expand(Value);
|
||||
CSbieProgressPtr pProgress = CSbieUtils::RunCommand(Value2, true);
|
||||
|
@ -1770,6 +1824,10 @@ SB_STATUS CSandMan::DeleteBoxContent(const CSandBoxPtr& pBox, EDelMode Mode, boo
|
|||
}
|
||||
|
||||
{
|
||||
//
|
||||
// delete content synchroniusly
|
||||
//
|
||||
|
||||
SB_PROGRESS Status;
|
||||
if (Mode != eForDelete && !DeleteSnapshots && pBox->HasSnapshots()) { // in auto delete mode always return to last snapshot
|
||||
QString Current;
|
||||
|
@ -1791,6 +1849,11 @@ finish:
|
|||
return Ret;
|
||||
}
|
||||
|
||||
void CSandMan::UpdateProcesses()
|
||||
{
|
||||
theAPI->UpdateProcesses(KeepTerminated() ? -1 : 1500, ShowAllSessions()); // keep for 1.5 sec
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxAdded(const CSandBoxPtr& pBox)
|
||||
{
|
||||
connect(pBox.data(), SIGNAL(StartMenuChanged()), this, SLOT(OnStartMenuChanged()));
|
||||
|
@ -1936,7 +1999,8 @@ void CSandMan::SyncStartMenu()
|
|||
} else
|
||||
OnLogMessage(tr("Added Shortcut to: %1").arg(Key));
|
||||
QDir().mkpath(Folder);
|
||||
CSbieUtils::CreateShortcut(theAPI, Location + Link.Name,
|
||||
QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe";
|
||||
CSbieUtils::CreateShortcut(StartExe, Location + Link.Name,
|
||||
Link.Name, pBoxEx->GetName(), Link.Target, Link.Icon.isEmpty() ? Link.Target : Link.Icon, Link.IconIndex);
|
||||
}
|
||||
}
|
||||
|
@ -1968,13 +2032,6 @@ void CSandMan::OnBoxClosed(const CSandBoxPtr& pBox)
|
|||
if (theConf->GetBool("Options/AutoBoxOpsNotify", false))
|
||||
OnLogMessage(tr("Auto deleting content of %1").arg(pBox->GetName()), true);
|
||||
|
||||
if (theConf->GetBool("Options/UseAsyncBoxOps", false) || IsSilentMode())
|
||||
{
|
||||
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
|
||||
SB_STATUS Status = pBoxEx->DeleteContentAsync(DeleteSnapshots);
|
||||
CheckResults(QList<SB_STATUS>() << Status);
|
||||
}
|
||||
else
|
||||
DeleteBoxContent(pBox, eAuto, DeleteSnapshots);
|
||||
}
|
||||
}
|
||||
|
@ -1994,7 +2051,12 @@ void CSandMan::OnBoxCleaned(CSandBoxPlus* pBoxEx)
|
|||
|
||||
void CSandMan::OnStatusChanged()
|
||||
{
|
||||
#ifdef INSIDER_BUILD
|
||||
QString appTitle = tr("Sandboxie-Plus Insider [%1]").arg(QString(__DATE__));
|
||||
#else
|
||||
QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion());
|
||||
#endif
|
||||
|
||||
if (theAPI->IsConnected())
|
||||
{
|
||||
bool bPortable = IsFullyPortable();
|
||||
|
@ -2041,12 +2103,12 @@ void CSandMan::OnStatusChanged()
|
|||
|
||||
QString cmd = CSbieUtils::GetContextMenuStartCmd();
|
||||
if (!cmd.isEmpty() && !cmd.contains("SandMan.exe", Qt::CaseInsensitive))
|
||||
CSettingsWindow__AddContextMenu();
|
||||
CSettingsWindow::AddContextMenu();
|
||||
}
|
||||
|
||||
m_pBoxView->Clear();
|
||||
|
||||
OnIniReloaded();
|
||||
m_pBoxView->ReloadUserConfig();
|
||||
m_pPopUpWindow->ReloadHiddenMessages();
|
||||
|
||||
theAPI->WatchIni(true, theConf->GetBool("Options/WatchIni", true));
|
||||
|
||||
|
@ -2107,7 +2169,7 @@ void CSandMan::OnStatusChanged()
|
|||
// clean up Auto Delete boxes after reboot
|
||||
//
|
||||
|
||||
theAPI->UpdateProcesses(false, ShowAllSessions());
|
||||
theAPI->UpdateProcesses(0, ShowAllSessions());
|
||||
|
||||
foreach(const CSandBoxPtr & pBox, AllBoxes) {
|
||||
if (pBox->GetActiveProcessCount() == 0)
|
||||
|
@ -2119,21 +2181,16 @@ void CSandMan::OnStatusChanged()
|
|||
if (isVisible())
|
||||
CheckSupport();
|
||||
|
||||
int WizardLevel = theConf->GetBool("Options/WizardLevel", 0);
|
||||
if (WizardLevel == 0) {
|
||||
if (!CSetupWizard::ShowWizard()) // if user canceled mark that and not show again
|
||||
theConf->SetValue("Options/WizardLevel", -1);
|
||||
int WizardLevel = abs(theConf->GetBool("Options/WizardLevel", 0));
|
||||
if (WizardLevel < (theConf->GetInt("Options/CheckForUpdates", 2) != 1 ? SETUP_LVL_2 : SETUP_LVL_1)) {
|
||||
if (!CSetupWizard::ShowWizard(WizardLevel)) { // if user canceled mark that and not show again, untill there is somethign new
|
||||
if(QMessageBox::question(NULL, "Sandboxie-Plus", tr("Do you want the setup wizard to be omited?"), QMessageBox::Yes, QMessageBox::No | QMessageBox::Default) == QMessageBox::Yes)
|
||||
theConf->SetValue("Options/WizardLevel", -SETUP_LVL_CURRENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (theConf->GetBool("Options/AutoRunSoftCompat", true))
|
||||
{
|
||||
if (m_SbieTemplates->RunCheck())
|
||||
{
|
||||
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
|
||||
connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool)));
|
||||
pSettingsWindow->showTab(CSettingsWindow::eSoftCompat);
|
||||
}
|
||||
}
|
||||
CheckCompat(this, "OpenCompat");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2151,6 +2208,48 @@ void CSandMan::OnStatusChanged()
|
|||
UpdateState();
|
||||
}
|
||||
|
||||
void CSandMan::CheckCompat(QObject* receiver, const char* member)
|
||||
{
|
||||
QElapsedTimer* timer = new QElapsedTimer();
|
||||
timer->start();
|
||||
|
||||
C7zFileEngineHandler IssueFS("issue");
|
||||
QFile File(CBoxAssistant::GetIssueDir(IssueFS) + "AppCompatibility.js");
|
||||
if (File.open(QFile::ReadOnly)) {
|
||||
CBoxEngine* pEngine = new CBoxEngine(this);
|
||||
pEngine->RunScript(File.readAll(), "AppCompatibility.js"); // note: script runs asynchroniusly
|
||||
QPointer<QObject> pObj = receiver; // QPointer tracks lifetime of receiver
|
||||
connect(pEngine, &CBoxEngine::finished, this, [pEngine, this, timer, pObj, member]() {
|
||||
|
||||
m_SbieTemplates->SetCheckResult(pEngine->GetResult().toStringList());
|
||||
|
||||
qDebug() << "Compatibility Check took" << timer->elapsed() << "ms";
|
||||
delete timer;
|
||||
pEngine->deleteLater(); // script done
|
||||
|
||||
if(pObj) QMetaObject::invokeMethod(pObj, member);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
m_SbieTemplates->RunCheck();
|
||||
|
||||
qDebug() << "Template Check took" << timer->elapsed() << "ms";
|
||||
delete timer;
|
||||
|
||||
QMetaObject::invokeMethod(receiver, member);
|
||||
}
|
||||
|
||||
void CSandMan::OpenCompat()
|
||||
{
|
||||
if (m_SbieTemplates->GetCheckState())
|
||||
{
|
||||
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
|
||||
connect(pSettingsWindow, SIGNAL(OptionsChanged(bool)), this, SLOT(UpdateSettings(bool)));
|
||||
pSettingsWindow->showTab(CSettingsWindow::eSoftCompat);
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::UpdateState()
|
||||
{
|
||||
bool isConnected = theAPI->IsConnected();
|
||||
|
@ -2390,6 +2489,13 @@ void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, qui
|
|||
m_pPopUpWindow->AddLogMessage(Message, MsgCode, MsgData, ProcessId);
|
||||
}
|
||||
|
||||
void CSandMan::SaveMessageLog(QIODevice* pFile)
|
||||
{
|
||||
QList<QStringList> Rows = m_pMessageLog->DumpPanel();
|
||||
foreach(const QStringList& Row, Rows)
|
||||
pFile->write(Row.join("\t").toLatin1() + "\n");
|
||||
}
|
||||
|
||||
bool CSandMan::CheckCertificate(QWidget* pWidget)
|
||||
{
|
||||
if (g_CertInfo.valid)
|
||||
|
@ -2773,7 +2879,7 @@ void CSandMan::HandleMaintenance(SB_RESULT(void*) Status)
|
|||
QMessageBox::warning(this, tr("Sandboxie-Plus - Error"), tr("Failed to start required Sandboxie components"));
|
||||
|
||||
OnLogMessage(tr("Maintenance operation failed (%1)").arg((quint32)dwStatus));
|
||||
CheckResults(QList<SB_STATUS>() << SB_ERR(dwStatus));
|
||||
CheckResults(QList<SB_STATUS>() << SB_ERR(dwStatus), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2782,7 +2888,7 @@ void CSandMan::HandleMaintenance(SB_RESULT(void*) Status)
|
|||
|
||||
QTimer::singleShot(1000, [this]() {
|
||||
SB_STATUS Status = this->ConnectSbieImpl();
|
||||
CheckResults(QList<SB_STATUS>() << Status);
|
||||
CheckResults(QList<SB_STATUS>() << Status, this);
|
||||
if (Status.IsError())
|
||||
theAPI->LoadEventLog();
|
||||
});
|
||||
|
@ -2803,7 +2909,7 @@ void CSandMan::HandleMaintenance(SB_RESULT(void*) Status)
|
|||
return;
|
||||
}
|
||||
|
||||
CheckResults(QList<SB_STATUS>() << Status);
|
||||
CheckResults(QList<SB_STATUS>() << Status, this);
|
||||
}
|
||||
|
||||
void CSandMan::OnViewMode(QAction* pAction)
|
||||
|
@ -2856,7 +2962,7 @@ void CSandMan::OnCleanUp()
|
|||
if(m_pRecoveryLog) m_pRecoveryLog->GetTree()->clear();
|
||||
|
||||
if (sender() == m_pCleanUpProcesses || sender() == m_pCleanUpButton)
|
||||
theAPI->UpdateProcesses(false, ShowAllSessions());
|
||||
theAPI->UpdateProcesses(0, ShowAllSessions());
|
||||
}
|
||||
|
||||
void CSandMan::OnProcView()
|
||||
|
@ -2990,8 +3096,6 @@ void CSandMan::OnResetMsgs()
|
|||
theConf->DelValue("Options/PortableStart");
|
||||
theConf->DelValue("Options/PortableRootDir");
|
||||
|
||||
theConf->DelValue("Options/CheckForUpdates");
|
||||
|
||||
theConf->DelValue("Options/NoEditInfo");
|
||||
theConf->DelValue("Options/NoEditWarn");
|
||||
|
||||
|
@ -3007,6 +3111,8 @@ void CSandMan::OnResetMsgs()
|
|||
theConf->DelValue("Options/InfoMkLink");
|
||||
|
||||
theConf->DelValue("Options/WarnOpenCOM");
|
||||
|
||||
theConf->DelValue("Options/WarnWizardOnClose");
|
||||
}
|
||||
|
||||
theAPI->GetUserSettings()->UpdateTextList("SbieCtrl_HideMessage", QStringList(), true);
|
||||
|
@ -3181,9 +3287,14 @@ void CSandMan::OnMonitoring()
|
|||
}
|
||||
}
|
||||
|
||||
SB_STATUS CSandMan::AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait, const QString& InitialMsg)
|
||||
void CSandMan::OnSymbolStatus(const QString& Message)
|
||||
{
|
||||
m_pAsyncProgress.insert(pProgress.data(), pProgress);
|
||||
statusBar()->showMessage(Message, 30*1000);
|
||||
}
|
||||
|
||||
SB_STATUS CSandMan::AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait, const QString& InitialMsg, QWidget* pParent)
|
||||
{
|
||||
m_pAsyncProgress.insert(pProgress.data(), qMakePair(pProgress, pParent));
|
||||
connect(pProgress.data(), SIGNAL(Message(const QString&)), this, SLOT(OnAsyncMessage(const QString&)));
|
||||
connect(pProgress.data(), SIGNAL(Progress(int)), this, SLOT(OnAsyncProgress(int)));
|
||||
connect(pProgress.data(), SIGNAL(Finished()), this, SLOT(OnAsyncFinished()));
|
||||
|
@ -3212,14 +3323,15 @@ void CSandMan::OnAsyncFinished()
|
|||
|
||||
void CSandMan::OnAsyncFinished(CSbieProgress* pSender)
|
||||
{
|
||||
CSbieProgressPtr pProgress = m_pAsyncProgress.take(pSender);
|
||||
auto Pair = m_pAsyncProgress.take(pSender);
|
||||
CSbieProgressPtr pProgress = Pair.first;
|
||||
if (pProgress.isNull())
|
||||
return;
|
||||
disconnect(pProgress.data() , SIGNAL(Finished()), this, SLOT(OnAsyncFinished()));
|
||||
|
||||
SB_STATUS Status = pProgress->GetStatus();
|
||||
if(Status.IsError())
|
||||
CSandMan::CheckResults(QList<SB_STATUS>() << Status);
|
||||
CheckResults(QList<SB_STATUS>() << Status, Pair.second.data());
|
||||
|
||||
if (m_pAsyncProgress.isEmpty()) {
|
||||
if(m_pProgressModal)
|
||||
|
@ -3241,8 +3353,8 @@ void CSandMan::OnAsyncProgress(int Progress)
|
|||
|
||||
void CSandMan::OnCancelAsync()
|
||||
{
|
||||
foreach(const CSbieProgressPtr& pProgress, m_pAsyncProgress)
|
||||
pProgress->Cancel();
|
||||
foreach(auto Pair, m_pAsyncProgress)
|
||||
Pair.first->Cancel();
|
||||
}
|
||||
|
||||
QString CSandMan::FormatError(const SB_STATUS& Error)
|
||||
|
@ -3273,9 +3385,11 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
|
|||
case SB_DeleteProtect: Message = tr("Delete protection is enabled for the sandbox"); break;
|
||||
case SB_DeleteNotEmpty: Message = tr("All sandbox processes must be stopped before the box content can be deleted"); break;
|
||||
case SB_DeleteError: Message = tr("Error deleting sandbox folder: %1"); break;
|
||||
case SB_RemNotStopped: Message = tr("A all processes in a sandbox must be stopped before it can be renamed."); break;
|
||||
//case SB_RemNotEmpty: Message = tr("A sandbox must be emptied before it can be renamed."); break;
|
||||
case SB_DelNotEmpty: Message = tr("A sandbox must be emptied before it can be deleted."); break;
|
||||
case SB_FailedMoveDir: Message = tr("Failed to move directory '%1' to '%2'"); break;
|
||||
case SB_FailedMoveImage:Message = tr("Failed to move box image '%1' to '%2'"); break;
|
||||
case SB_SnapIsRunning: Message = tr("This Snapshot operation can not be performed while processes are still running in the box."); break;
|
||||
case SB_SnapMkDirFail: Message = tr("Failed to create directory for new snapshot"); break;
|
||||
case SB_SnapCopyDatFail:Message = tr("Failed to copy box data files"); break;
|
||||
|
@ -3290,6 +3404,9 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
|
|||
case SB_NameExists: Message = tr("A sandbox with that name already exists"); break;
|
||||
case SB_PasswordBad: Message = tr("The config password must not be longer than 64 characters"); break;
|
||||
case SB_Canceled: Message = tr("The operation was canceled by the user"); break;
|
||||
case SB_DeleteNoMount: Message = tr("The content of an un mounted sandbox can not be deleted"); break;
|
||||
|
||||
case SB_OtherError: Message = tr("%1"); break;
|
||||
|
||||
case SBX_7zNotReady: Message = tr("Import/Export not available, 7z.dll could not be loaded"); break;
|
||||
case SBX_7zCreateFailed: Message = tr("Failed to create the box archive"); break;
|
||||
|
@ -3306,7 +3423,7 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
|
|||
return Message;
|
||||
}
|
||||
|
||||
void CSandMan::CheckResults(QList<SB_STATUS> Results, bool bAsync)
|
||||
void CSandMan::CheckResults(QList<SB_STATUS> Results, QWidget* pParent, bool bAsync)
|
||||
{
|
||||
QStringList Errors;
|
||||
for (QList<SB_STATUS>::iterator I = Results.begin(); I != Results.end(); ++I) {
|
||||
|
@ -3319,13 +3436,18 @@ void CSandMan::CheckResults(QList<SB_STATUS> Results, bool bAsync)
|
|||
theGUI->OnLogMessage(Error, true);
|
||||
}
|
||||
else if (Errors.count() == 1)
|
||||
QMessageBox::warning(theGUI, tr("Sandboxie-Plus - Error"), Errors.first());
|
||||
QMessageBox::warning(pParent ? pParent : this, tr("Sandboxie-Plus - Error"), Errors.first());
|
||||
else if (Errors.count() > 1) {
|
||||
CMultiErrorDialog Dialog(tr("Operation failed for %1 item(s).").arg(Errors.size()), Errors, theGUI);
|
||||
CMultiErrorDialog Dialog(tr("Operation failed for %1 item(s).").arg(Errors.size()), Errors, pParent ? pParent : this);
|
||||
Dialog.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxAssistant()
|
||||
{
|
||||
CBoxAssistant::ShowAssistant();
|
||||
}
|
||||
|
||||
void CSandMan::OpenUrl(const QUrl& url)
|
||||
{
|
||||
QString scheme = url.scheme();
|
||||
|
@ -3333,6 +3455,11 @@ void CSandMan::OpenUrl(const QUrl& url)
|
|||
QString path = url.path();
|
||||
QString query = url.query();
|
||||
|
||||
if (scheme == "addon") {
|
||||
m_AddonManager->TryInstallAddon(host, qobject_cast<QWidget*>(sender()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (scheme == "sbie") {
|
||||
if (path == "/check")
|
||||
m_pUpdater->CheckForUpdates(true);
|
||||
|
@ -3486,19 +3613,23 @@ void CSandMan::UpdateTitleTheme(const HWND& hwnd)
|
|||
|
||||
void CSandMan::LoadLanguage()
|
||||
{
|
||||
QString Lang = theConf->GetString("Options/UiLanguage");
|
||||
if(Lang.isEmpty())
|
||||
Lang = QLocale::system().name();
|
||||
m_Language = theConf->GetString("Options/UiLanguage");
|
||||
if(m_Language.isEmpty())
|
||||
m_Language = QLocale::system().name();
|
||||
|
||||
if (Lang.compare("native", Qt::CaseInsensitive) == 0)
|
||||
Lang.clear();
|
||||
if (m_Language.compare("native", Qt::CaseInsensitive) == 0)
|
||||
#ifdef _DEBUG
|
||||
m_Language = "en";
|
||||
#else
|
||||
m_Language.clear();
|
||||
#endif
|
||||
|
||||
m_LanguageId = LocaleNameToLCID(Lang.toStdWString().c_str(), 0);
|
||||
m_LanguageId = LocaleNameToLCID(m_Language.toStdWString().c_str(), 0);
|
||||
if (!m_LanguageId)
|
||||
m_LanguageId = 1033; // default to English
|
||||
|
||||
LoadLanguage(Lang, "sandman", 0);
|
||||
LoadLanguage(Lang, "qt", 1);
|
||||
LoadLanguage(m_Language, "sandman", 0);
|
||||
LoadLanguage(m_Language, "qt", 1);
|
||||
|
||||
QTreeViewEx::m_ResetColumns = tr("Reset Columns");
|
||||
CPanelView::m_CopyCell = tr("Copy Cell");
|
||||
|
@ -3522,10 +3653,9 @@ void CSandMan::LoadLanguage(const QString& Lang, const QString& Module, int Inde
|
|||
QString LangAux = Lang; // Short version as fallback
|
||||
LangAux.truncate(LangAux.lastIndexOf('_'));
|
||||
|
||||
C7zFileEngineHandler LangFS(QApplication::applicationDirPath() + "/translations.7z", "lang", this);
|
||||
|
||||
QString LangDir;
|
||||
if (LangFS.IsOpen())
|
||||
C7zFileEngineHandler LangFS("lang", this);
|
||||
if (LangFS.Open(QApplication::applicationDirPath() + "/translations.7z"))
|
||||
LangDir = LangFS.Prefix() + "/";
|
||||
else
|
||||
LangDir = QApplication::applicationDirPath() + "/translations/";
|
||||
|
|
|
@ -21,6 +21,7 @@ class CFileView;
|
|||
class CBoxBorder;
|
||||
class CSbieTemplates;
|
||||
class CTraceView;
|
||||
class CAddonManager;
|
||||
|
||||
struct ToolBarAction {
|
||||
// Identifier of action stored in ini. Empty for separator.
|
||||
|
@ -42,32 +43,37 @@ public:
|
|||
virtual ~CSandMan();
|
||||
|
||||
CSbieTemplates* GetCompat() { return m_SbieTemplates; }
|
||||
void CheckCompat(QObject* receiver, const char* member);
|
||||
CAddonManager* GetAddonManager() { return m_AddonManager; }
|
||||
|
||||
static QString GetVersion();
|
||||
|
||||
bool IsWFPEnabled() const;
|
||||
|
||||
SB_PROGRESS RecoverFiles(const QString& BoxName, const QList<QPair<QString, QString>>& FileList, QWidget* pParent, int Action = 0);
|
||||
static QStringList GetFileCheckers(const CSandBoxPtr& pBox);
|
||||
SB_PROGRESS CheckFiles(const QString& BoxName, const QStringList& Files);
|
||||
|
||||
enum EDelMode {
|
||||
eDefault,
|
||||
eCleanUp,
|
||||
eAuto,
|
||||
eForDelete
|
||||
};
|
||||
|
||||
SB_STATUS DeleteBoxContent(const CSandBoxPtr& pBox, EDelMode Mode, bool DeleteSnapshots = true);
|
||||
|
||||
SB_STATUS AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait = false, const QString& InitialMsg = QString());
|
||||
void UpdateProcesses();
|
||||
|
||||
SB_STATUS AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait = false, const QString& InitialMsg = QString(), QWidget* pParent = NULL);
|
||||
static QString FormatError(const SB_STATUS& Error);
|
||||
static void CheckResults(QList<SB_STATUS> Results, bool bAsync = false);
|
||||
void CheckResults(QList<SB_STATUS> Results, QWidget* pParent, bool bAsync = false);
|
||||
|
||||
static QIcon GetIcon(const QString& Name, int iAction = 1);
|
||||
|
||||
bool IsFullyPortable();
|
||||
|
||||
bool IsShowHidden() { return m_pShowHidden && m_pShowHidden->isChecked(); }
|
||||
bool KeepTerminated() { return m_pKeepTerminated && m_pKeepTerminated->isChecked(); }
|
||||
bool KeepTerminated();
|
||||
bool ShowAllSessions() { return m_pShowAllSessions && m_pShowAllSessions->isChecked(); }
|
||||
bool IsSilentMode();
|
||||
bool IsDisableRecovery() {return IsSilentMode() || m_pDisableRecovery && m_pDisableRecovery->isChecked();}
|
||||
|
@ -78,6 +84,7 @@ public:
|
|||
int SafeExec(QDialog* pDialog);
|
||||
|
||||
bool RunSandboxed(const QStringList& Commands, QString BoxName = QString(), const QString& WrkDir = QString());
|
||||
SB_RESULT(quint32) RunStart(const QString& BoxName, const QString& Command, bool Elevated = false, const QString& WorkingDir = QString(), QProcess* pProcess = NULL);
|
||||
|
||||
QIcon GetBoxIcon(int boxType, bool inUse = false);// , bool inBusy = false);
|
||||
QRgb GetBoxColor(int boxType) { return m_BoxColors[boxType]; }
|
||||
|
@ -93,6 +100,8 @@ public:
|
|||
|
||||
void UpdateCertState();
|
||||
|
||||
void SaveMessageLog(QIODevice* pFile);
|
||||
|
||||
signals:
|
||||
void CertUpdated();
|
||||
|
||||
|
@ -124,8 +133,9 @@ protected:
|
|||
bool m_bStopPending;
|
||||
CBoxBorder* m_pBoxBorder;
|
||||
CSbieTemplates* m_SbieTemplates;
|
||||
CAddonManager* m_AddonManager;
|
||||
|
||||
QMap<CSbieProgress*, CSbieProgressPtr> m_pAsyncProgress;
|
||||
QMap<CSbieProgress*, QPair<CSbieProgressPtr, QPointer<QWidget>>> m_pAsyncProgress;
|
||||
|
||||
QStringList m_MissingTemplates;
|
||||
|
||||
|
@ -171,6 +181,8 @@ public slots:
|
|||
bool OpenRecovery(const CSandBoxPtr& pBox, bool& DeleteSnapshots, bool bCloseEmpty = false);
|
||||
class CRecoveryWindow* ShowRecovery(const CSandBoxPtr& pBox, bool bFind = true);
|
||||
|
||||
void OpenCompat();
|
||||
|
||||
void UpdateSettings(bool bRebuildUI);
|
||||
void RebuildUI();
|
||||
void OnIniReloaded();
|
||||
|
@ -214,6 +226,7 @@ private slots:
|
|||
void OnSettingsAction();
|
||||
void OnEmptyAll();
|
||||
void OnWndFinder();
|
||||
void OnBoxAssistant();
|
||||
void OnDisableForce();
|
||||
void OnDisableForce2();
|
||||
void OnDisablePopUp();
|
||||
|
@ -234,6 +247,8 @@ private slots:
|
|||
void OnReloadIni();
|
||||
void OnMonitoring();
|
||||
|
||||
void OnSymbolStatus(const QString& Message);
|
||||
|
||||
void CheckForUpdates(bool bManual = true);
|
||||
|
||||
void OnExit();
|
||||
|
@ -380,6 +395,9 @@ private:
|
|||
QAction* m_pReloadIni;
|
||||
QAction* m_pEnableMonitoring;
|
||||
|
||||
//QMenu* m_pMenuTools;
|
||||
QAction* m_pBoxAssistant;
|
||||
|
||||
QAction* m_pSeparator;
|
||||
QLabel* m_pLabel;
|
||||
|
||||
|
@ -434,6 +452,7 @@ private:
|
|||
public:
|
||||
class COnlineUpdater*m_pUpdater;
|
||||
|
||||
QString m_Language;
|
||||
quint32 m_LanguageId;
|
||||
bool m_DarkTheme;
|
||||
bool m_FusionTheme;
|
||||
|
|
|
@ -23,7 +23,6 @@ HEADERS += ./stdafx.h \
|
|||
./Helpers/WinHelper.h \
|
||||
./Helpers/ReadDirectoryChanges.h \
|
||||
./Helpers/ReadDirectoryChangesPrivate.h \
|
||||
./Windows/NewBoxWindow.h \
|
||||
./Windows/RecoveryWindow.h \
|
||||
./Windows/PopUpWindow.h \
|
||||
./Windows/SnapshotsWindow.h \
|
||||
|
@ -34,7 +33,18 @@ HEADERS += ./stdafx.h \
|
|||
./OnlineUpdater.h \
|
||||
./Wizards/NewBoxWizard.h \
|
||||
./Wizards/TemplateWizard.h \
|
||||
./Wizards/SetupWizard.h
|
||||
./Wizards/SetupWizard.h \
|
||||
./Wizards/BoxAssistant.h \
|
||||
./Windows/BoxImageWindow.h \
|
||||
./Engine/BoxEngine.h \
|
||||
./Engine/BoxObject.h \
|
||||
./Engine/IniObject.h \
|
||||
./Engine/SbieObject.h \
|
||||
./Engine/SysObject.h \
|
||||
./Engine/V4ScriptDebuggerApi.h \
|
||||
./Engine/JSEngineExt.h \
|
||||
./Engine/WizardObject.h \
|
||||
./AddonManager.h
|
||||
|
||||
SOURCES += ./main.cpp \
|
||||
./stdafx.cpp \
|
||||
|
@ -58,7 +68,6 @@ SOURCES += ./main.cpp \
|
|||
./Helpers/ReadDirectoryChanges.cpp \
|
||||
./Helpers/ReadDirectoryChangesPrivate.cpp \
|
||||
./Helpers/WindowFromPointEx.cpp \
|
||||
./Windows/NewBoxWindow.cpp \
|
||||
./Windows/OptionsWindow.cpp \
|
||||
./Windows/PopUpWindow.cpp \
|
||||
./Windows/RecoveryWindow.cpp \
|
||||
|
@ -69,15 +78,23 @@ SOURCES += ./main.cpp \
|
|||
./OnlineUpdater.cpp \
|
||||
./Wizards/NewBoxWizard.cpp \
|
||||
./Wizards/TemplateWizard.cpp \
|
||||
./Wizards/SetupWizard.cpp
|
||||
./Wizards/SetupWizard.cpp \
|
||||
./Wizards/BoxAssistant.cpp \
|
||||
./Windows/BoxImageWindow.cpp \
|
||||
./Engine/BoxEngine.cpp \
|
||||
./Engine/BoxObject.cpp \
|
||||
./Engine/IniObject.cpp \
|
||||
./Engine/SbieObject.cpp \
|
||||
./Engine/JSEngineExt.cpp \
|
||||
./Engine/SysObject.cpp \
|
||||
./AddonManager.cpp
|
||||
|
||||
FORMS += ./Forms/NewBoxWindow.ui \
|
||||
FORMS += ./Forms/SelectBoxWindow.ui \
|
||||
./Forms/OptionsWindow.ui \
|
||||
./Forms/PopUpWindow.ui \
|
||||
./Forms/RecoveryWindow.ui \
|
||||
./Forms/SettingsWindow.ui \
|
||||
./Forms/SnapshotsWindow.ui \
|
||||
./Forms/SelectBoxWindow.ui
|
||||
./Forms/SnapshotsWindow.ui
|
||||
|
||||
TRANSLATIONS += sandman_de.ts \
|
||||
sandman_en.ts \
|
||||
|
|
|
@ -3,7 +3,7 @@ TEMPLATE = app
|
|||
TARGET = SandMan
|
||||
PRECOMPILED_HEADER = stdafx.h
|
||||
|
||||
QT += core gui network widgets concurrent
|
||||
QT += core gui network widgets widgets-private concurrent core-private qml qml-private
|
||||
|
||||
CONFIG += lrelease
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
</ImportGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<QtInstall>msvc2019_64</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;winextras;concurrent</QtModules>
|
||||
<QtModules>core;network;gui;widgets;qml;winextras;concurrent;widgets-private;qml-private</QtModules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="QtSettings">
|
||||
<QtInstall>msvc2019_64</QtInstall>
|
||||
|
@ -127,7 +127,7 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<QtInstall>msvc2019_64</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;winextras;concurrent</QtModules>
|
||||
<QtModules>core;gui;network;qml;widgets;concurrent;widgets-private;qml-private</QtModules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="QtSettings">
|
||||
<QtInstall>msvc2019_64</QtInstall>
|
||||
|
@ -160,7 +160,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
|
@ -182,7 +182,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
|
@ -207,7 +207,7 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
@ -228,7 +228,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
|
@ -249,7 +249,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -273,13 +273,27 @@
|
|||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>QSbieAPI.lib;MiscHelpers.lib;ntdll.lib;QtSingleApp.lib;UGlobalHotkey.lib;comctl32.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\SandboxieTools\Common\verify.c">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BoxJob.cpp" />
|
||||
<ClCompile Include="BoxMonitor.cpp" />
|
||||
<ClCompile Include="Dialogs\MultiErrorDialog.cpp" />
|
||||
<ClCompile Include="Engine\BoxEngine.cpp" />
|
||||
<ClCompile Include="Engine\BoxObject.cpp" />
|
||||
<ClCompile Include="Engine\IniObject.cpp" />
|
||||
<ClCompile Include="Engine\JSEngineExt.cpp" />
|
||||
<ClCompile Include="Engine\SbieObject.cpp" />
|
||||
<ClCompile Include="Engine\SysObject.cpp" />
|
||||
<ClCompile Include="Helpers\FindTool.cpp" />
|
||||
<ClCompile Include="Helpers\FullScreen.cpp" />
|
||||
<ClCompile Include="Helpers\ReadDirectoryChanges.cpp" />
|
||||
|
@ -292,6 +306,7 @@
|
|||
<ClCompile Include="Models\TraceModel.cpp" />
|
||||
<ClCompile Include="Models\SbieModel.cpp" />
|
||||
<ClCompile Include="OnlineUpdater.cpp" />
|
||||
<ClCompile Include="AddonManager.cpp" />
|
||||
<ClCompile Include="SandMan.cpp" />
|
||||
<ClCompile Include="SandManRecovery.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
|
@ -331,7 +346,6 @@
|
|||
<ClCompile Include="Views\SbieView.cpp" />
|
||||
<ClCompile Include="Views\StackView.cpp" />
|
||||
<ClCompile Include="Views\TraceView.cpp" />
|
||||
<ClCompile Include="Windows\NewBoxWindow.cpp" />
|
||||
<ClCompile Include="Windows\OptionsAccess.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
|
@ -419,11 +433,13 @@
|
|||
<ClCompile Include="Windows\SettingsWindow.cpp" />
|
||||
<ClCompile Include="Windows\SnapshotsWindow.cpp" />
|
||||
<ClCompile Include="Windows\SupportDialog.cpp" />
|
||||
<ClCompile Include="Wizards\BoxAssistant.cpp" />
|
||||
<ClCompile Include="Wizards\NewBoxWizard.cpp" />
|
||||
<ClCompile Include="Wizards\SetupWizard.cpp" />
|
||||
<ClCompile Include="Wizards\TemplateWizard.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="Wizards\BoxAssistant.h" />
|
||||
<QtMoc Include="Views\StackView.h" />
|
||||
<QtMoc Include="Wizards\TemplateWizard.h" />
|
||||
<QtMoc Include="Wizards\NewBoxWizard.h" />
|
||||
|
@ -433,7 +449,6 @@
|
|||
<QtMoc Include="Wizards\SetupWizard.h" />
|
||||
<QtMoc Include="Windows\SelectBoxWindow.h" />
|
||||
<QtMoc Include="Views\TraceView.h" />
|
||||
<QtMoc Include="Windows\NewBoxWindow.h" />
|
||||
<QtMoc Include="Windows\RecoveryWindow.h" />
|
||||
<QtMoc Include="Windows\PopUpWindow.h" />
|
||||
<QtMoc Include="Windows\SnapshotsWindow.h" />
|
||||
|
@ -447,6 +462,14 @@
|
|||
<QtMoc Include="BoxJob.h" />
|
||||
<ClInclude Include="..\version.h" />
|
||||
<QtMoc Include="BoxMonitor.h" />
|
||||
<QtMoc Include="Engine\BoxEngine.h" />
|
||||
<QtMoc Include="Engine\BoxObject.h" />
|
||||
<QtMoc Include="Engine\SbieObject.h" />
|
||||
<QtMoc Include="Engine\IniObject.h" />
|
||||
<QtMoc Include="Engine\SysObject.h" />
|
||||
<QtMoc Include="Engine\WizardObject.h" />
|
||||
<QtMoc Include="Engine\JSEngineExt.h" />
|
||||
<ClInclude Include="Engine\V4ScriptDebuggerApi.h" />
|
||||
<ClInclude Include="Helpers\FindTool.h" />
|
||||
<ClInclude Include="Helpers\FullScreen.h" />
|
||||
<ClInclude Include="Helpers\ReadDirectoryChanges.h" />
|
||||
|
@ -455,6 +478,7 @@
|
|||
<ClInclude Include="Helpers\WinAdmin.h" />
|
||||
<QtMoc Include="Models\MonitorModel.h" />
|
||||
<ClInclude Include="Helpers\WinHelper.h" />
|
||||
<QtMoc Include="AddonManager.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<QtMoc Include="SbiePlusAPI.h" />
|
||||
<QtMoc Include="SbieProcess.h" />
|
||||
|
@ -469,7 +493,6 @@
|
|||
<Image Include="Resources\SandMan.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="Forms\NewBoxWindow.ui" />
|
||||
<QtUic Include="Forms\OptionsWindow.ui" />
|
||||
<QtUic Include="Forms\PopUpWindow.ui" />
|
||||
<QtUic Include="Forms\RecoveryWindow.ui" />
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
<Filter Include="Wizards">
|
||||
<UniqueIdentifier>{4bf40c7e-2ce4-4528-813c-3b48b8c56155}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Engine">
|
||||
<UniqueIdentifier>{7f2e2eea-0d08-44d4-af39-01390e441438}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
|
@ -90,9 +93,6 @@
|
|||
<ClCompile Include="Windows\RecoveryWindow.cpp">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Windows\NewBoxWindow.cpp">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Helpers\FindTool.cpp">
|
||||
<Filter>Helpers</Filter>
|
||||
</ClCompile>
|
||||
|
@ -192,6 +192,33 @@
|
|||
<ClCompile Include="Views\StackView.cpp">
|
||||
<Filter>Views</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Wizards\BoxAssistant.cpp">
|
||||
<Filter>Wizards</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Engine\BoxEngine.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Engine\BoxObject.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Engine\SbieObject.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Engine\SysObject.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Engine\IniObject.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Engine\JSEngineExt.cpp">
|
||||
<Filter>Engine</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AddonManager.cpp">
|
||||
<Filter>SandMan</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\SandboxieTools\Common\verify.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
|
@ -224,6 +251,9 @@
|
|||
<ClInclude Include="Helpers\WinHelper.h">
|
||||
<Filter>Helpers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Engine\V4ScriptDebuggerApi.h">
|
||||
<Filter>Engine</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="SandMan.h">
|
||||
|
@ -256,9 +286,6 @@
|
|||
<QtMoc Include="Windows\RecoveryWindow.h">
|
||||
<Filter>Windows</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Windows\NewBoxWindow.h">
|
||||
<Filter>Windows</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Models\TraceModel.h">
|
||||
<Filter>Models</Filter>
|
||||
</QtMoc>
|
||||
|
@ -301,6 +328,33 @@
|
|||
<QtMoc Include="Views\StackView.h">
|
||||
<Filter>Views</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Wizards\BoxAssistant.h">
|
||||
<Filter>Wizards</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\BoxEngine.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\BoxObject.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\WizardObject.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\SysObject.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\SbieObject.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\IniObject.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Engine\JSEngineExt.h">
|
||||
<Filter>Engine</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="AddonManager.h">
|
||||
<Filter>SandMan</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRcc Include="Resources\SandMan.qrc">
|
||||
|
@ -334,9 +388,6 @@
|
|||
<QtUic Include="Forms\RecoveryWindow.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Forms\NewBoxWindow.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtUic Include="Forms\SelectBoxWindow.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
|
|
|
@ -72,17 +72,27 @@ CRecoveryWindow* CSandMan::ShowRecovery(const CSandBoxPtr& pBox, bool bFind)
|
|||
return pBoxEx->m_pRecoveryWnd;
|
||||
}
|
||||
|
||||
SB_PROGRESS CSandMan::CheckFiles(const QString& BoxName, const QStringList& Files)
|
||||
QStringList CSandMan::GetFileCheckers(const CSandBoxPtr& pBox)
|
||||
{
|
||||
CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
|
||||
QStringList Checkers;
|
||||
|
||||
if (theGUI->GetAddonManager()->HasAddon("FileChecker"))
|
||||
Checkers.append(pBox->Expand("powershell -exec bypass -nop -File \"%SbieHome%\\bin\\CheckFile.ps1\" -bin"));
|
||||
|
||||
if (!pBox.isNull()) {
|
||||
foreach(const QString & Value, pBox->GetTextList("OnFileRecovery", true, false, true)) {
|
||||
Checkers.append(pBox->Expand(Value));
|
||||
}
|
||||
}
|
||||
QtConcurrent::run(CSandMan::CheckFilesAsync, pProgress, BoxName, Files, Checkers);
|
||||
|
||||
return Checkers;
|
||||
}
|
||||
|
||||
SB_PROGRESS CSandMan::CheckFiles(const QString& BoxName, const QStringList& Files)
|
||||
{
|
||||
CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
|
||||
QtConcurrent::run(CSandMan::CheckFilesAsync, pProgress, BoxName, Files, GetFileCheckers(pBox));
|
||||
return SB_PROGRESS(OP_ASYNC, pProgress);
|
||||
}
|
||||
|
||||
|
@ -124,13 +134,7 @@ SB_PROGRESS CSandMan::RecoverFiles(const QString& BoxName, const QList<QPair<QSt
|
|||
{
|
||||
CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
|
||||
QStringList Checkers;
|
||||
if (!pBox.isNull()) {
|
||||
foreach(const QString & Value, pBox->GetTextList("OnFileRecovery", true, false, true)) {
|
||||
Checkers.append(pBox->Expand(Value));
|
||||
}
|
||||
}
|
||||
QtConcurrent::run(CSandMan::RecoverFilesAsync, qMakePair(pProgress, pParent), BoxName, FileList, Checkers, Action);
|
||||
QtConcurrent::run(CSandMan::RecoverFilesAsync, qMakePair(pProgress, pParent), BoxName, FileList, GetFileCheckers(pBox), Action);
|
||||
return SB_PROGRESS(OP_ASYNC, pProgress);
|
||||
}
|
||||
|
||||
|
|
|
@ -336,9 +336,6 @@ void CSandMan::OnBoxMenuHover(QAction* action)
|
|||
}
|
||||
}
|
||||
|
||||
double CSelectBoxWindow__GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value = 0.0, int Depth = 0);
|
||||
QTreeWidgetItem* CSelectBoxWindow__GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QTreeWidgetItem*>& GroupItems, QTreeWidget* treeBoxes, const QString& Name, int Depth = 0);
|
||||
|
||||
void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason)
|
||||
{
|
||||
static bool TriggerSet = false;
|
||||
|
@ -365,7 +362,7 @@ void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason)
|
|||
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
||||
QMultiMap<double, CSandBoxPtr> Boxes2;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes) {
|
||||
Boxes2.insertMulti(CSelectBoxWindow__GetBoxOrder(Groups, pBox->GetName()), pBox);
|
||||
Boxes2.insertMulti(CBoxPicker::GetBoxOrder(Groups, pBox->GetName()), pBox);
|
||||
}
|
||||
Boxes = Boxes2.values();
|
||||
}
|
||||
|
@ -387,7 +384,7 @@ void CSandMan::OnSysTray(QSystemTrayIcon::ActivationReason Reason)
|
|||
continue;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* pParent = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, m_pTrayBoxes, pBox->GetName());
|
||||
QTreeWidgetItem* pParent = CBoxPicker::GetBoxParent(Groups, GroupItems, m_pTrayBoxes, pBox->GetName());
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
pItem->setText(0, pBox->GetName().replace("_", " "));
|
||||
|
|
|
@ -92,16 +92,16 @@ void CSbiePlusAPI::StopMonitor()
|
|||
m_BoxMonitor->Stop();
|
||||
}
|
||||
|
||||
SB_STATUS CSbiePlusAPI::RunStart(const QString& BoxName, const QString& Command, bool Elevated, const QString& WorkingDir, QProcess* pProcess)
|
||||
SB_RESULT(quint32) CSbiePlusAPI::RunStart(const QString& BoxName, const QString& Command, bool Elevated, const QString& WorkingDir, QProcess* pProcess)
|
||||
{
|
||||
if (!pProcess)
|
||||
pProcess = new QProcess(this);
|
||||
SB_STATUS Status = CSbieAPI::RunStart(BoxName, Command, Elevated, WorkingDir, pProcess);
|
||||
SB_RESULT(quint32) Status = CSbieAPI::RunStart(BoxName, Command, Elevated, WorkingDir, pProcess);
|
||||
if (pProcess->parent() == this) {
|
||||
if (!Status.IsError()) {
|
||||
connect(pProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnStartFinished()));
|
||||
m_PendingStarts.insert(pProcess->processId());
|
||||
return SB_OK;
|
||||
return Status;
|
||||
}
|
||||
delete pProcess;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ void CSandBoxPlus::ExportBoxAsync(const CSbieProgressPtr& pProgress, const QStri
|
|||
}
|
||||
|
||||
SB_STATUS Status = SB_OK;
|
||||
if (!Archive.Update(&Files))
|
||||
if (!Archive.Update(&Files, true, theConf->GetInt("Options/ExportCompression", 5))) // 0, 1 - 9
|
||||
Status = SB_ERR((ESbieMsgCodes)SBX_7zCreateFailed);
|
||||
|
||||
//if(!Status.IsError() && !pProgress->IsCanceled())
|
||||
|
@ -549,22 +549,22 @@ void CSandBoxPlus::SetBoxPaths(const QString& FilePath, const QString& RegPath,
|
|||
return;
|
||||
}
|
||||
|
||||
m_IsEmpty = IsEmpty();
|
||||
|
||||
if (bPathChanged && theConf->GetBool("Options/WatchBoxSize", false) && m_TotalSize == -1)
|
||||
((CSbiePlusAPI*)theAPI)->m_BoxMonitor->ScanBox(this);
|
||||
if(bPathChanged)
|
||||
UpdateSize(false);
|
||||
|
||||
if (theConf->GetBool("Options/ScanStartMenu", true))
|
||||
ScanStartMenu();
|
||||
}
|
||||
|
||||
void CSandBoxPlus::UpdateSize()
|
||||
void CSandBoxPlus::UpdateSize(bool bReset)
|
||||
{
|
||||
if(bReset)
|
||||
m_TotalSize = -1;
|
||||
if(theConf->GetBool("Options/WatchBoxSize", false))
|
||||
((CSbiePlusAPI*)theAPI)->m_BoxMonitor->ScanBox(this);
|
||||
|
||||
m_IsEmpty = IsEmpty();
|
||||
|
||||
if(theConf->GetBool("Options/WatchBoxSize", false) && m_TotalSize == -1)
|
||||
((CSbiePlusAPI*)theAPI)->m_BoxMonitor->ScanBox(this);
|
||||
}
|
||||
|
||||
void CSandBoxPlus::SetSize(quint64 Size)
|
||||
|
@ -600,6 +600,28 @@ void CSandBoxPlus::CloseBox()
|
|||
ScanStartMenu();
|
||||
}
|
||||
|
||||
SB_STATUS CSandBoxPlus::RenameBox(const QString& NewName)
|
||||
{
|
||||
if (GetBool("IsShadow"))
|
||||
return RenameSection(NewName);
|
||||
|
||||
BeginModifyingBox();
|
||||
|
||||
SB_STATUS Status = CSandBox::RenameBox(NewName);
|
||||
|
||||
ConnectEndSlot(Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
SB_STATUS CSandBoxPlus::RemoveBox()
|
||||
{
|
||||
if (GetBool("IsShadow"))
|
||||
return RemoveSection();
|
||||
|
||||
return CSandBox::RemoveBox();
|
||||
}
|
||||
|
||||
void CSandBoxPlus::ConnectEndSlot(const SB_PROGRESS& Status)
|
||||
{
|
||||
CSbieProgressPtr pProgress = Status.GetValue();
|
||||
|
@ -628,6 +650,13 @@ void CSandBoxPlus::EndModifyingBox()
|
|||
ScanStartMenu();
|
||||
}
|
||||
|
||||
bool CSandBoxPlus::IsEmpty() const
|
||||
{
|
||||
if (!CSandBox::IsEmpty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSandBoxPlus::CheckUnsecureConfig() const
|
||||
{
|
||||
//if (GetBool("UnsafeTemplate", false, true, true)) return true;
|
||||
|
@ -975,7 +1004,7 @@ next:
|
|||
if (Status.IsError()) {
|
||||
theAPI->m_JobCount -= m_JobQueue.count();
|
||||
m_JobQueue.clear();
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status);
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, theGUI);
|
||||
return;
|
||||
}
|
||||
if (!m_JobQueue.isEmpty())
|
||||
|
@ -1003,7 +1032,7 @@ void CSandBoxPlus::OnAsyncFinished()
|
|||
if (Status.IsError()) {
|
||||
theAPI->m_JobCount -= m_JobQueue.count();
|
||||
m_JobQueue.clear();
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, true);
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, theGUI, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
|
||||
virtual void StopMonitor();
|
||||
|
||||
virtual SB_STATUS RunStart(const QString& BoxName, const QString& Command, bool Elevated = false, const QString& WorkingDir = QString(), QProcess* pProcess = NULL);
|
||||
virtual SB_RESULT(quint32) RunStart(const QString& BoxName, const QString& Command, bool Elevated = false, const QString& WorkingDir = QString(), QProcess* pProcess = NULL);
|
||||
|
||||
virtual bool IsStarting(qint64 pid) const { return m_PendingStarts.contains(pid); }
|
||||
|
||||
|
@ -47,6 +47,8 @@ protected:
|
|||
virtual CSandBox* NewSandBox(const QString& BoxName, class CSbieAPI* pAPI);
|
||||
virtual CBoxedProcess* NewBoxedProcess(quint32 ProcessId, class CSandBox* pBox);
|
||||
|
||||
virtual SB_STATUS UpdateBoxPaths(CSandBox* pSandBox) { return CSbieAPI::UpdateBoxPaths(pSandBox); }
|
||||
|
||||
virtual CBoxedProcessPtr OnProcessBoxed(quint32 ProcessId, const QString& Path, const QString& Box, quint32 ParentId, const QString& CmdLine);
|
||||
|
||||
int m_JobCount;
|
||||
|
@ -82,11 +84,14 @@ public:
|
|||
virtual void CloseBox();
|
||||
|
||||
virtual SB_PROGRESS CleanBox() { BeginModifyingBox(); SB_PROGRESS Status = CSandBox::CleanBox(); ConnectEndSlot(Status); return Status; }
|
||||
virtual SB_STATUS RenameBox(const QString& NewName) { BeginModifyingBox(); SB_STATUS Status = CSandBox::RenameBox(NewName); ConnectEndSlot(Status); return Status; }
|
||||
virtual SB_STATUS RenameBox(const QString& NewName);
|
||||
virtual SB_STATUS RemoveBox();
|
||||
virtual SB_PROGRESS TakeSnapshot(const QString& Name) { BeginModifyingBox(); SB_PROGRESS Status = CSandBox::TakeSnapshot(Name); ConnectEndSlot(Status); return Status; }
|
||||
virtual SB_PROGRESS RemoveSnapshot(const QString& ID) { BeginModifyingBox(); SB_PROGRESS Status = CSandBox::RemoveSnapshot(ID); ConnectEndSlot(Status); return Status; }
|
||||
virtual SB_PROGRESS SelectSnapshot(const QString& ID) { BeginModifyingBox(); SB_PROGRESS Status = CSandBox::SelectSnapshot(ID); ConnectEndSlot(Status); return Status; }
|
||||
|
||||
virtual bool IsEmpty() const;
|
||||
|
||||
virtual QString GetStatusStr() const;
|
||||
|
||||
virtual void SetLogApi(bool bEnable);
|
||||
|
@ -115,7 +120,7 @@ public:
|
|||
|
||||
virtual bool IsEmptyCached() const { return m_IsEmpty; }
|
||||
|
||||
virtual void UpdateSize();
|
||||
virtual void UpdateSize(bool bReset = true);
|
||||
virtual quint64 GetSize() const { if(m_TotalSize == -1) return 0; return m_TotalSize; }
|
||||
virtual void SetSize(quint64 Size); //{ m_TotalSize = Size; }
|
||||
virtual bool IsSizePending() const;
|
||||
|
@ -153,8 +158,7 @@ public:
|
|||
class COptionsWindow* m_pOptionsWnd;
|
||||
class CRecoveryWindow* m_pRecoveryWnd;
|
||||
|
||||
bool IsOpen() const { return m_bRootAccessOpen; }
|
||||
bool IsBusy() const { return IsSizePending() || !m_JobQueue.isEmpty(); }
|
||||
bool IsBoxBusy() const { return IsSizePending() || !m_JobQueue.isEmpty(); }
|
||||
SB_STATUS DeleteContentAsync(bool DeleteSnapshots = true, bool bOnAutoDelete = false);
|
||||
|
||||
struct SLink {
|
||||
|
|
|
@ -219,7 +219,7 @@ int openShellContextMenu(const QStringList& Files, void* parentWindow, const CSa
|
|||
std::wstring Str3 = CFileView::tr("Recover to Same Folder").toStdWString();
|
||||
addItemToShellContextMenu(hMenu, Str3.c_str(), MENU_RECOVER);
|
||||
|
||||
if (!pBox->GetTextList("OnFileRecovery", true, false, true).isEmpty()) {
|
||||
if (!CSandMan::GetFileCheckers(pBox).isEmpty()) {
|
||||
std::wstring Str4 = CFileView::tr("Run Recovery Checks").toStdWString();
|
||||
addItemToShellContextMenu(hMenu, Str4.c_str(), MENU_CHECK_FILE);
|
||||
}
|
||||
|
@ -354,7 +354,8 @@ void CFileView::OnFileMenu(const QPoint&)
|
|||
if (Path.isEmpty())
|
||||
return;
|
||||
|
||||
CSbieUtils::CreateShortcut(theAPI, Path, LinkName, BoxName, LinkPath, LinkPath);
|
||||
QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe";
|
||||
CSbieUtils::CreateShortcut(StartExe, Path, LinkName, BoxName, LinkPath, LinkPath);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "../Windows/SnapshotsWindow.h"
|
||||
#include "../../MiscHelpers/Common/CheckableMessageBox.h"
|
||||
#include "../Windows/RecoveryWindow.h"
|
||||
#include "../Windows/NewBoxWindow.h"
|
||||
#include "../Views/FileView.h"
|
||||
#include "../Wizards/NewBoxWizard.h"
|
||||
#include "../Helpers/WinHelper.h"
|
||||
|
@ -678,10 +677,6 @@ bool CSbieView::UpdateMenu()
|
|||
iSandBoxeCount = -1;
|
||||
else if (iSandBoxeCount != -1)
|
||||
iSandBoxeCount++;
|
||||
|
||||
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
|
||||
if(pBoxEx->IsBusy())
|
||||
bBoxBusy = true;
|
||||
}
|
||||
else
|
||||
iGroupe++;
|
||||
|
@ -992,18 +987,7 @@ bool CSbieView::MoveItem(const QString& Name, const QString& To, int pos)
|
|||
|
||||
QString CSbieView::AddNewBox(bool bAlowTemp)
|
||||
{
|
||||
QString BoxName;
|
||||
|
||||
bool bVintage = theConf->GetInt("Options/ViewMode", 1) == 2;
|
||||
|
||||
if (bVintage) {
|
||||
CNewBoxWindow NewBoxWindow(this);
|
||||
connect(theGUI, SIGNAL(Closed()), &NewBoxWindow, SLOT(close()));
|
||||
if (NewBoxWindow.exec() == 1)
|
||||
BoxName = NewBoxWindow.m_Name;
|
||||
}
|
||||
else
|
||||
BoxName = CNewBoxWizard::CreateNewBox(bAlowTemp, this);
|
||||
QString BoxName = CNewBoxWizard::CreateNewBox(bAlowTemp, this);
|
||||
|
||||
if (!BoxName.isEmpty()) {
|
||||
theAPI->ReloadBoxes();
|
||||
|
@ -1049,7 +1033,7 @@ QString CSbieView::ImportSandbox()
|
|||
}
|
||||
}
|
||||
else
|
||||
CSandMan::CheckResults(QList<SB_STATUS>() << Status);
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, this);
|
||||
|
||||
return Name;
|
||||
}
|
||||
|
@ -1117,7 +1101,7 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
return;
|
||||
if (Action == m_pStopAsync)
|
||||
{
|
||||
foreach(const CSandBoxPtr & pBox, SandBoxes)
|
||||
foreach(const CSandBoxPtr& pBox, SandBoxes)
|
||||
{
|
||||
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
|
||||
pBoxEx->OnCancelAsync();
|
||||
|
@ -1129,12 +1113,12 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
if(!Command.isEmpty())
|
||||
SandBoxes.first()->RunCommand(Command);*/
|
||||
|
||||
Results.append(SandBoxes.first()->RunStart("run_dialog"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "run_dialog"));
|
||||
}
|
||||
else if (Action == m_pMenuRunBrowser)
|
||||
Results.append(SandBoxes.first()->RunStart("default_browser"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "default_browser"));
|
||||
else if (Action == m_pMenuRunMailer)
|
||||
Results.append(SandBoxes.first()->RunStart("mail_agent"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "mail_agent"));
|
||||
else if (Action == m_pMenuRunExplorer)
|
||||
{
|
||||
if (theConf->GetInt("Options/ViewMode", 1) != 1 && theConf->GetBool("Options/BoxedExplorerInfo", true))
|
||||
|
@ -1148,21 +1132,21 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
theConf->SetValue("Options/BoxedExplorerInfo", false);
|
||||
}
|
||||
|
||||
Results.append(SandBoxes.first()->RunStart("explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"));
|
||||
}
|
||||
else if (Action == m_pMenuRunRegEdit)
|
||||
Results.append(SandBoxes.first()->RunStart("regedit.exe"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "regedit.exe"));
|
||||
else if (Action == m_pMenuRunAppWiz)
|
||||
Results.append(SandBoxes.first()->RunStart("\"C:\\WINDOWS\\System32\\control.exe\" \"C:\\Windows\\System32\\appwiz.cpl\""));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "\"C:\\WINDOWS\\System32\\control.exe\" \"C:\\Windows\\System32\\appwiz.cpl\""));
|
||||
else if (Action == m_pMenuAutoRun)
|
||||
Results.append(SandBoxes.first()->RunStart("auto_run"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "auto_run"));
|
||||
else if (Action == m_pMenuRunCmd)
|
||||
Results.append(SandBoxes.first()->RunStart("cmd.exe"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "cmd.exe"));
|
||||
else if (Action == m_pMenuRunCmdAdmin)
|
||||
Results.append(SandBoxes.first()->RunStart("cmd.exe", true));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "cmd.exe", true));
|
||||
#ifdef _WIN64
|
||||
else if (Action == m_pMenuRunCmd32)
|
||||
Results.append(SandBoxes.first()->RunStart("C:\\WINDOWS\\SysWOW64\\cmd.exe"));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "C:\\WINDOWS\\SysWOW64\\cmd.exe"));
|
||||
#endif
|
||||
else if (Action == m_pMenuPresetsShowUAC)
|
||||
{
|
||||
|
@ -1318,8 +1302,7 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
}
|
||||
|
||||
theAPI->CommitIniChanges();
|
||||
theAPI->ReloadConfig();
|
||||
theAPI->ReloadBoxes();
|
||||
theAPI->ReloadBoxes(true);
|
||||
}
|
||||
|
||||
Results.append(Status);
|
||||
|
@ -1368,13 +1351,16 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
bool bChanged = false;
|
||||
foreach(const CSandBoxPtr& pBox, SandBoxes)
|
||||
{
|
||||
if (!pBox->GetBool("IsShadow")) {
|
||||
SB_STATUS Status = theGUI->DeleteBoxContent(pBox, CSandMan::eForDelete);
|
||||
if (Status.GetMsgCode() == SB_Canceled)
|
||||
break;
|
||||
if (Status.IsError())
|
||||
continue;
|
||||
}
|
||||
|
||||
QString Name = pBox->GetName();
|
||||
if (!Status.IsError())
|
||||
Status = pBox->RemoveBox();
|
||||
SB_STATUS Status = pBox->RemoveBox();
|
||||
Results.append(Status);
|
||||
|
||||
if (!Status.IsError()) {
|
||||
|
@ -1410,32 +1396,33 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
if(!theGUI->OpenRecovery(SandBoxes.first(), DeleteSnapshots))
|
||||
return;
|
||||
}
|
||||
else if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to delete the content of the selected sandbox?")
|
||||
else {
|
||||
if (SandBoxes.first()->HasSnapshots()) {
|
||||
if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to delete the content of the selected sandbox?")
|
||||
, tr("Also delete all Snapshots"), &DeleteSnapshots, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if(QMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to delete the content of the selected sandbox?")
|
||||
, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you really want to delete the content of all selected sandboxes?")
|
||||
, tr("Also delete all Snapshots"), &DeleteSnapshots, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes)
|
||||
return;
|
||||
|
||||
foreach(const CSandBoxPtr &pBox, SandBoxes)
|
||||
foreach(const CSandBoxPtr& pBox, SandBoxes)
|
||||
{
|
||||
if (theConf->GetBool("Options/UseAsyncBoxOps", false) || theGUI->IsSilentMode())
|
||||
{
|
||||
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
|
||||
SB_STATUS Status = pBoxEx->DeleteContentAsync(DeleteSnapshots);
|
||||
if (Status.IsError())
|
||||
Results.append(Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
SB_STATUS Status = theGUI->DeleteBoxContent(pBox, CSandMan::eDefault, DeleteSnapshots);
|
||||
SB_STATUS Status = theGUI->DeleteBoxContent(pBox, CSandMan::eCleanUp, DeleteSnapshots);
|
||||
if (Status.GetMsgCode() == SB_Canceled)
|
||||
break;
|
||||
Results.append(Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Action == m_pMenuEmptyBox)
|
||||
{
|
||||
if (theConf->GetInt("Options/WarnTerminate", -1) == -1)
|
||||
|
@ -1477,14 +1464,14 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
QString Command = Action->data().toString();
|
||||
QString WorkingDir = Action->property("WorkingDir").toString();
|
||||
if (Command.isEmpty())
|
||||
Results.append(SandBoxes.first()->RunStart("start_menu", false, WorkingDir));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), "start_menu", false, WorkingDir));
|
||||
else {
|
||||
auto pBoxEx = SandBoxes.first().objectCast<CSandBoxPlus>();
|
||||
Results.append(SandBoxes.first()->RunStart(pBoxEx->GetFullCommand(Command), false, WorkingDir));
|
||||
Results.append(theGUI->RunStart(SandBoxes.first()->GetName(), pBoxEx->GetFullCommand(Command), false, WorkingDir));
|
||||
}
|
||||
}
|
||||
|
||||
CSandMan::CheckResults(Results);
|
||||
theGUI->CheckResults(Results, this);
|
||||
}
|
||||
|
||||
bool CSbieView::CreateShortcut(const QString& LinkPath, const QString& BoxName, const QString &IconPath, int IconIndex, const QString &WorkDir)
|
||||
|
@ -1511,11 +1498,12 @@ bool CSbieView::CreateShortcut(const QString& LinkPath, const QString& BoxName,
|
|||
Path.append("\\");
|
||||
Path += "[" + BoxName + "] " + LinkName;
|
||||
|
||||
Path = QFileDialog::getSaveFileName(this, tr("Create Shortcut to sandbox %1").arg(BoxName), Path, QString("Shortcut files (*.lnk)")).replace("/", "\\");
|
||||
Path = QFileDialog::getSaveFileName(theGUI, tr("Create Shortcut to sandbox %1").arg(BoxName), Path, QString("Shortcut files (*.lnk)")).replace("/", "\\");
|
||||
if (Path.isEmpty())
|
||||
return false;
|
||||
|
||||
return CSbieUtils::CreateShortcut(theAPI, Path, LinkName, BoxName, LinkPath, IconPath, IconIndex, WorkDir);
|
||||
QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe";
|
||||
return CSbieUtils::CreateShortcut(StartExe, Path, LinkName, BoxName, LinkPath, IconPath, IconIndex, WorkDir);
|
||||
}
|
||||
|
||||
void CSbieView::OnProcessAction()
|
||||
|
@ -1567,7 +1555,8 @@ void CSbieView::OnProcessAction(QAction* Action, const QList<CBoxedProcessPtr>&
|
|||
if (Path.isEmpty())
|
||||
return;
|
||||
|
||||
CSbieUtils::CreateShortcut(theAPI, Path, LinkName, BoxName, LinkPath, LinkPath);
|
||||
QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe";
|
||||
CSbieUtils::CreateShortcut(StartExe, Path, LinkName, BoxName, LinkPath, LinkPath);
|
||||
}
|
||||
else if (Action == m_pMenuPinToRun)
|
||||
{
|
||||
|
@ -1604,7 +1593,7 @@ void CSbieView::OnProcessAction(QAction* Action, const QList<CBoxedProcessPtr>&
|
|||
Results.append(pProcess->SetSuspend(false));*/
|
||||
}
|
||||
|
||||
CSandMan::CheckResults(Results);
|
||||
theGUI->CheckResults(Results, this);
|
||||
}
|
||||
|
||||
void CSbieView::ShowOptions(const CSandBoxPtr& pBox)
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
|
||||
QMap<QString, QStringList> GetGroups() { return m_Groups; }
|
||||
|
||||
static bool CreateShortcut(const QString& LinkPath, const QString& BoxName, const QString& IconPath = QString(), int IconIndex = 0, const QString& WorkDir = QString());
|
||||
|
||||
signals:
|
||||
void BoxSelected();
|
||||
|
||||
|
@ -138,8 +140,6 @@ private:
|
|||
|
||||
QMenu* GetMenuFolder(const QString& Folder, QMenu* pParent, QMap<QString, QMenu*>& Folders);
|
||||
|
||||
bool CreateShortcut(const QString& LinkPath, const QString& BoxName, const QString& IconPath = QString(), int IconIndex = 0, const QString& WorkDir = QString());
|
||||
|
||||
QVBoxLayout* m_pMainLayout;
|
||||
|
||||
QTreeViewEx* m_pSbieTree;
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#include "stdafx.h"
|
||||
#include "TraceView.h"
|
||||
#include "..\SandMan.h"
|
||||
#include "..\AddonManager.h"
|
||||
#include "../QSbieAPI/SbieAPI.h"
|
||||
#include "..\Models\TraceModel.h"
|
||||
#include "..\..\MiscHelpers\Common\Common.h"
|
||||
#include "..\..\MiscHelpers\Common\CheckList.h"
|
||||
#include "SbieView.h"
|
||||
#include <QtConcurrent>
|
||||
|
||||
//class CTraceFilterProxyModel : public CSortFilterProxyModel
|
||||
//{
|
||||
|
@ -370,6 +372,8 @@ void CTraceView::SetEnabled(bool bSet)
|
|||
|
||||
void CTraceView::OnShowStack()
|
||||
{
|
||||
if (!theGUI->GetAddonManager()->HasAddon("DbgHelp"))
|
||||
theGUI->GetAddonManager()->TryInstallAddon("DbgHelp", this, tr("To use the stack traces feature the DbgHelp.dll and SymSrv.dll are required, do you want to download and install them?"));
|
||||
theAPI->GetGlobalSettings()->SetBool("MonitorStackTrace", m_pShowStack->isChecked());
|
||||
m_pTrace->m_pStackView->setVisible(m_pShowStack->isChecked());
|
||||
}
|
||||
|
@ -709,29 +713,64 @@ void CTraceView::SaveToFile()
|
|||
}
|
||||
else
|
||||
{
|
||||
const QVector<CTraceEntryPtr> &ResourceLog = theAPI->GetTrace();
|
||||
for (int i = 0; i < ResourceLog.count(); i++)
|
||||
{
|
||||
const CTraceEntryPtr& pEntry = ResourceLog.at(i);
|
||||
|
||||
QStringList Line;
|
||||
Line.append(QDateTime::fromMSecsSinceEpoch(pEntry->GetTimeStamp()).toString("hh:mm:ss.zzz"));
|
||||
QString Name = pEntry->GetProcessName();
|
||||
Line.append(Name.isEmpty() ? tr("Unknown") : Name);
|
||||
Line.append(QString("%1").arg(pEntry->GetProcessId()));
|
||||
Line.append(QString("%1").arg(pEntry->GetThreadId()));
|
||||
Line.append(pEntry->GetTypeStr());
|
||||
Line.append(pEntry->GetStautsStr());
|
||||
Line.append(pEntry->GetName());
|
||||
Line.append(pEntry->GetMessage());
|
||||
|
||||
File.write(Line.join("\t").toLatin1() + "\n");
|
||||
}
|
||||
SaveToFile(&File);
|
||||
}
|
||||
|
||||
File.close();
|
||||
}
|
||||
|
||||
void CTraceView::SaveToFileAsync(const CSbieProgressPtr& pProgress, QVector<CTraceEntryPtr> ResourceLog, QIODevice* pFile)
|
||||
{
|
||||
pProgress->ShowMessage(tr("Saving TraceLog..."));
|
||||
|
||||
QByteArray Unknown = "Unknown";
|
||||
|
||||
quint64 LastTimeStamp = 0;
|
||||
QByteArray LastTimeStampStr;
|
||||
for (int i = 0; i < ResourceLog.count() && !pProgress->IsCanceled(); i++)
|
||||
{
|
||||
if (i % 10000 == 0)
|
||||
pProgress->SetProgress(100 * i / ResourceLog.count());
|
||||
|
||||
const CTraceEntryPtr& pEntry = ResourceLog.at(i);
|
||||
|
||||
if (LastTimeStamp != pEntry->GetTimeStamp()) {
|
||||
LastTimeStamp = pEntry->GetTimeStamp();
|
||||
LastTimeStampStr = QDateTime::fromMSecsSinceEpoch(pEntry->GetTimeStamp()).toString("hh:mm:ss.zzz").toUtf8();
|
||||
}
|
||||
|
||||
pFile->write(LastTimeStampStr);
|
||||
pFile->write("\t");
|
||||
QString Name = pEntry->GetProcessName();
|
||||
pFile->write(Name.isEmpty() ? Unknown : Name.toUtf8());
|
||||
pFile->write("\t");
|
||||
pFile->write(QByteArray::number(pEntry->GetProcessId()));
|
||||
pFile->write("\t");
|
||||
pFile->write(QByteArray::number(pEntry->GetThreadId()));
|
||||
pFile->write("\t");
|
||||
pFile->write(pEntry->GetTypeStr().toUtf8());
|
||||
pFile->write("\t");
|
||||
pFile->write(pEntry->GetStautsStr().toUtf8());
|
||||
pFile->write("\t");
|
||||
pFile->write(pEntry->GetName().toUtf8());
|
||||
pFile->write("\t");
|
||||
pFile->write(pEntry->GetMessage().toUtf8());
|
||||
pFile->write("\n");
|
||||
}
|
||||
|
||||
pProgress->Finish(SB_OK);
|
||||
}
|
||||
|
||||
bool CTraceView::SaveToFile(QIODevice* pFile)
|
||||
{
|
||||
pFile->write("Timestamp\tProcess\tPID\tTID\tType\tStatus\tName\tMessage\n"); // don't translate log
|
||||
QVector<CTraceEntryPtr> ResourceLog = theAPI->GetTrace();
|
||||
CSbieProgressPtr pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||
QtConcurrent::run(CTraceView::SaveToFileAsync, pProgress, ResourceLog, pFile);
|
||||
theGUI->AddAsyncOp(pProgress, true);
|
||||
return !pProgress->IsCanceled();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CTraceWindow
|
||||
|
|
|
@ -71,6 +71,8 @@ public:
|
|||
|
||||
void SetEnabled(bool bSet);
|
||||
|
||||
static bool SaveToFile(QIODevice* pFile);
|
||||
|
||||
public slots:
|
||||
void Refresh();
|
||||
void Clear();
|
||||
|
@ -93,6 +95,8 @@ protected:
|
|||
void timerEvent(QTimerEvent* pEvent);
|
||||
int m_uTimerID;
|
||||
|
||||
static void SaveToFileAsync(const CSbieProgressPtr& pProgress, QVector<CTraceEntryPtr> ResourceLog, QIODevice* pFile);
|
||||
|
||||
struct SProgInfo
|
||||
{
|
||||
QString Name;
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "NewBoxWindow.h"
|
||||
#include "SandMan.h"
|
||||
#include "../MiscHelpers/Common/Settings.h"
|
||||
#include "Views/SbieView.h"
|
||||
|
||||
|
||||
CNewBoxWindow::CNewBoxWindow(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
Qt::WindowFlags flags = windowFlags();
|
||||
flags |= Qt::CustomizeWindowHint;
|
||||
//flags &= ~Qt::WindowContextHelpButtonHint;
|
||||
//flags &= ~Qt::WindowSystemMenuHint;
|
||||
//flags &= ~Qt::WindowMinMaxButtonsHint;
|
||||
//flags |= Qt::WindowMinimizeButtonHint;
|
||||
//flags &= ~Qt::WindowCloseButtonHint;
|
||||
flags &= ~Qt::WindowContextHelpButtonHint;
|
||||
//flags &= ~Qt::WindowSystemMenuHint;
|
||||
setWindowFlags(flags);
|
||||
|
||||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("Sandboxie-Plus - Create New Box"));
|
||||
|
||||
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(CreateBox()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
||||
|
||||
QMap<QString, CSandBoxPtr> Boxes = theAPI->GetAllBoxes();
|
||||
|
||||
for (int i=0;; i++) {
|
||||
QString NewName = "New Box";
|
||||
if (i > 0) NewName.append(" " + QString::number(i));
|
||||
if (Boxes.contains(NewName.toLower().replace(" ", "_")))
|
||||
continue;
|
||||
ui.txtName->setText(NewName);
|
||||
break;
|
||||
}
|
||||
|
||||
ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eHardenedPlus), tr("Hardened Sandbox with Data Protection"), (int)CSandBoxPlus::eHardenedPlus);
|
||||
ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eHardened), tr("Security Hardened Sandbox"), (int)CSandBoxPlus::eHardened);
|
||||
ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eDefaultPlus), tr("Sandbox with Data Protection"), (int)CSandBoxPlus::eDefaultPlus);
|
||||
ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eDefault), tr("Standard Isolation Sandbox (Default)"), (int)CSandBoxPlus::eDefault);
|
||||
//ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eInsecure), tr("INSECURE Configuration (please change)"), (int)CSandBoxPlus::eInsecure);
|
||||
ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eAppBoxPlus), tr("Application Compartment with Data Protection"), (int)CSandBoxPlus::eAppBoxPlus);
|
||||
ui.cmbBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eAppBox), tr("Application Compartment (NO Isolation)"), (int)CSandBoxPlus::eAppBox);
|
||||
|
||||
connect(ui.cmbBoxType, SIGNAL(currentIndexChanged(int)), this, SLOT(OnBoxTypChanged()));
|
||||
ui.cmbBoxType->setCurrentIndex(3); // default
|
||||
|
||||
ui.txtName->setFocus();
|
||||
|
||||
//restoreGeometry(theConf->GetBlob("NewBoxWindow/Window_Geometry"));
|
||||
}
|
||||
|
||||
CNewBoxWindow::~CNewBoxWindow()
|
||||
{
|
||||
//theConf->SetBlob("NewBoxWindow/Window_Geometry", saveGeometry());
|
||||
}
|
||||
|
||||
void CNewBoxWindow::OnBoxTypChanged()
|
||||
{
|
||||
int BoxType = ui.cmbBoxType->currentData().toInt();
|
||||
|
||||
ui.lblBoxInfo->setText(theGUI->GetBoxDescription(BoxType));
|
||||
|
||||
if(BoxType != CSandBoxPlus::eDefault)
|
||||
theGUI->CheckCertificate(this);
|
||||
}
|
||||
|
||||
void CNewBoxWindow::CreateBox()
|
||||
{
|
||||
m_Name = ui.txtName->text();
|
||||
int BoxType = ui.cmbBoxType->currentData().toInt();
|
||||
|
||||
if (!theGUI->GetBoxView()->TestNameAndWarn(m_Name))
|
||||
return;
|
||||
|
||||
m_Name.replace(" ", "_");
|
||||
|
||||
SB_STATUS Status = theAPI->CreateBox(m_Name, true);
|
||||
|
||||
if (!Status.IsError())
|
||||
{
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(m_Name);
|
||||
|
||||
pBox->SetBool("AutoRecover", true);
|
||||
|
||||
switch (BoxType)
|
||||
{
|
||||
case CSandBoxPlus::eHardenedPlus:
|
||||
case CSandBoxPlus::eHardened:
|
||||
//pBox->SetBool("NoSecurityIsolation", false);
|
||||
pBox->SetBool("UseSecurityMode", true);
|
||||
//pBox->SetBool("DropAdminRights", true);
|
||||
//pBox->SetBool("MsiInstallerExemptions", false);
|
||||
pBox->SetBool("UsePrivacyMode", BoxType == CSandBoxPlus::eHardenedPlus);
|
||||
break;
|
||||
case CSandBoxPlus::eDefaultPlus:
|
||||
case CSandBoxPlus::eDefault:
|
||||
//pBox->SetBool("NoSecurityIsolation", false);
|
||||
pBox->SetBool("UseSecurityMode", false);
|
||||
//pBox->SetBool("DropAdminRights", false);
|
||||
//pBox->SetBool("MsiInstallerExemptions", false);
|
||||
//pBox->SetBool("RunServicesAsSystem", false);
|
||||
pBox->SetBool("UsePrivacyMode", BoxType == CSandBoxPlus::eDefaultPlus);
|
||||
break;
|
||||
case CSandBoxPlus::eAppBoxPlus:
|
||||
case CSandBoxPlus::eAppBox:
|
||||
//pBox->SetBool("UseSecurityMode", false);
|
||||
pBox->SetBool("NoSecurityIsolation", true);
|
||||
//pBox->SetBool("RunServicesAsSystem", true);
|
||||
pBox->SetBool("UsePrivacyMode", BoxType == CSandBoxPlus::eAppBoxPlus);
|
||||
//pBox->InsertText("Template", "NoUACProxy"); // proxy is always needed for exes in the box
|
||||
pBox->InsertText("Template", "RpcPortBindingsExt");
|
||||
break;
|
||||
}
|
||||
|
||||
QRgb rgb = theGUI->GetBoxColor(BoxType);
|
||||
pBox->SetText("BorderColor", QString("#%1%2%3").arg(qBlue(rgb), 2, 16, QChar('0')).arg(qGreen(rgb), 2, 16, QChar('0')).arg(qRed(rgb), 2, 16, QChar('0')) + ",ttl");
|
||||
}
|
||||
|
||||
if(Status.IsError())
|
||||
CSandMan::CheckResults(QList<SB_STATUS>() << Status);
|
||||
else
|
||||
accept();
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include "ui_NewBoxWindow.h"
|
||||
#include "SbiePlusAPI.h"
|
||||
|
||||
class CNewBoxWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CNewBoxWindow(QWidget *parent = Q_NULLPTR);
|
||||
~CNewBoxWindow();
|
||||
|
||||
QString m_Name;
|
||||
|
||||
private slots:
|
||||
void CreateBox();
|
||||
|
||||
void OnBoxTypChanged();
|
||||
|
||||
private:
|
||||
Ui::NewBoxWindow ui;
|
||||
};
|
|
@ -919,7 +919,7 @@ void COptionsWindow::SaveConfig()
|
|||
}
|
||||
catch (SB_STATUS Status)
|
||||
{
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status);
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, this);
|
||||
}
|
||||
|
||||
m_pBox->SetRefreshOnChange(true);
|
||||
|
|
|
@ -579,7 +579,7 @@ void CRecoveryWindow::RecoverFiles(bool bBrowse, QString RecoveryFolder)
|
|||
if (Status.GetStatus() == OP_ASYNC)
|
||||
{
|
||||
connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(FindFiles()));
|
||||
theGUI->AddAsyncOp(Status.GetValue());
|
||||
theGUI->AddAsyncOp(Status.GetValue(), false, tr("Recovering File(s)..."), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,98 @@
|
|||
#include <dbt.h>
|
||||
#endif
|
||||
|
||||
QTreeWidgetItem* CSelectBoxWindow__GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QTreeWidgetItem*>& GroupItems, QTreeWidget* treeBoxes, const QString& Name, int Depth = 0)
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBoxPicker
|
||||
//
|
||||
|
||||
CBoxPicker::CBoxPicker(QString DefaultBox, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_pTreeBoxes = new QTreeWidget();
|
||||
m_pTreeBoxes->setHeaderLabels(tr("Sandbox").split("|"));
|
||||
connect(m_pTreeBoxes, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SIGNAL(BoxDblClick()));
|
||||
m_pTreeBoxes->setAlternatingRowColors(theConf->GetBool("Options/AltRowColors", false));
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(this);
|
||||
pLayout->setContentsMargins(0, 0, 0, 0);
|
||||
pLayout->addWidget(new CFinder(this, this, 0));
|
||||
pLayout->insertWidget(0, m_pTreeBoxes);
|
||||
|
||||
this->setMaximumWidth(300);
|
||||
|
||||
if(DefaultBox.isEmpty() && theAPI->IsConnected())
|
||||
DefaultBox = theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox");
|
||||
|
||||
LoadBoxed("", DefaultBox);
|
||||
}
|
||||
|
||||
void CBoxPicker::SetFilter(const QString& Exp, int iOptions, int Column)
|
||||
{
|
||||
LoadBoxed(Exp);
|
||||
}
|
||||
|
||||
void CBoxPicker::LoadBoxed(const QString& Filter, const QString& SelectBox)
|
||||
{
|
||||
m_pTreeBoxes->clear();
|
||||
|
||||
QList<CSandBoxPtr> Boxes = theAPI->GetAllBoxes().values(); // map is sorted by key (box name)
|
||||
QMap<QString, QStringList> Groups = theGUI->GetBoxView()->GetGroups();
|
||||
|
||||
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
||||
QMultiMap<double, CSandBoxPtr> Boxes2;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes) {
|
||||
Boxes2.insertMulti(GetBoxOrder(Groups, pBox->GetName()), pBox);
|
||||
}
|
||||
Boxes = Boxes2.values();
|
||||
}
|
||||
|
||||
QFileIconProvider IconProvider;
|
||||
bool ColorIcons = theConf->GetBool("Options/ColorBoxIcons", false);
|
||||
|
||||
QMap<QString, QTreeWidgetItem*> GroupItems;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes)
|
||||
{
|
||||
if (!pBox->IsEnabled() || !pBox->GetBool("ShowForRunIn", true))
|
||||
continue;
|
||||
|
||||
if (!Filter.isEmpty() && !pBox->GetName().contains(Filter, Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
||||
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(pBox.data());
|
||||
|
||||
QTreeWidgetItem* pParent = GetBoxParent(Groups, GroupItems, m_pTreeBoxes, pBox->GetName());
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
pItem->setText(0, pBox->GetName().replace("_", " "));
|
||||
pItem->setData(0, Qt::UserRole, pBox->GetName());
|
||||
QIcon Icon;
|
||||
QString Action = pBox->GetText("DblClickAction");
|
||||
if (!Action.isEmpty() && Action.left(1) != "!")
|
||||
Icon = IconProvider.icon(QFileInfo(pBoxEx->GetCommandFile(Action)));
|
||||
else if(ColorIcons)
|
||||
Icon = theGUI->GetColorIcon(pBoxEx->GetColor(), pBox->GetActiveProcessCount());
|
||||
else
|
||||
Icon = theGUI->GetBoxIcon(pBoxEx->GetType(), pBox->GetActiveProcessCount() != 0);
|
||||
pItem->setData(0, Qt::DecorationRole, Icon);
|
||||
if (pParent)
|
||||
pParent->addChild(pItem);
|
||||
else
|
||||
m_pTreeBoxes->addTopLevelItem(pItem);
|
||||
|
||||
if (pBox->GetName().compare(SelectBox, Qt::CaseInsensitive) == 0)
|
||||
m_pTreeBoxes->setCurrentItem(pItem);
|
||||
}
|
||||
|
||||
m_pTreeBoxes->expandAll();
|
||||
}
|
||||
|
||||
QString CBoxPicker::GetBoxName() const
|
||||
{
|
||||
auto pItem = m_pTreeBoxes->currentItem();
|
||||
if (!pItem) return QString();
|
||||
return pItem->data(0, Qt::UserRole).toString();
|
||||
}
|
||||
|
||||
QTreeWidgetItem* CBoxPicker::GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QTreeWidgetItem*>& GroupItems, QTreeWidget* treeBoxes, const QString& Name, int Depth)
|
||||
{
|
||||
if (Depth > 100)
|
||||
return NULL;
|
||||
|
@ -27,7 +118,7 @@ QTreeWidgetItem* CSelectBoxWindow__GetBoxParent(const QMap<QString, QStringList>
|
|||
QFont fnt = pParent->font(0);
|
||||
fnt.setBold(true);
|
||||
pParent->setFont(0, fnt);
|
||||
if (QTreeWidgetItem* pParent2 = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, treeBoxes, I.key(), ++Depth))
|
||||
if (QTreeWidgetItem* pParent2 = GetBoxParent(Groups, GroupItems, treeBoxes, I.key(), ++Depth))
|
||||
pParent2->addChild(pParent);
|
||||
else
|
||||
treeBoxes->addTopLevelItem(pParent);
|
||||
|
@ -38,7 +129,7 @@ QTreeWidgetItem* CSelectBoxWindow__GetBoxParent(const QMap<QString, QStringList>
|
|||
return NULL;
|
||||
}
|
||||
|
||||
double CSelectBoxWindow__GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value = 0.0, int Depth = 0)
|
||||
double CBoxPicker::GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value, int Depth)
|
||||
{
|
||||
if (Depth > 100)
|
||||
return 1000000000;
|
||||
|
@ -48,12 +139,16 @@ double CSelectBoxWindow__GetBoxOrder(const QMap<QString, QStringList>& Groups, c
|
|||
value = double(Pos) + value / 10.0;
|
||||
if (I.key().isEmpty())
|
||||
return value;
|
||||
return CSelectBoxWindow__GetBoxOrder(Groups, I.key(), value, ++Depth);
|
||||
return GetBoxOrder(Groups, I.key(), value, ++Depth);
|
||||
}
|
||||
}
|
||||
return 1000000000;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSelectBoxWindow
|
||||
//
|
||||
|
||||
CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& BoxName, const QString& WrkDir, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
|
@ -88,8 +183,6 @@ CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& B
|
|||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("Sandboxie-Plus - Run Sandboxed"));
|
||||
|
||||
ui.treeBoxes->setAlternatingRowColors(theConf->GetBool("Options/AltRowColors", false));
|
||||
|
||||
connect(ui.radBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
connect(ui.radBoxedNew, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
connect(ui.radUnBoxed, SIGNAL(clicked(bool)), this, SLOT(OnBoxType()));
|
||||
|
@ -97,20 +190,12 @@ CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& B
|
|||
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(OnRun()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), SLOT(reject()));
|
||||
|
||||
connect(ui.treeBoxes, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnBoxDblClick(QTreeWidgetItem*)));
|
||||
m_pBoxPicker = new CBoxPicker(BoxName);
|
||||
connect(m_pBoxPicker, SIGNAL(BoxDblClick()), this, SLOT(OnRun()));
|
||||
ui.treeBoxes->parentWidget()->layout()->replaceWidget(ui.treeBoxes, m_pBoxPicker);
|
||||
delete ui.treeBoxes;
|
||||
|
||||
QWidget* pWidget = new QWidget();
|
||||
QVBoxLayout* pLayout = new QVBoxLayout(pWidget);
|
||||
pLayout->setContentsMargins(0, 0, 0, 0);
|
||||
pLayout->addWidget(new CFinder(this, pWidget, 0));
|
||||
ui.treeBoxes->parentWidget()->layout()->replaceWidget(ui.treeBoxes, pWidget);
|
||||
pLayout->insertWidget(0, ui.treeBoxes);
|
||||
|
||||
LoadBoxed("", BoxName);
|
||||
|
||||
ui.treeBoxes->setFocus();
|
||||
|
||||
//ui.treeBoxes->sortByColumn(0, Qt::AscendingOrder);
|
||||
m_pBoxPicker->setFocus();
|
||||
|
||||
//restoreGeometry(theConf->GetBlob("SelectBoxWindow/Window_Geometry"));
|
||||
}
|
||||
|
@ -126,86 +211,19 @@ void CSelectBoxWindow::closeEvent(QCloseEvent *e)
|
|||
this->deleteLater();
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::SetFilter(const QString& Exp, int iOptions, int Column)
|
||||
{
|
||||
LoadBoxed(Exp);
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::LoadBoxed(const QString& Filter, const QString& SelectBox)
|
||||
{
|
||||
ui.treeBoxes->clear();
|
||||
|
||||
QList<CSandBoxPtr> Boxes = theAPI->GetAllBoxes().values(); // map is sorted by key (box name)
|
||||
QMap<QString, QStringList> Groups = theGUI->GetBoxView()->GetGroups();
|
||||
|
||||
if (theConf->GetBool("MainWindow/BoxTree_UseOrder", false)) {
|
||||
QMultiMap<double, CSandBoxPtr> Boxes2;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes) {
|
||||
Boxes2.insertMulti(CSelectBoxWindow__GetBoxOrder(Groups, pBox->GetName()), pBox);
|
||||
}
|
||||
Boxes = Boxes2.values();
|
||||
}
|
||||
|
||||
QFileIconProvider IconProvider;
|
||||
bool ColorIcons = theConf->GetBool("Options/ColorBoxIcons", false);
|
||||
|
||||
QMap<QString, QTreeWidgetItem*> GroupItems;
|
||||
foreach(const CSandBoxPtr &pBox, Boxes)
|
||||
{
|
||||
if (!pBox->IsEnabled() || !pBox->GetBool("ShowForRunIn", true))
|
||||
continue;
|
||||
|
||||
if (!Filter.isEmpty() && !pBox->GetName().contains(Filter, Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
||||
CSandBoxPlus* pBoxEx = qobject_cast<CSandBoxPlus*>(pBox.data());
|
||||
|
||||
QTreeWidgetItem* pParent = CSelectBoxWindow__GetBoxParent(Groups, GroupItems, ui.treeBoxes, pBox->GetName());
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem();
|
||||
pItem->setText(0, pBox->GetName().replace("_", " "));
|
||||
pItem->setData(0, Qt::UserRole, pBox->GetName());
|
||||
QIcon Icon;
|
||||
QString Action = pBox->GetText("DblClickAction");
|
||||
if (!Action.isEmpty() && Action.left(1) != "!")
|
||||
Icon = IconProvider.icon(QFileInfo(pBoxEx->GetCommandFile(Action)));
|
||||
else if(ColorIcons)
|
||||
Icon = theGUI->GetColorIcon(pBoxEx->GetColor(), pBox->GetActiveProcessCount());
|
||||
else
|
||||
Icon = theGUI->GetBoxIcon(pBoxEx->GetType(), pBox->GetActiveProcessCount() != 0);
|
||||
pItem->setData(0, Qt::DecorationRole, Icon);
|
||||
if (pParent)
|
||||
pParent->addChild(pItem);
|
||||
else
|
||||
ui.treeBoxes->addTopLevelItem(pItem);
|
||||
|
||||
if (pBox->GetName().compare(SelectBox, Qt::CaseInsensitive) == 0)
|
||||
ui.treeBoxes->setCurrentItem(pItem);
|
||||
}
|
||||
|
||||
ui.treeBoxes->expandAll();
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxType()
|
||||
{
|
||||
ui.treeBoxes->setEnabled(ui.radBoxed->isChecked());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxDblClick(QTreeWidgetItem*)
|
||||
{
|
||||
OnRun();
|
||||
m_pBoxPicker->setEnabled(ui.radBoxed->isChecked());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnRun()
|
||||
{
|
||||
QTreeWidgetItem* pItem = ui.treeBoxes->currentItem();
|
||||
|
||||
QString BoxName;
|
||||
|
||||
if (ui.radUnBoxed->isChecked())
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Are you sure you want to run the program outside the sandbox?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
pItem = NULL;
|
||||
}
|
||||
else if (ui.radBoxedNew->isChecked())
|
||||
{
|
||||
|
@ -215,20 +233,17 @@ void CSelectBoxWindow::OnRun()
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (pItem == NULL) {
|
||||
else
|
||||
{
|
||||
BoxName = m_pBoxPicker->GetBoxName();
|
||||
if (BoxName.isEmpty()) {
|
||||
QMessageBox("Sandboxie-Plus", tr("Please select a sandbox."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
BoxName = pItem->data(0, Qt::UserRole).toString();
|
||||
}
|
||||
|
||||
|
||||
//QList<SB_STATUS> Results;
|
||||
foreach(const QString & Command, m_Commands) {
|
||||
theAPI->RunStart(BoxName, Command, ui.chkAdmin->isChecked(), m_WrkDir);
|
||||
}
|
||||
//CSandMan::CheckResults(Results);
|
||||
foreach(const QString & Command, m_Commands)
|
||||
theGUI->RunStart(BoxName, Command, ui.chkAdmin->isChecked(), m_WrkDir);
|
||||
|
||||
setResult(1);
|
||||
close();
|
||||
|
|
|
@ -4,6 +4,38 @@
|
|||
#include "ui_SelectBoxWindow.h"
|
||||
#include "SbiePlusAPI.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBoxPicker
|
||||
//
|
||||
|
||||
class CBoxPicker : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CBoxPicker(QString DefaultBox = "", QWidget *parent = Q_NULLPTR);
|
||||
|
||||
void LoadBoxed(const QString& Filter = QString(), const QString& SelectBox = QString());
|
||||
|
||||
QString GetBoxName() const;
|
||||
|
||||
static QTreeWidgetItem* GetBoxParent(const QMap<QString, QStringList>& Groups, QMap<QString, QTreeWidgetItem*>& GroupItems, QTreeWidget* treeBoxes, const QString& Name, int Depth = 0);
|
||||
static double GetBoxOrder(const QMap<QString, QStringList>& Groups, const QString& Name, double value = 0.0, int Depth = 0);
|
||||
|
||||
signals:
|
||||
void BoxDblClick();
|
||||
|
||||
private slots:
|
||||
void SetFilter(const QString& Exp, int iOptions, int Column);
|
||||
|
||||
private:
|
||||
QTreeWidget *m_pTreeBoxes;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSelectBoxWindow
|
||||
//
|
||||
|
||||
class CSelectBoxWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -13,20 +45,16 @@ public:
|
|||
~CSelectBoxWindow();
|
||||
|
||||
private slots:
|
||||
void SetFilter(const QString& Exp, int iOptions, int Column);
|
||||
|
||||
void OnBoxDblClick(QTreeWidgetItem*);
|
||||
void OnBoxType();
|
||||
void OnRun();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* e);
|
||||
|
||||
void LoadBoxed(const QString& Filter = QString(), const QString& SelectBox = QString());
|
||||
|
||||
QStringList m_Commands;
|
||||
QString m_WrkDir;
|
||||
|
||||
private:
|
||||
Ui::SelectBoxWindow ui;
|
||||
CBoxPicker* m_pBoxPicker;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../MiscHelpers/Archive/ArchiveFS.h"
|
||||
#include <QJsonDocument>
|
||||
#include "../Wizards/TemplateWizard.h"
|
||||
#include "../AddonManager.h"
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -111,6 +112,8 @@ quint32 g_FeatureFlags = 0;
|
|||
QByteArray g_Certificate;
|
||||
SCertInfo g_CertInfo = { 0 };
|
||||
|
||||
void COptionsWindow__AddCertIcon(QWidget* pOriginalWidget);
|
||||
|
||||
CSettingsWindow::CSettingsWindow(QWidget* parent)
|
||||
: CConfigDialog(parent)
|
||||
{
|
||||
|
@ -144,11 +147,12 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
ui.tabs->setTabIcon(0, CSandMan::GetIcon("Config"));
|
||||
ui.tabs->setTabIcon(1, CSandMan::GetIcon("Shell"));
|
||||
ui.tabs->setTabIcon(2, CSandMan::GetIcon("Design"));
|
||||
ui.tabs->setTabIcon(3, CSandMan::GetIcon("Support"));
|
||||
ui.tabs->setTabIcon(4, CSandMan::GetIcon("Advanced"));
|
||||
ui.tabs->setTabIcon(5, CSandMan::GetIcon("Control"));
|
||||
ui.tabs->setTabIcon(6, CSandMan::GetIcon("Compatibility"));
|
||||
ui.tabs->setTabIcon(7, CSandMan::GetIcon("Editor"));
|
||||
ui.tabs->setTabIcon(3, CSandMan::GetIcon("Plugins"));
|
||||
ui.tabs->setTabIcon(4, CSandMan::GetIcon("Support"));
|
||||
ui.tabs->setTabIcon(5, CSandMan::GetIcon("Advanced"));
|
||||
ui.tabs->setTabIcon(6, CSandMan::GetIcon("Control"));
|
||||
ui.tabs->setTabIcon(7, CSandMan::GetIcon("Compatibility"));
|
||||
ui.tabs->setTabIcon(8, CSandMan::GetIcon("Editor"));
|
||||
|
||||
ui.tabsGeneral->setCurrentIndex(0);
|
||||
ui.tabsGeneral->setTabIcon(0, CSandMan::GetIcon("Presets"));
|
||||
|
@ -162,6 +166,14 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
ui.tabsGUI->setTabIcon(0, CSandMan::GetIcon("Interface"));
|
||||
ui.tabsGUI->setTabIcon(1, CSandMan::GetIcon("Monitor"));
|
||||
|
||||
ui.tabsAddons->setCurrentIndex(0);
|
||||
ui.tabsAddons->setTabIcon(0, CSandMan::GetIcon("Plugin"));
|
||||
//ui.tabsAddons->setTabIcon(1, CSandMan::GetIcon("Qube"));
|
||||
|
||||
ui.tabsSupport->setCurrentIndex(0);
|
||||
ui.tabsSupport->setTabIcon(0, CSandMan::GetIcon("Cert"));
|
||||
ui.tabsSupport->setTabIcon(1, CSandMan::GetIcon("ReloadIni"));
|
||||
|
||||
ui.tabsAdvanced->setCurrentIndex(0);
|
||||
ui.tabsAdvanced->setTabIcon(0, CSandMan::GetIcon("Options"));
|
||||
ui.tabsAdvanced->setTabIcon(1, CSandMan::GetIcon("EditIni"));
|
||||
|
@ -216,10 +228,9 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
ui.uiLang->addItem(tr("Auto Detection"), "");
|
||||
ui.uiLang->addItem(tr("No Translation"), "native");
|
||||
|
||||
C7zFileEngineHandler LangFS(QApplication::applicationDirPath() + "/translations.7z", "lang", this);
|
||||
|
||||
QString langDir;
|
||||
if (LangFS.IsOpen())
|
||||
C7zFileEngineHandler LangFS("lang", this);
|
||||
if (LangFS.Open(QApplication::applicationDirPath() + "/translations.7z"))
|
||||
langDir = LangFS.Prefix() + "/";
|
||||
else
|
||||
langDir = QApplication::applicationDirPath() + "/translations/";
|
||||
|
@ -352,6 +363,26 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
m_RunChanged = false;
|
||||
//
|
||||
|
||||
// Addons
|
||||
QObject::connect(theGUI->GetAddonManager(), &CAddonManager::DataUpdated, this, [=]() {
|
||||
ui.lblUpdateAddons->setVisible(false);
|
||||
OnLoadAddon();
|
||||
});
|
||||
|
||||
connect(ui.btnInstallAddon, SIGNAL(clicked(bool)), this, SLOT(OnInstallAddon()));
|
||||
connect(ui.btnRemoveAddon, SIGNAL(clicked(bool)), this, SLOT(OnRemoveAddon()));
|
||||
|
||||
if (theConf->GetInt("Options/CheckForAddons", 2) == 1) {
|
||||
ui.lblUpdateAddons->setVisible(false);
|
||||
theGUI->GetAddonManager()->UpdateAddons();
|
||||
} else {
|
||||
connect(ui.lblUpdateAddons, &QLabel::linkActivated, this, [=]() {
|
||||
theGUI->GetAddonManager()->UpdateAddons();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
// Advanced Config
|
||||
connect(ui.cmbDefault, SIGNAL(currentIndexChanged(int)), this, SLOT(OnGeneralChanged()));
|
||||
connect(ui.chkAutoRoot, SIGNAL(stateChanged(int)), this, SLOT(OnRootChanged())); // not sbie ini
|
||||
|
@ -419,7 +450,7 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
connect(ui.lblSupport, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
connect(ui.lblSupportCert, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
connect(ui.lblCertExp, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
//connect(ui.lblInsiderInfo, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
connect(ui.lblInsiderInfo, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
|
||||
m_CertChanged = false;
|
||||
connect(ui.txtCertificate, SIGNAL(textChanged()), this, SLOT(CertChanged()));
|
||||
|
@ -433,22 +464,28 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
"SIGNATURE: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
|
||||
);
|
||||
|
||||
connect(ui.chkNoCheck, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged()));
|
||||
|
||||
//
|
||||
|
||||
connect(ui.lblCurrent, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&)));
|
||||
connect(ui.lblStable, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&)));
|
||||
connect(ui.lblPreview, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&)));
|
||||
//connect(ui.lblInsider, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&)));
|
||||
connect(ui.lblInsider, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&)));
|
||||
//connect(ui.lblInsiderInfo, SIGNAL(linkActivated(const QString&)), this, SLOT(OnUpdate(const QString&)));
|
||||
|
||||
connect(ui.chkAutoUpdate, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater()));
|
||||
|
||||
connect(ui.radStable, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater()));
|
||||
connect(ui.radPreview, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater()));
|
||||
//connect(ui.radInsider, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater()));
|
||||
connect(ui.radInsider, SIGNAL(toggled(bool)), this, SLOT(UpdateUpdater()));
|
||||
|
||||
connect(ui.cmbUpdate, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged()));
|
||||
connect(ui.cmbRelease, SIGNAL(currentIndexChanged(int)), this, SLOT(OnOptChanged()));
|
||||
|
||||
connect(ui.chkNoCheck, SIGNAL(stateChanged(int)), this, SLOT(OnOptChanged()));
|
||||
connect(ui.chkUpdateIssues, SIGNAL(toggled(bool)), this, SLOT(OnOptChanged()));
|
||||
connect(ui.chkUpdateAddons, SIGNAL(toggled(bool)), this, SLOT(OnOptChanged()));
|
||||
|
||||
//
|
||||
|
||||
connect(ui.tabs, SIGNAL(currentChanged(int)), this, SLOT(OnTab()));
|
||||
|
@ -464,6 +501,9 @@ CSettingsWindow::CSettingsWindow(QWidget* parent)
|
|||
connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked(bool)), this, SLOT(apply()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
//COptionsWindow__AddCertIcon(ui.chkUpdateTemplates);
|
||||
COptionsWindow__AddCertIcon(ui.chkUpdateIssues);
|
||||
|
||||
this->installEventFilter(this); // prevent enter from closing the dialog
|
||||
|
||||
restoreGeometry(theConf->GetBlob("SettingsWindow/Window_Geometry"));
|
||||
|
@ -693,7 +733,7 @@ void CSettingsWindow::OnDelCommand()
|
|||
OnRunChanged();
|
||||
}
|
||||
|
||||
Qt::CheckState CSettingsWindow__IsContextMenu()
|
||||
Qt::CheckState CSettingsWindow::IsContextMenu()
|
||||
{
|
||||
//QSettings Package("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\PackagedCom\\Package", QSettings::NativeFormat);
|
||||
QSettings Package("HKEY_CURRENT_USER\\Software\\Classes\\PackagedCom\\Package", QSettings::NativeFormat);
|
||||
|
@ -710,7 +750,7 @@ Qt::CheckState CSettingsWindow__IsContextMenu()
|
|||
return Qt::Unchecked; // not set up
|
||||
}
|
||||
|
||||
void CSettingsWindow__AddContextMenu(bool bAlwaysClassic)
|
||||
void CSettingsWindow::AddContextMenu(bool bAlwaysClassic)
|
||||
{
|
||||
QSettings CurrentVersion("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat);
|
||||
if (CurrentVersion.value("CurrentBuild").toInt() >= 22000 && !bAlwaysClassic) // Windows 11
|
||||
|
@ -731,7 +771,7 @@ void CSettingsWindow__AddContextMenu(bool bAlwaysClassic)
|
|||
QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe");
|
||||
}
|
||||
|
||||
void CSettingsWindow__RemoveContextMenu()
|
||||
void CSettingsWindow::RemoveContextMenu()
|
||||
{
|
||||
QSettings CurrentVersion("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", QSettings::NativeFormat);
|
||||
if (CurrentVersion.value("CurrentBuild").toInt() >= 22000) // Windows 11
|
||||
|
@ -745,11 +785,13 @@ void CSettingsWindow__RemoveContextMenu()
|
|||
CSbieUtils::RemoveContextMenu();
|
||||
}
|
||||
|
||||
void CSettingsWindow__AddBrowserIcon()
|
||||
bool CSettingsWindow::AddBrowserIcon()
|
||||
{
|
||||
QString Path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).replace("/", "\\");
|
||||
Path += "\\" + CSettingsWindow::tr("Sandboxed Web Browser") + ".lnk";
|
||||
CSbieUtils::CreateShortcut(theAPI, Path, "", "", "default_browser");
|
||||
QString StartExe = theAPI->GetSbiePath() + "\\SandMan.exe";
|
||||
QString BoxName = theAPI->GetGlobalSettings()->GetText("DefaultBox", "DefaultBox");
|
||||
return CSbieUtils::CreateShortcut(StartExe, Path, "", BoxName, "default_browser");
|
||||
}
|
||||
|
||||
void CSettingsWindow::LoadSettings()
|
||||
|
@ -771,7 +813,7 @@ void CSettingsWindow::LoadSettings()
|
|||
ui.chkSvcStart->setEnabled(false);
|
||||
}
|
||||
|
||||
ui.chkShellMenu->setCheckState(CSettingsWindow__IsContextMenu());
|
||||
ui.chkShellMenu->setCheckState(IsContextMenu());
|
||||
ui.chkShellMenu2->setChecked(CSbieUtils::HasContextMenu2());
|
||||
ui.chkAlwaysDefault->setChecked(theConf->GetBool("Options/RunInDefaultBox", false));
|
||||
|
||||
|
@ -817,6 +859,7 @@ void CSettingsWindow::LoadSettings()
|
|||
ui.chkCompactTray->setChecked(theConf->GetBool("Options/CompactTray", false));
|
||||
ui.chkBoxOpsNotify->setChecked(theConf->GetBool("Options/AutoBoxOpsNotify", false));
|
||||
|
||||
OnLoadAddon();
|
||||
|
||||
if (theAPI->IsConnected())
|
||||
{
|
||||
|
@ -926,14 +969,17 @@ void CSettingsWindow::LoadSettings()
|
|||
|
||||
UpdateCert();
|
||||
|
||||
|
||||
ui.chkNoCheck->setChecked(theConf->GetBool("Options/NoSupportCheck", false));
|
||||
if(ui.chkNoCheck->isCheckable() && !g_CertInfo.expired)
|
||||
ui.chkNoCheck->setVisible(false); // hide if not relevant
|
||||
|
||||
ui.chkAutoUpdate->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForUpdates", 2)));
|
||||
//ui.chkAutoDownload->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/DownloadUpdates", 0)));
|
||||
//ui.chkAutoInstall->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/InstallUpdates", 0)));
|
||||
|
||||
QString ReleaseChannel = theConf->GetString("Options/ReleaseChannel", "stable");
|
||||
ui.radStable->setChecked(ReleaseChannel == "stable");
|
||||
ui.radPreview->setChecked(ReleaseChannel == "preview");
|
||||
//ui.radInsider->setChecked(ReleaseChannel == "insider");
|
||||
ui.radInsider->setChecked(ReleaseChannel == "insider");
|
||||
|
||||
m_HoldChange = true;
|
||||
UpdateUpdater();
|
||||
|
@ -942,10 +988,12 @@ void CSettingsWindow::LoadSettings()
|
|||
ui.cmbUpdate->setCurrentIndex(ui.cmbUpdate->findData(theConf->GetString("Options/OnNewUpdate", "ignore")));
|
||||
ui.cmbRelease->setCurrentIndex(ui.cmbRelease->findData(theConf->GetString("Options/OnNewRelease", "download")));
|
||||
|
||||
//ui.chkUpdateTemplates->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForTemplates", 2)));
|
||||
ui.chkUpdateAddons->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForAddons", 2)));
|
||||
ui.chkUpdateIssues->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/CheckForIssues", 2)));
|
||||
|
||||
ui.chkNoCheck->setChecked(theConf->GetBool("Options/NoSupportCheck", false));
|
||||
if(ui.chkNoCheck->isCheckable() && !g_CertInfo.expired)
|
||||
ui.chkNoCheck->setVisible(false); // hide if not relevant
|
||||
//ui.chkUpdateTemplates->setEnabled(g_CertInfo.valid && !g_CertInfo.expired);
|
||||
ui.chkUpdateIssues->setEnabled(g_CertInfo.valid && !g_CertInfo.expired);
|
||||
}
|
||||
|
||||
void CSettingsWindow::UpdateCert()
|
||||
|
@ -988,7 +1036,7 @@ void CSettingsWindow::UpdateCert()
|
|||
ui.txtCertificate->setPalette(palette);
|
||||
}
|
||||
|
||||
//ui.radInsider->setEnabled(g_CertInfo.insider);
|
||||
ui.radInsider->setEnabled(g_CertInfo.insider);
|
||||
}
|
||||
|
||||
void CSettingsWindow::UpdateUpdater()
|
||||
|
@ -1000,7 +1048,7 @@ void CSettingsWindow::UpdateUpdater()
|
|||
ui.lblRevision->setText(QString());
|
||||
}
|
||||
else {
|
||||
if (ui.radStable->isChecked() && (!g_CertInfo.valid)) {
|
||||
if (ui.radStable->isChecked() && (!g_CertInfo.valid || g_CertInfo.expired)) {
|
||||
ui.cmbUpdate->setEnabled(false);
|
||||
ui.cmbUpdate->setCurrentIndex(ui.cmbUpdate->findData("ignore"));
|
||||
ui.lblRevision->setText(tr("Supporter certificate required"));
|
||||
|
@ -1096,14 +1144,14 @@ void CSettingsWindow::SaveSettings()
|
|||
theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", false);
|
||||
}
|
||||
|
||||
if (ui.chkShellMenu->checkState() != CSettingsWindow__IsContextMenu())
|
||||
if (ui.chkShellMenu->checkState() != IsContextMenu())
|
||||
{
|
||||
if (ui.chkShellMenu->isChecked()) {
|
||||
CSecretCheckBox* SecretCheckBox = qobject_cast<CSecretCheckBox*>(ui.chkShellMenu);
|
||||
CSettingsWindow__AddContextMenu(SecretCheckBox && SecretCheckBox->IsSecretSet());
|
||||
AddContextMenu(SecretCheckBox && SecretCheckBox->IsSecretSet());
|
||||
}
|
||||
else
|
||||
CSettingsWindow__RemoveContextMenu();
|
||||
RemoveContextMenu();
|
||||
}
|
||||
|
||||
if (ui.chkShellMenu2->isChecked() != CSbieUtils::HasContextMenu2()) {
|
||||
|
@ -1285,7 +1333,7 @@ void CSettingsWindow::SaveSettings()
|
|||
}
|
||||
catch (SB_STATUS Status)
|
||||
{
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status);
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, theGUI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1321,23 +1369,25 @@ void CSettingsWindow::SaveSettings()
|
|||
m_CertChanged = false;
|
||||
}
|
||||
|
||||
theConf->SetValue("Options/NoSupportCheck", ui.chkNoCheck->isChecked());
|
||||
|
||||
theConf->SetValue("Options/CheckForUpdates", CSettingsWindow__Chk2Int(ui.chkAutoUpdate->checkState()));
|
||||
//theConf->SetValue("Options/DownloadUpdates", CSettingsWindow__Chk2Int(ui.chkAutoDownload->checkState()));
|
||||
//theConf->SetValue("Options/InstallUpdates", CSettingsWindow__Chk2Int(ui.chkAutoInstall->checkState()));
|
||||
|
||||
QString ReleaseChannel;
|
||||
if (ui.radStable->isChecked())
|
||||
ReleaseChannel = "stable";
|
||||
else if (ui.radPreview->isChecked())
|
||||
ReleaseChannel = "preview";
|
||||
//else if (ui.radInsider->isChecked())
|
||||
// ReleaseChannel = "insider";
|
||||
else if (ui.radInsider->isChecked())
|
||||
ReleaseChannel = "insider";
|
||||
if(!ReleaseChannel.isEmpty()) theConf->SetValue("Options/ReleaseChannel", ReleaseChannel);
|
||||
|
||||
theConf->SetValue("Options/OnNewUpdate", ui.cmbUpdate->currentData());
|
||||
theConf->SetValue("Options/OnNewRelease", ui.cmbRelease->currentData());
|
||||
|
||||
theConf->SetValue("Options/NoSupportCheck", ui.chkNoCheck->isChecked());
|
||||
//theConf->SetValue("Options/CheckForTemplates", CSettingsWindow__Chk2Int(ui.chkUpdateTemplates->checkState()));
|
||||
theConf->SetValue("Options/CheckForAddons", CSettingsWindow__Chk2Int(ui.chkUpdateAddons->checkState()));
|
||||
theConf->SetValue("Options/CheckForIssues", CSettingsWindow__Chk2Int(ui.chkUpdateIssues->checkState()));
|
||||
|
||||
emit OptionsChanged(m_bRebuildUI);
|
||||
}
|
||||
|
@ -1435,6 +1485,49 @@ void CSettingsWindow::OnOptChanged()
|
|||
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnLoadAddon()
|
||||
{
|
||||
ui.treeAddons->clear();
|
||||
foreach(const CAddonPtr pAddon, theGUI->GetAddonManager()->GetAddons()) {
|
||||
|
||||
QTreeWidgetItem* pItem = new QTreeWidgetItem;
|
||||
pItem->setText(0, pAddon->GetLocalizedEntry("name"));
|
||||
if(!pAddon->Data["mandatory"].toBool())
|
||||
pItem->setData(0, Qt::UserRole, pAddon->Id);
|
||||
pItem->setIcon(0, pAddon->Data.contains("icon") ? CSandMan::GetIcon(pAddon->Data["icon"].toString()) : CSandMan::GetIcon("Addon"));
|
||||
pItem->setText(1, pAddon->Installed ? tr("Installed") : "");
|
||||
pItem->setText(2, pAddon->GetLocalizedEntry("description"));
|
||||
|
||||
ui.treeAddons->addTopLevelItem(pItem);
|
||||
}
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnInstallAddon()
|
||||
{
|
||||
QTreeWidgetItem* pItem = ui.treeAddons->currentItem();
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
QString Id = pItem->data(0, Qt::UserRole).toString();
|
||||
SB_PROGRESS Status = theGUI->GetAddonManager()->TryInstallAddon(Id, this);
|
||||
if (Status.GetStatus() == OP_ASYNC) connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(OnLoadAddon()));
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnRemoveAddon()
|
||||
{
|
||||
QTreeWidgetItem* pItem = ui.treeAddons->currentItem();
|
||||
if (!pItem)
|
||||
return;
|
||||
|
||||
QString Id = pItem->data(0, Qt::UserRole).toString();
|
||||
if (Id.isEmpty()) {
|
||||
QMessageBox::warning(this, "Sandboxie-Plus", tr("This Addon is mandatory and can not be removed."));
|
||||
return;
|
||||
}
|
||||
SB_PROGRESS Status = theGUI->GetAddonManager()->TryRemoveAddon(Id, this);
|
||||
if (Status.GetStatus() == OP_ASYNC) connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(OnLoadAddon()));
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnBrowse()
|
||||
{
|
||||
QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
|
||||
|
@ -1477,8 +1570,12 @@ void CSettingsWindow::OnTab(QWidget* pTab)
|
|||
else if (pTab == ui.tabCompat && m_CompatLoaded != 1 && theAPI->IsConnected())
|
||||
{
|
||||
if(m_CompatLoaded == 0)
|
||||
theGUI->GetCompat()->RunCheck();
|
||||
theGUI->CheckCompat(this, "OnCompat");
|
||||
}
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnCompat()
|
||||
{
|
||||
ui.treeCompat->clear();
|
||||
|
||||
bool bNew = false;
|
||||
|
@ -1520,7 +1617,6 @@ void CSettingsWindow::OnTab(QWidget* pTab)
|
|||
OnCompatChanged();
|
||||
|
||||
LoadTemplates();
|
||||
}
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnProtectionChange()
|
||||
|
@ -1824,8 +1920,8 @@ void CSettingsWindow::OnUpdateData(const QVariantMap& Data, const QVariantMap& P
|
|||
ui.lblCurrent->setText(tr("%1 (Current)").arg(Version));
|
||||
ui.lblStable->setText(CSettingsWindow__MkVersion("stable", Releases));
|
||||
ui.lblPreview->setText(CSettingsWindow__MkVersion("preview", Releases));
|
||||
//if(ui.radInsider->isEnabled())
|
||||
// ui.lblInsider->setText(CSettingsWindow__MkVersion("insider", Releases));
|
||||
if(ui.radInsider->isEnabled())
|
||||
ui.lblInsider->setText(CSettingsWindow__MkVersion("insider", Releases));
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnUpdate(const QString& Channel)
|
||||
|
|
|
@ -55,6 +55,11 @@ public:
|
|||
virtual void accept() {}
|
||||
virtual void reject();
|
||||
|
||||
static Qt::CheckState IsContextMenu();
|
||||
static void AddContextMenu(bool bAlwaysClassic = false);
|
||||
static void RemoveContextMenu();
|
||||
static bool AddBrowserIcon();
|
||||
|
||||
static bool ApplyCertificate(const QByteArray &Certificate, QWidget* widget);
|
||||
|
||||
static void LoadCertificate(QString CertPath = QString());
|
||||
|
@ -83,6 +88,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void OnTab();
|
||||
void OnCompat();
|
||||
|
||||
void OnAddMessage();
|
||||
void OnDelMessage();
|
||||
|
@ -103,6 +109,10 @@ private slots:
|
|||
void OnFeaturesChanged() { m_FeaturesChanged = true; OnGeneralChanged(); }
|
||||
void OnGeneralChanged() { m_GeneralChanged = true; OnOptChanged(); }
|
||||
|
||||
void OnLoadAddon();
|
||||
void OnInstallAddon();
|
||||
void OnRemoveAddon();
|
||||
|
||||
void OnBrowse();
|
||||
|
||||
void OnProtectionChange();
|
||||
|
@ -185,10 +195,6 @@ private:
|
|||
Ui::SettingsWindow ui;
|
||||
};
|
||||
|
||||
void CSettingsWindow__AddContextMenu(bool bAlwaysClassic = false);
|
||||
void CSettingsWindow__RemoveContextMenu();
|
||||
void CSettingsWindow__AddBrowserIcon();
|
||||
|
||||
void WindowsMoveFile(const QString& from, const QString& to);
|
||||
|
||||
extern quint32 g_FeatureFlags;
|
||||
|
|
|
@ -242,9 +242,9 @@ void CSnapshotsWindow::HandleResult(SB_PROGRESS Status)
|
|||
if (Status.GetStatus() == OP_ASYNC)
|
||||
{
|
||||
connect(Status.GetValue().data(), SIGNAL(Finished()), this, SLOT(UpdateSnapshots()));
|
||||
theGUI->AddAsyncOp(Status.GetValue());
|
||||
theGUI->AddAsyncOp(Status.GetValue(), false, tr("Performing Snapshot operation..."), this);
|
||||
}
|
||||
else if (Status.IsError())
|
||||
CSandMan::CheckResults(QList<SB_STATUS>() << Status);
|
||||
theGUI->CheckResults(QList<SB_STATUS>() << Status, this);
|
||||
UpdateSnapshots();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../MiscHelpers/Common/Common.h"
|
||||
#include "SettingsWindow.h"
|
||||
#include <Windows.h>
|
||||
#include "OnlineUpdater.h"
|
||||
|
||||
bool CSupportDialog::m_ReminderShown = false;
|
||||
|
||||
|
@ -32,14 +33,35 @@ bool CSupportDialog::IsBusinessUse()
|
|||
|
||||
bool CSupportDialog::CheckSupport(bool bOnRun)
|
||||
{
|
||||
bool NoGo = false;
|
||||
|
||||
#ifdef INSIDER_BUILD
|
||||
if (g_CertInfo.valid) {
|
||||
if (!g_CertInfo.insider) {
|
||||
TArguments args = GetArguments(g_Certificate, L'\n', L':');
|
||||
if (args.value("TYPE").contains("PATREON")) {
|
||||
if (QMessageBox::question(NULL, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR.\r\n"
|
||||
"If you are a great patreaon supporter already, sandboxie can check online for an update of your certificate."), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok) {
|
||||
theGUI->m_pUpdater->UpdateCert(true);
|
||||
if (g_CertInfo.insider)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
QMessageBox::warning(NULL, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR."));
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
NoGo = true;
|
||||
#else
|
||||
if (g_CertInfo.valid)
|
||||
return false;
|
||||
|
||||
QDateTime InstallDate = GetSbieInstallationDate();
|
||||
bool bOnARM64 = (g_FeatureFlags & CSbieAPI::eSbieFeatureARM64) != 0;
|
||||
|
||||
bool NoGo = false;
|
||||
|
||||
QDateTime CurretnDate = QDateTime::currentDateTimeUtc();
|
||||
int Days = InstallDate.daysTo(CurretnDate);
|
||||
if (Days < 40)
|
||||
|
@ -92,6 +114,7 @@ bool CSupportDialog::CheckSupport(bool bOnRun)
|
|||
return false;
|
||||
}
|
||||
m_ReminderShown = true;
|
||||
#endif
|
||||
|
||||
if (!ShowDialog(NoGo))
|
||||
PostQuitMessage(0);
|
||||
|
@ -107,6 +130,13 @@ bool CSupportDialog::ShowDialog(bool NoGo, int Wait)
|
|||
|
||||
QString Message;
|
||||
|
||||
#ifdef INSIDER_BUILD
|
||||
if (!g_CertInfo.insider)
|
||||
{
|
||||
Message += tr("This is a <a href=\"https://sandboxie-plus.com/go.php?to=sbie-insider\">exclusive Insider build</a> of Sandboxie-Plus it is only available to <a href=\"https://sandboxie-plus.com/go.php?to=patreon\">Patreon Supporters</a> on higher tiers as well as to project contributors and owners of a HUGE supporter certificate.");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (IsBusinessUse())
|
||||
{
|
||||
if (g_CertInfo.expired) {
|
||||
|
@ -272,7 +302,22 @@ void CSupportDialog::OnButton()
|
|||
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
|
||||
pSettingsWindow->showTab(CSettingsWindow::eSupport, true);
|
||||
connect(pSettingsWindow, &CSettingsWindow::Closed, [this]() {
|
||||
if(g_CertInfo.valid)
|
||||
#ifdef INSIDER_BUILD
|
||||
if (g_CertInfo.valid && !g_CertInfo.insider) {
|
||||
TArguments args = GetArguments(g_Certificate, L'\n', L':');
|
||||
if (args.value("TYPE").contains("PATREON")) {
|
||||
theGUI->m_pUpdater->UpdateCert(true);
|
||||
if (g_CertInfo.insider) {
|
||||
accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QMessageBox::warning(this, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR."));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (g_CertInfo.valid)
|
||||
accept();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWizard>
|
||||
#include <QProxyStyle>
|
||||
#include "SbiePlusAPI.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QRadioButton;
|
||||
class QButtonGroup;
|
||||
class QListWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class CWizardEngine;
|
||||
|
||||
class MyButtonStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
MyButtonStyle(QStyle* pStyle) : QProxyStyle(pStyle) {}
|
||||
|
||||
virtual QSize sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const
|
||||
{
|
||||
QSize s = QProxyStyle::sizeFromContents(type, option, size, widget);
|
||||
if (type == CE_PushButton && widget->property("leftButton").toBool())
|
||||
{
|
||||
if (const QStyleOptionButton* button = qstyleoption_cast<const QStyleOptionButton*>(option))
|
||||
{
|
||||
if (!button->icon.isNull()) {
|
||||
s.setWidth(s.width() + 20 + button->iconSize.width());
|
||||
}
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
virtual void drawControl(ControlElement element, const QStyleOption* opt, QPainter* p, const QWidget* widget) const
|
||||
{
|
||||
if (element == CE_PushButtonLabel && widget->property("leftButton").toBool())
|
||||
{
|
||||
if (const QStyleOptionButton* button = qstyleoption_cast<const QStyleOptionButton*>(opt))
|
||||
{
|
||||
QRect textRect = button->rect;
|
||||
uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
|
||||
if (!proxy()->styleHint(SH_UnderlineShortcut, button, widget))
|
||||
tf |= Qt::TextHideMnemonic;
|
||||
|
||||
if (!button->icon.isNull()) {
|
||||
QRect iconRect;
|
||||
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
|
||||
if (mode == QIcon::Normal && button->state & State_HasFocus)
|
||||
mode = QIcon::Active;
|
||||
QIcon::State state = QIcon::Off;
|
||||
if (button->state & State_On)
|
||||
state = QIcon::On;
|
||||
|
||||
QPixmap pixmap = button->icon.pixmap(widget ? widget->window()->windowHandle() : 0, button->iconSize, mode, state);
|
||||
|
||||
int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
|
||||
int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
|
||||
int labelWidth = pixmapWidth;
|
||||
int labelHeight = pixmapHeight;
|
||||
int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
|
||||
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
|
||||
if (!button->text.isEmpty())
|
||||
labelWidth += (textWidth + iconSpacing);
|
||||
|
||||
textRect.setLeft(textRect.left() + 20 + button->iconSize.width());
|
||||
|
||||
/*************************************************************/
|
||||
// Make the icon rectangle always be 10px in from the left edge
|
||||
/*************************************************************/
|
||||
iconRect = QRect(10,
|
||||
textRect.y() + (textRect.height() - labelHeight) / 2,
|
||||
pixmapWidth, pixmapHeight);
|
||||
|
||||
iconRect = visualRect(button->direction, textRect, iconRect);
|
||||
|
||||
/***********************************/
|
||||
// Always horizontal align the text
|
||||
/***********************************/
|
||||
tf |= Qt::AlignLeft;
|
||||
|
||||
|
||||
if (button->state & (State_On | State_Sunken))
|
||||
iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
|
||||
proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
|
||||
p->drawPixmap(iconRect, pixmap);
|
||||
}
|
||||
else {
|
||||
tf |= Qt::AlignHCenter;
|
||||
}
|
||||
if (button->state & (State_On | State_Sunken))
|
||||
textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
|
||||
proxy()->pixelMetric(PM_ButtonShiftVertical, opt, widget));
|
||||
|
||||
if (button->features & QStyleOptionButton::HasMenu) {
|
||||
int indicatorSize = proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget);
|
||||
if (button->direction == Qt::LeftToRight)
|
||||
textRect = textRect.adjusted(0, 0, -indicatorSize, 0);
|
||||
else
|
||||
textRect = textRect.adjusted(indicatorSize, 0, 0, 0);
|
||||
}
|
||||
proxy()->drawItemText(p, textRect, tf, button->palette, (button->state & State_Enabled),
|
||||
button->text, QPalette::ButtonText);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// For all other controls, draw the default
|
||||
QProxyStyle::drawControl(element, opt, p, widget);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CBoxAssistant : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum { Page_Begin, Page_Group, Page_List, Page_Run, Page_Submit, Page_Complete, Page_Next };
|
||||
|
||||
CBoxAssistant(QWidget *parent = nullptr);
|
||||
~CBoxAssistant();
|
||||
|
||||
static void ShowAssistant();
|
||||
|
||||
virtual void accept();
|
||||
virtual void reject();
|
||||
|
||||
QString Tr(const QString& Text) { return m_Translation.value(Text, Text).toString(); }
|
||||
|
||||
static QString GetIssueDir(class C7zFileEngineHandler& IssueFS, QDateTime* pDate = NULL);
|
||||
|
||||
private slots:
|
||||
|
||||
void OnUpdateData(const QVariantMap& Data, const QVariantMap& Params);
|
||||
void OnDownload(const QString& Path, const QVariantMap& Params);
|
||||
|
||||
void OnToggleDebugger();
|
||||
|
||||
void OnBoxUsed(const CSandBoxPtr& pBox);
|
||||
|
||||
protected:
|
||||
friend class CBeginPage;
|
||||
friend class CGroupPage;
|
||||
friend class CListPage;
|
||||
friend class CRunPage;
|
||||
friend class CSubmitPage;
|
||||
friend class CCompletePage;
|
||||
|
||||
void LoadIssues(const QString& IssueDir);
|
||||
|
||||
QList<QVariantMap> GetIssues(const QVariantMap& Root) const;
|
||||
|
||||
void PushIssue(const QVariantMap& Issue) { m_IssueStack.append(Issue); }
|
||||
void PopIssue() { m_IssueStack.removeLast(); }
|
||||
QVariantMap CurrentIssue() const { return m_IssueStack.isEmpty() ? QVariantMap() : m_IssueStack.last(); }
|
||||
|
||||
bool StartEngine();
|
||||
void KillEngine();
|
||||
|
||||
CWizardEngine* GetEngine() { return m_pEngine; }
|
||||
|
||||
int m_NextCounter;
|
||||
|
||||
struct SUsedBox
|
||||
{
|
||||
CSandBoxPtr pBox;
|
||||
QStringList OldDumps;
|
||||
};
|
||||
|
||||
QList<SUsedBox> m_UsedBoxes;
|
||||
|
||||
private:
|
||||
QMap<QString,QList<QVariantMap>> m_GroupedIssues;
|
||||
|
||||
QList<QVariantMap> m_IssueStack;
|
||||
QDateTime m_IssueDate;
|
||||
|
||||
CWizardEngine* m_pEngine;
|
||||
bool m_bUseDebugger;
|
||||
QMainWindow* m_pDebugger;
|
||||
|
||||
QVariantMap m_Translation;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBeginPage
|
||||
//
|
||||
|
||||
class CBeginPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CBeginPage(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
int nextId() const override;
|
||||
bool isComplete() const override;
|
||||
bool validatePage() override;
|
||||
|
||||
private slots:
|
||||
void OnCategory();
|
||||
|
||||
private:
|
||||
QGridLayout* m_pLayout;
|
||||
QPushButton* m_pCurrent;
|
||||
QList<QWidget*> m_pWidgets;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CGroupPage
|
||||
//
|
||||
|
||||
class CGroupPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CGroupPage(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
void cleanupPage() override;
|
||||
int nextId() const override;
|
||||
bool isComplete() const override;
|
||||
bool validatePage() override;
|
||||
|
||||
private:
|
||||
QGridLayout* m_pLayout;
|
||||
QLabel* m_pTopLabel;
|
||||
QButtonGroup* m_pGroup;
|
||||
QList<QWidget*> m_pWidgets;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CListPage
|
||||
//
|
||||
|
||||
class CListPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CListPage(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
void cleanupPage() override;
|
||||
int nextId() const override;
|
||||
bool isComplete() const override;
|
||||
bool validatePage() override;
|
||||
|
||||
private slots:
|
||||
void ApplyFilter();
|
||||
|
||||
private:
|
||||
void LoadIssues();
|
||||
|
||||
QGridLayout* m_pLayout;
|
||||
QLineEdit* m_pFilter;
|
||||
QListWidget* m_pList;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CRunPage
|
||||
//
|
||||
|
||||
class CRunPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CRunPage(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
void cleanupPage() override;
|
||||
bool isComplete() const override;
|
||||
int nextId() const override;
|
||||
bool validatePage() override;
|
||||
|
||||
private slots:
|
||||
void OnStateChanged(int state, const QString& Text = "");
|
||||
void CheckUserInput();
|
||||
|
||||
private:
|
||||
QGridLayout* m_pLayout;
|
||||
QLabel* m_pTopLabel;
|
||||
QWidget* m_pForm;
|
||||
QMultiMap<QString, QWidget*> m_pWidgets;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSubmitPage
|
||||
//
|
||||
|
||||
class CSubmitPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CSubmitPage(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
int nextId() const override {return -1;}
|
||||
bool validatePage() override;
|
||||
|
||||
private:
|
||||
QLabel* m_pTopLabel;
|
||||
QTextEdit* m_pReport;
|
||||
QLineEdit* m_pMail;
|
||||
QCheckBox* m_pAttachIni;
|
||||
QCheckBox* m_pAttachLog;
|
||||
QCheckBox* m_pAttachDmp;
|
||||
|
||||
CSbieProgressPtr m_pUploadProgress;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CCompletePage
|
||||
//
|
||||
|
||||
class CCompletePage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CCompletePage(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
int nextId() const override {return -1;}
|
||||
|
||||
private:
|
||||
QLabel* m_pLabel;
|
||||
};
|
||||
|
|
@ -28,6 +28,8 @@ CNewBoxWizard::CNewBoxWizard(bool bAlowTemp, QWidget *parent)
|
|||
connect(this, &QWizard::helpRequested, this, &CNewBoxWizard::showHelp);
|
||||
|
||||
setWindowTitle(tr("New Box Wizard"));
|
||||
|
||||
setMinimumWidth(600);
|
||||
}
|
||||
|
||||
void CNewBoxWizard::showHelp()
|
||||
|
@ -120,8 +122,10 @@ SB_STATUS CNewBoxWizard::TryToCreateBox()
|
|||
}
|
||||
pBox->SetBool("BlockNetworkFiles", !field("shareAccess").toBool());
|
||||
|
||||
if(field("fakeAdmin").toBool())
|
||||
if (field("fakeAdmin").toBool()) {
|
||||
pBox->SetBool("DropAdminRights", true);
|
||||
pBox->SetBool("FakeAdminRights", true);
|
||||
}
|
||||
if(field("msiServer").toBool())
|
||||
pBox->SetBool("MsiInstallerExemptions", true);
|
||||
|
||||
|
@ -617,6 +621,7 @@ bool CSummaryPage::validatePage()
|
|||
|
||||
SB_STATUS Status = ((CNewBoxWizard*)wizard())->TryToCreateBox();
|
||||
if (Status.IsError()) {
|
||||
if(Status.GetMsgCode() != SB_Canceled)
|
||||
QMessageBox::critical(this, "Sandboxie-Plus", tr("Failed to create new box: %1").arg(theGUI->FormatError(Status)));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -8,16 +8,19 @@
|
|||
#include <QButtonGroup>
|
||||
#include "../QSbieAPI/SbieUtils.h"
|
||||
|
||||
QString emailRegExp = QStringLiteral(".+@.+");
|
||||
|
||||
CSetupWizard::CSetupWizard(QWidget *parent)
|
||||
CSetupWizard::CSetupWizard(int iOldLevel, QWidget *parent)
|
||||
: QWizard(parent)
|
||||
{
|
||||
if (iOldLevel < SETUP_LVL_1) {
|
||||
setPage(Page_Intro, new CIntroPage);
|
||||
setPage(Page_Certificate, new CCertificatePage);
|
||||
setPage(Page_UI, new CUIPage);
|
||||
setPage(Page_Shell, new CShellPage);
|
||||
setPage(Page_WFP, new CWFPPage);
|
||||
//setPage(Page_WFP, new CWFPPage);
|
||||
}
|
||||
if (iOldLevel < SETUP_LVL_2) {
|
||||
setPage(Page_Update, new CSBUpdate);
|
||||
}
|
||||
setPage(Page_Finish, new CFinishPage);
|
||||
|
||||
setWizardStyle(ModernStyle);
|
||||
|
@ -51,12 +54,13 @@ void CSetupWizard::showHelp()
|
|||
lastHelpMessage = message;
|
||||
}
|
||||
|
||||
bool CSetupWizard::ShowWizard()
|
||||
bool CSetupWizard::ShowWizard(int iOldLevel)
|
||||
{
|
||||
CSetupWizard wizard;
|
||||
CSetupWizard wizard(iOldLevel, theGUI);
|
||||
if (!theGUI->SafeExec(&wizard))
|
||||
return false;
|
||||
|
||||
if (iOldLevel < SETUP_LVL_1) {
|
||||
//bool useBusiness = wizard.field("useBusiness").toBool();
|
||||
//QString Certificate = wizard.field("useCertificate").toString();
|
||||
//bool isEvaluate = wizard.field("isEvaluate").toBool();
|
||||
|
@ -76,21 +80,57 @@ bool CSetupWizard::ShowWizard()
|
|||
AutorunEnable(wizard.field("isAutoStart").toBool());
|
||||
|
||||
if (wizard.field("useContecxtMenu").toBool())
|
||||
CSettingsWindow__AddContextMenu();
|
||||
CSettingsWindow::AddContextMenu();
|
||||
|
||||
if (wizard.field("useBrowserIcon").toBool())
|
||||
CSettingsWindow__AddBrowserIcon();
|
||||
CSettingsWindow::AddBrowserIcon();
|
||||
|
||||
if (wizard.field("useWFP").toBool()) {
|
||||
theAPI->GetGlobalSettings()->SetBool("NetworkEnableWFP", true);
|
||||
theAPI->ReloadConfig(true);
|
||||
//if (wizard.field("useWFP").toBool()) {
|
||||
// theAPI->GetGlobalSettings()->SetBool("NetworkEnableWFP", true);
|
||||
// theAPI->ReloadConfig(true);
|
||||
//}
|
||||
}
|
||||
|
||||
if (wizard.field("isUpdate").toBool()) {
|
||||
if (iOldLevel < SETUP_LVL_2) {
|
||||
|
||||
if (wizard.field("updateAll").toBool())
|
||||
{
|
||||
theConf->SetValue("Options/CheckForUpdates", 1);
|
||||
theConf->SetValue("Options/OnNewUpdate", "install");
|
||||
//theConf->SetValue("Options/CheckForTemplates", 1);
|
||||
theConf->SetValue("Options/CheckForIssues", 1);
|
||||
theConf->SetValue("Options/CheckForAddons", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wizard.field("updateApp").toBool())
|
||||
theConf->SetValue("Options/CheckForUpdates", 1);
|
||||
if(wizard.field("applyHotfixes").toBool())
|
||||
theConf->SetValue("Options/OnNewUpdate", "install");
|
||||
//if(wizard.field("updateCompat").toBool())
|
||||
// theConf->SetValue("Options/CheckForTemplates", 1);
|
||||
if(wizard.field("updateIssues").toBool())
|
||||
theConf->SetValue("Options/CheckForIssues", 1);
|
||||
if(wizard.field("updateAddons").toBool())
|
||||
theConf->SetValue("Options/CheckForAddons", 1);
|
||||
}
|
||||
|
||||
theConf->SetValue("Options/WizardLevel", 1);
|
||||
if (wizard.field("updateAll").toBool() || wizard.field("updateApp").toBool()) {
|
||||
QString ReleaseChannel;
|
||||
if (wizard.field("channelStable").toBool())
|
||||
ReleaseChannel = "stable";
|
||||
else if (wizard.field("channelPreview").toBool())
|
||||
ReleaseChannel = "preview";
|
||||
else if (wizard.field("channelInsider").toBool())
|
||||
ReleaseChannel = "insider";
|
||||
if (!ReleaseChannel.isEmpty()) theConf->SetValue("Options/ReleaseChannel", ReleaseChannel);
|
||||
}
|
||||
}
|
||||
|
||||
//if (wizard.field("isUpdate").toBool())
|
||||
// theConf->SetValue("Options/CheckForUpdates", 1);
|
||||
|
||||
theConf->SetValue("Options/WizardLevel", SETUP_LVL_CURRENT);
|
||||
|
||||
theGUI->UpdateSettings(true);
|
||||
|
||||
|
@ -101,7 +141,7 @@ void CSetupWizard::ShellUninstall()
|
|||
{
|
||||
AutorunEnable(false);
|
||||
|
||||
CSettingsWindow__RemoveContextMenu();
|
||||
CSettingsWindow::RemoveContextMenu();
|
||||
CSbieUtils::RemoveContextMenu2();
|
||||
|
||||
// todo: delete desktop browser shortcut and start menu integration
|
||||
|
@ -439,7 +479,8 @@ CShellPage::CShellPage(QWidget *parent)
|
|||
|
||||
int CShellPage::nextId() const
|
||||
{
|
||||
return CSetupWizard::Page_WFP;
|
||||
//return CSetupWizard::Page_WFP;
|
||||
return CSetupWizard::Page_Update;
|
||||
//return CSetupWizard::Page_Finish;
|
||||
}
|
||||
|
||||
|
@ -447,7 +488,7 @@ int CShellPage::nextId() const
|
|||
// CWFPPage
|
||||
//
|
||||
|
||||
CWFPPage::CWFPPage(QWidget *parent)
|
||||
/*CWFPPage::CWFPPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Configure <b>Sandboxie-Plus</b> network filtering"));
|
||||
|
@ -475,6 +516,147 @@ CWFPPage::CWFPPage(QWidget *parent)
|
|||
}
|
||||
|
||||
int CWFPPage::nextId() const
|
||||
{
|
||||
return CSetupWizard::Page_Finish;
|
||||
}*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSBUpdate
|
||||
//
|
||||
|
||||
CSBUpdate::CSBUpdate(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Configure <b>Sandboxie-Plus</b> updater"));
|
||||
setSubTitle(tr("Like with any other security product it's important to keep your Sandboxie-Plus up to date."));
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->setSpacing(3);
|
||||
|
||||
int row = 0;
|
||||
int rows = 4;
|
||||
|
||||
m_pUpdate = new QCheckBox(tr("Regularly Check for all udpates to Sandboxie-Plus and optional components"));
|
||||
m_pUpdate->setToolTip(tr("Let sandboxie regularly check for latest updates."));
|
||||
layout->addWidget(m_pUpdate, row++, 0, 1, rows);
|
||||
connect(m_pUpdate, &QCheckBox::toggled, this, &CSBUpdate::UpdateOptions);
|
||||
registerField("updateAll", m_pUpdate);
|
||||
|
||||
QWidget* pSpacer = new QWidget();
|
||||
pSpacer->setMinimumHeight(16);
|
||||
pSpacer->setMaximumWidth(16);
|
||||
layout->addWidget(pSpacer, row+5, 0, 1, 1);
|
||||
|
||||
m_pVersion = new QCheckBox(tr("Check for new Sandboxie-Plus versions:"));
|
||||
m_pVersion->setToolTip(tr("Check for new Sandboxie-Plus builds."));
|
||||
layout->addWidget(m_pVersion, row++, 1, 1, rows-2);
|
||||
//layout->addWidget(new QComboBox(), row-1, 3, 1, 1);
|
||||
connect(m_pVersion, &QCheckBox::toggled, this, &CSBUpdate::UpdateOptions);
|
||||
registerField("updateApp", m_pVersion);
|
||||
|
||||
m_pChanelInfo = new QLabel(tr("Sellect in which update channel to look for new Sandboxie-Plus builds:"));
|
||||
m_pChanelInfo->setMinimumHeight(20);
|
||||
layout->addWidget(m_pChanelInfo, row++, 1, 1, rows-1);
|
||||
|
||||
pSpacer = new QWidget();
|
||||
pSpacer->setMinimumHeight(16);
|
||||
pSpacer->setMaximumWidth(16);
|
||||
layout->addWidget(pSpacer, row, 1, 1, 1);
|
||||
|
||||
m_pStable = new QRadioButton(tr("In the Stable Channel"));
|
||||
m_pStable->setToolTip(tr("The stable channel contains the latest stable GitHub releases."));
|
||||
layout->addWidget(m_pStable, row++, 2, 1, rows-2);
|
||||
registerField("channelStable", m_pStable);
|
||||
|
||||
m_pPreview = new QRadioButton(tr("In the Preview Channel - with newest experimental changes"));
|
||||
m_pPreview->setToolTip(tr("The preview channel contains the latest GitHub pre-releases."));
|
||||
layout->addWidget(m_pPreview, row++, 2, 1, rows-2);
|
||||
registerField("channelPreview", m_pPreview);
|
||||
|
||||
m_pInsider = new QRadioButton(tr("In the Insider Channel - exclusive features"));
|
||||
m_pInsider->setToolTip(tr("The Insider channel offers early access to new features and bugfixes that will eventually be released to the public, "
|
||||
"as well as all relevant improvements from the stable channel. \nUnlike the preview channel, it does not include untested, potentially breaking, "
|
||||
"or experimental changes that may not be ready for wider use."));
|
||||
layout->addWidget(m_pInsider, row, 2, 1, 1);
|
||||
registerField("channelInsider", m_pInsider);
|
||||
QLabel* pInsiderInfo = new QLabel(tr("More about the <a href=\"https://sandboxie-plus.com/go.php?to=sbie-insider\">Insider Channel</a>"));
|
||||
connect(pInsiderInfo, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
layout->addWidget(pInsiderInfo, row++, 3, 1, 1);
|
||||
|
||||
//m_pTemplates = new QCheckBox(tr("Keep Compatybility Templates up to date"));
|
||||
//m_pTemplates->setToolTip(tr("Check for latest compatybility tempaltes."));
|
||||
//layout->addWidget(m_pTemplates, row++, 1, 1, rows-1);
|
||||
//registerField("updateCompat", m_pTemplates);
|
||||
|
||||
m_pHotfixes = new QCheckBox(tr("Keep Compatybility Templates up to date and apply hotfixes"));
|
||||
m_pHotfixes->setToolTip(tr("Check for latest compatybility tempaltes and hotfixes."));
|
||||
layout->addWidget(m_pHotfixes, row++, 1, 1, rows-1);
|
||||
registerField("applyHotfixes", m_pHotfixes);
|
||||
|
||||
m_pIssues = new QCheckBox(tr("Get the latest Scripts for the Troubleshooting Wizard"));
|
||||
m_pIssues->setToolTip(tr("Check for latest troubleshooting scripts for the troubleshooting wizars."));
|
||||
layout->addWidget(m_pIssues, row++, 1, 1, rows-1);
|
||||
registerField("updateIssues", m_pIssues);
|
||||
|
||||
m_pAddons = new QCheckBox(tr("Keep the list of optional Addon components up to date"));
|
||||
m_pAddons->setToolTip(tr("Check for latest avaialble addons."));
|
||||
layout->addWidget(m_pAddons, row++, 1, 1, rows-1);
|
||||
registerField("updateAddons", m_pAddons);
|
||||
|
||||
m_pUpdateInfo = new QLabel();
|
||||
m_pUpdateInfo->setWordWrap(true);
|
||||
//m_pUpdateInfo->setText(tr("Sandboxie-Plus applies many application restrictions which may occasionally lead to compatibility issues, necessitating mitigation efforts. "
|
||||
// "Compatibility may be broken by new Windows updates and changes within sandboxed applications themselves. "
|
||||
// "To ensure smooth operation, it is highly recommended to regularly check for Sandboxie-Plus updates, apply the latest compatibility templates, and keep troubleshooting scripts up-to-date."));
|
||||
m_pUpdateInfo->setText(tr("Sandboxie-Plus applies strict application restrictions, which can lead to compatibility issues. "
|
||||
"Stay updated with Sandboxie-Plus, including compatibility templates and troubleshooting, to ensure smooth operation amid Windows updates and application changes."));
|
||||
layout->addWidget(m_pUpdateInfo, row++, 0, 1, rows);
|
||||
|
||||
layout->addItem(new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Expanding), row++, 0);
|
||||
|
||||
m_pBottomLabel = new QLabel(tr("Access to the latest compatibility templates and the online troubleshooting database requires a valid <a href=\"https://sandboxie-plus.com/go.php?to=sbie-cert\">supporter certificate</a>."));
|
||||
connect(m_pBottomLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&)));
|
||||
m_pBottomLabel->setWordWrap(true);
|
||||
layout->addWidget(m_pBottomLabel, row++, 0, 1, rows);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void CSBUpdate::initializePage()
|
||||
{
|
||||
m_pUpdate->setChecked(true);
|
||||
m_pStable->setChecked(true);
|
||||
|
||||
m_pBottomLabel->setVisible(!g_CertInfo.valid || g_CertInfo.expired);
|
||||
|
||||
UpdateOptions();
|
||||
}
|
||||
|
||||
void CSBUpdate::UpdateOptions()
|
||||
{
|
||||
m_pVersion->setVisible(!m_pUpdate->isChecked());
|
||||
//m_pTemplates->setVisible(!m_pUpdate->isChecked());
|
||||
m_pHotfixes->setVisible(!m_pUpdate->isChecked());
|
||||
m_pIssues->setVisible(!m_pUpdate->isChecked());
|
||||
m_pAddons->setVisible(!m_pUpdate->isChecked());
|
||||
m_pChanelInfo->setVisible(m_pUpdate->isChecked());
|
||||
m_pUpdateInfo->setVisible(m_pUpdate->isChecked());
|
||||
|
||||
if (m_pUpdate->isChecked()) {
|
||||
m_pVersion->setChecked(true);
|
||||
//m_pTemplates->setChecked(true);
|
||||
m_pIssues->setChecked(true);
|
||||
m_pAddons->setChecked(true);
|
||||
}
|
||||
|
||||
m_pStable->setEnabled(m_pVersion->isChecked());
|
||||
m_pPreview->setEnabled(m_pVersion->isChecked());
|
||||
m_pInsider->setEnabled(g_CertInfo.insider && m_pVersion->isChecked());
|
||||
|
||||
m_pHotfixes->setEnabled(m_pVersion->isChecked());
|
||||
}
|
||||
|
||||
int CSBUpdate::nextId() const
|
||||
{
|
||||
return CSetupWizard::Page_Finish;
|
||||
}
|
||||
|
@ -496,19 +678,19 @@ CFinishPage::CFinishPage(QWidget *parent)
|
|||
m_pLabel->setText(tr("Almost complete, click Finish to apply all selected options and conclude the wizard."));
|
||||
layout->addWidget(m_pLabel);
|
||||
|
||||
QWidget* pSpacer = new QWidget();
|
||||
pSpacer->setMinimumHeight(16);
|
||||
layout->addWidget(pSpacer);
|
||||
//QWidget* pSpacer = new QWidget();
|
||||
//pSpacer->setMinimumHeight(16);
|
||||
//layout->addWidget(pSpacer);
|
||||
|
||||
//QLabel* pLabel = new QLabel;
|
||||
//pLabel->setWordWrap(true);
|
||||
//pLabel->setText(tr("Like with any other security product it's important to keep your Sandboxie-Plus up to date."));
|
||||
//layout->addWidget(pLabel);
|
||||
|
||||
m_pUpdate = new QCheckBox(tr("Keep Sandboxie-Plus up to date."));
|
||||
m_pUpdate->setChecked(true);
|
||||
layout->addWidget(m_pUpdate);
|
||||
registerField("isUpdate", m_pUpdate);
|
||||
//m_pUpdate = new QCheckBox(tr("Keep Sandboxie-Plus up to date."));
|
||||
//m_pUpdate->setChecked(true);
|
||||
//layout->addWidget(m_pUpdate);
|
||||
//registerField("isUpdate", m_pUpdate);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
|
|
@ -9,16 +9,20 @@ class QLineEdit;
|
|||
class QRadioButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#define SETUP_LVL_1 1
|
||||
#define SETUP_LVL_2 2
|
||||
#define SETUP_LVL_CURRENT SETUP_LVL_2
|
||||
|
||||
class CSetupWizard : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum { Page_Intro, Page_Certificate, Page_UI, Page_Shell, Page_WFP, Page_Finish };
|
||||
enum { Page_Intro, Page_Certificate, Page_UI, Page_Shell, Page_Update, Page_Finish };
|
||||
|
||||
CSetupWizard(QWidget *parent = nullptr);
|
||||
CSetupWizard(int iOldLevel = 0, QWidget *parent = nullptr);
|
||||
|
||||
static bool ShowWizard();
|
||||
static bool ShowWizard(int iOldLevel = 0);
|
||||
|
||||
static void ShellUninstall();
|
||||
|
||||
|
@ -117,7 +121,7 @@ private:
|
|||
// CWFPPage
|
||||
//
|
||||
|
||||
class CWFPPage : public QWizardPage
|
||||
/*class CWFPPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -128,6 +132,39 @@ public:
|
|||
|
||||
private:
|
||||
QCheckBox *m_pUseWFP;
|
||||
};*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSBUpdate
|
||||
//
|
||||
|
||||
class CSBUpdate : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CSBUpdate(QWidget *parent = nullptr);
|
||||
|
||||
void initializePage() override;
|
||||
|
||||
int nextId() const override;
|
||||
|
||||
private slots:
|
||||
void UpdateOptions();
|
||||
|
||||
private:
|
||||
QCheckBox* m_pUpdate;
|
||||
QCheckBox* m_pVersion;
|
||||
QLabel* m_pChanelInfo;
|
||||
QRadioButton* m_pStable;
|
||||
QRadioButton* m_pPreview;
|
||||
QRadioButton* m_pInsider;
|
||||
QCheckBox* m_pHotfixes;
|
||||
//QCheckBox* m_pTemplates;
|
||||
QCheckBox* m_pIssues;
|
||||
QCheckBox* m_pAddons;
|
||||
QLabel* m_pUpdateInfo;
|
||||
QLabel* m_pBottomLabel;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -147,6 +184,6 @@ public:
|
|||
|
||||
private:
|
||||
QLabel *m_pLabel;
|
||||
QCheckBox *m_pUpdate;
|
||||
//QCheckBox *m_pUpdate;
|
||||
};
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ CBrowserTypePage::CBrowserTypePage(QWidget *parent)
|
|||
layout->addWidget(new QLabel(tr("Enter browser name:")), row++, 0);
|
||||
|
||||
m_pName = new QLineEdit();
|
||||
m_pName->setMaxLength(32);
|
||||
m_pName->setMaxLength(32); // BOXNAME_COUNT
|
||||
m_pName->setMaximumWidth(150);
|
||||
layout->addWidget(m_pName, row++, 0, 1, 1);
|
||||
connect(m_pName, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameChanged()));
|
||||
|
|
|
@ -28,8 +28,12 @@ int main(int argc, char *argv[])
|
|||
g_CertInfo.business = GetArguments(g_Certificate, L'\n', L':').value("TYPE").toUpper().contains("BUSINESS");
|
||||
}
|
||||
|
||||
// use AppFolder/PlusData when present, else fallback to AppFolder
|
||||
QString ConfDir = AppDir + "\\PlusData";
|
||||
if(!QFile::exists(ConfDir))
|
||||
ConfDir = AppDir;
|
||||
// use a shared setting location when used in a business environment for easier administration
|
||||
theConf = new CSettings(AppDir, "Sandboxie-Plus", g_CertInfo.business);
|
||||
theConf = new CSettings(ConfDir, "Sandboxie-Plus", g_CertInfo.business);
|
||||
|
||||
#ifndef _DEBUG
|
||||
InitMiniDumpWriter(QString("SandMan-v%1").arg(CSandMan::GetVersion()).toStdWString().c_str() , QString(theConf->GetConfigDir()).replace("/", "\\").toStdWString().c_str());
|
||||
|
@ -101,22 +105,34 @@ int main(int argc, char *argv[])
|
|||
g_PendingMessage = "Op:" + Op;
|
||||
}
|
||||
|
||||
CmdPos = Args.indexOf("/box:__ask__", Qt::CaseInsensitive);
|
||||
CmdPos = -1;
|
||||
for (int i = 0; i < Args.size(); i++) {
|
||||
if (Args[i].left(5).compare("/box:", Qt::CaseInsensitive) == 0)
|
||||
CmdPos = i;
|
||||
}
|
||||
if (CmdPos != -1) {
|
||||
// Note: a escaped command ending with \" will fail and unescape "
|
||||
//QString CommandLine;
|
||||
//for (int i = CmdPos + 1; i < Args.count(); i++)
|
||||
// CommandLine += "\"" + Args[i] + "\" ";
|
||||
//g_PendingMessage = "Run:" + CommandLine.trimmed();
|
||||
LPWSTR ChildCmdLine = wcsstr(GetCommandLineW(), L"/box:__ask__") + 13;
|
||||
LPWSTR cmdLine0 = wcsstr(GetCommandLineW(), L"/box:");
|
||||
if (!cmdLine0) return -1;
|
||||
LPWSTR cmdLine = wcschr(cmdLine0 + 5, L' ');
|
||||
if (!cmdLine) return -2;
|
||||
|
||||
if (IsBoxed) {
|
||||
ShellExecute(NULL, L"open", ChildCmdLine, NULL, NULL, SW_SHOWNORMAL);
|
||||
ShellExecute(NULL, L"open", cmdLine + 1, NULL, NULL, SW_SHOWNORMAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_PendingMessage = "Run:" + QString::fromWCharArray(ChildCmdLine);
|
||||
g_PendingMessage = "Run:" + QString::fromWCharArray(cmdLine + 1);
|
||||
|
||||
g_PendingMessage += "\nFrom:" + QDir::currentPath();
|
||||
|
||||
QString BoxName = QString::fromWCharArray(cmdLine0 + 5, cmdLine - (cmdLine0 + 5));
|
||||
if(BoxName != "__ask__")
|
||||
g_PendingMessage += "\nIn:" + BoxName;
|
||||
}
|
||||
|
||||
if (IsBoxed) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#define VERSION_MJR 1
|
||||
#define VERSION_MIN 9
|
||||
#define VERSION_REV 8
|
||||
#define VERSION_MIN 10
|
||||
#define VERSION_REV 0
|
||||
#define VERSION_UPD 0
|
||||
|
||||
#ifndef STR
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
#include "../framework.h"
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
// C RunTime Header Files
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <tchar.h>
|
||||
#include <winternl.h>
|
||||
|
||||
#include "helpers.h"
|
||||
#include <winhttp.h>
|
||||
|