This commit is contained in:
DavidXanatos 2021-01-02 09:03:16 +01:00
parent 911745eca6
commit 841192a2b0
18 changed files with 266 additions and 33 deletions

View File

@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [0.5.3b / 5.45.2] - 2020-12-02
### Added
- added settings for the porteble boxed root folder option
- added process name to resource log
- added command line column to the process view in the sandman UI
### Fixed
- fixed a few issues wiht group handling
- fixed issue with GetRawInputDeviceInfo when runnign a 32 bit program on a 64 bis system
- fixed issue when pressing apply int he "Resource Access" tab the last edited value was not always applyed
- fixed issue merging entries in resource access monitor

View File

@ -68,6 +68,10 @@
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>

View File

@ -65,6 +65,10 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
@ -135,6 +139,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalOptions> /SUBSYSTEM:WINDOWS</AdditionalOptions>
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

View File

@ -28,6 +28,8 @@ typedef long NTSTATUS;
#include "..\..\Sandboxie\common\win32_ntddk.h"
#include <psapi.h> // For access to GetModuleFileNameEx
#include <winnt.h>
//struct SBoxedProcess
//{
//};
@ -52,12 +54,114 @@ CBoxedProcess::~CBoxedProcess()
//delete m;
}
typedef enum _PEB_OFFSET
{
PhpoCurrentDirectory,
PhpoDllPath,
PhpoImagePathName,
PhpoCommandLine,
PhpoWindowTitle,
PhpoDesktopInfo,
PhpoShellInfo,
PhpoRuntimeData,
PhpoTypeMask = 0xffff,
PhpoWow64 = 0x10000
} PEB_OFFSET;
typedef struct _STRING32
{
USHORT Length;
USHORT MaximumLength;
ULONG Buffer;
} UNICODE_STRING32, * PUNICODE_STRING32;
QString CBoxedProcess__GetPebString(HANDLE ProcessHandle, PEB_OFFSET Offset)
{
BOOL is64BitOperatingSystem = FALSE;
BOOL isWow64Process = FALSE;
#ifdef _WIN64
is64BitOperatingSystem = TRUE;
#else // ! _WIN64
IsWow64Process(GetCurrentProcess(), &isWow64Process);
is64BitOperatingSystem = isWow64Process;
#endif _WIN64
BOOL isTargetWow64Process = FALSE;
IsWow64Process(ProcessHandle, &isTargetWow64Process);
BOOL isTarget64BitProcess = is64BitOperatingSystem && !isTargetWow64Process;
ULONG processParametersOffset = isTarget64BitProcess ? 0x20 : 0x10;
ULONG offset = 0;
switch (Offset)
{
case PhpoCurrentDirectory: offset = isTarget64BitProcess ? 0x38 : 0x24; break;
case PhpoCommandLine: offset = isTarget64BitProcess ? 0x70 : 0x40; break;
default:
return QString();
}
wstring s;
if (isTargetWow64Process) // OS : 64Bit, Cur : 32 or 64, Tar: 32bit
{
PVOID peb32;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessWow64Information, &peb32, sizeof(PVOID), NULL)))
return QString();
ULONG procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)peb32 + processParametersOffset), &procParams, sizeof(ULONG), NULL)))
return QString();
UNICODE_STRING32 us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING32), NULL)))
return QString();
if ((us.Buffer == 0) || (us.Length == 0))
return QString();
s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return QString();
}
else if (isWow64Process) //Os : 64Bit, Cur 32, Tar 64
{
return QString(); // not supported
}
else // Os,Cur,Tar : 64 or 32
{
PROCESS_BASIC_INFORMATION pbi;
if (!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL)))
return QString();
ULONG_PTR procParams;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)((ULONG64)pbi.PebBaseAddress + processParametersOffset), &procParams, sizeof(ULONG_PTR), NULL)))
return QString();
UNICODE_STRING us;
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)(procParams + offset), &us, sizeof(UNICODE_STRING), NULL)))
return QString();
if ((us.Buffer == 0) || (us.Length == 0))
return QString();
s.resize(us.Length / 2);
if (!NT_SUCCESS(NtReadVirtualMemory(ProcessHandle, (PVOID)us.Buffer, (PVOID)s.c_str(), s.length() * 2, NULL)))
return QString();
}
return QString::fromWCharArray(s.c_str());
}
bool CBoxedProcess::InitProcessInfo()
{
HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)m_ProcessId);
HANDLE ProcessHandle;
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, (DWORD)m_ProcessId);
if (ProcessHandle == INVALID_HANDLE_VALUE) // try with less rights
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)m_ProcessId);
if (ProcessHandle == INVALID_HANDLE_VALUE)
return false;
PROCESS_BASIC_INFORMATION BasicInformation;
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &BasicInformation, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (NT_SUCCESS(status)) {
@ -68,6 +172,27 @@ bool CBoxedProcess::InitProcessInfo()
if (DWORD size = GetModuleFileNameEx(ProcessHandle, NULL, filename, MAX_PATH))
m_ImagePath = QString::fromWCharArray(filename);
if (1) // windows 8.1 and later // todo add os version check
{
#define ProcessCommandLineInformation ((PROCESSINFOCLASS)60)
ULONG returnLength = 0;
NTSTATUS status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, NULL, 0, &returnLength);
if (!(status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL && status != STATUS_INFO_LENGTH_MISMATCH))
{
PUNICODE_STRING commandLine = (PUNICODE_STRING)malloc(returnLength);
status = NtQueryInformationProcess(ProcessHandle, ProcessCommandLineInformation, commandLine, returnLength, &returnLength);
if (NT_SUCCESS(status) && commandLine->Buffer != NULL)
m_CommandLine = QString::fromWCharArray(commandLine->Buffer);
free(commandLine);
}
#undef ProcessCommandLineInformation
}
if (m_CommandLine.isEmpty()) // fall back to teh win 7 method - requirers PROCESS_VM_READ
{
m_CommandLine = CBoxedProcess__GetPebString(ProcessHandle, PhpoCommandLine);
}
NtClose(ProcessHandle);
return true;
}

View File

@ -34,6 +34,7 @@ public:
virtual quint32 GetProcessId() const { return m_ProcessId; }
virtual quint32 GetParendPID() const { return m_ParendPID; }
virtual QString GetProcessName() const { return m_ImageName; }
virtual QString GetCommandLine() const { return m_CommandLine; }
virtual QString GetFileName() const { return m_ImagePath; }
virtual QDateTime GetTimeStamp() const { return m_StartTime; }
@ -53,6 +54,7 @@ protected:
quint32 m_ParendPID;
QString m_ImageName;
QString m_ImagePath;
QString m_CommandLine;
quint32 m_SessionId;
QDateTime m_StartTime;
quint64 m_uTerminated;

View File

@ -1762,6 +1762,8 @@ CBoxedProcessPtr CSbieAPI::OnProcessBoxed(quint32 ProcessId, const QString& Path
pProcess = CBoxedProcessPtr(NewBoxedProcess(ProcessId, pBox.data()));
pBox->m_ProcessList.insert(ProcessId, pProcess);
m_BoxedProxesses.insert(ProcessId, pProcess);
pProcess->InitProcessInfo();
}
if (pProcess->m_ParendPID == 0){
@ -1891,9 +1893,8 @@ bool CSbieAPI::GetMonitor()
CResLogEntryPtr LogEntry = CResLogEntryPtr(new CResLogEntry(pid, type, Data));
QWriteLocker Lock(&m_ResLogMutex);
if (!m_ResLogList.isEmpty() && m_ResLogList.last()->GetValue() == LogEntry->GetValue())
{
m_ResLogList.last()->IncrCounter();
if (!m_ResLogList.isEmpty() && m_ResLogList.last()->Equals(LogEntry)) {
m_ResLogList.last()->Merge(LogEntry);
return true;
}
m_ResLogList.append(LogEntry);

View File

@ -38,9 +38,15 @@ public:
QString GetValue() const { return m_Name; }
QString GetTypeStr() const;
QString GetStautsStr() const;
void IncrCounter() { m_Counter++; }
int GetCount() const { return m_Counter; }
bool Equals(const QSharedDataPointer<CResLogEntry>& pOther) const {
return pOther->m_ProcessId == this->m_ProcessId
//&& pOther->m_Type.Flags == this->m_Type.Flags
&& pOther->m_Name == this->m_Name;
}
void Merge(const QSharedDataPointer<CResLogEntry>& pOther) { m_Counter++; this->m_Type.Flags |= pOther->m_Type.Flags; }
quint64 GetUID() const { return m_uid; }
protected:

View File

@ -45,7 +45,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
@ -346,13 +346,6 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="chkSeparateUserFolders">
<property name="text">
<string>Separate user folders</string>
</property>
</widget>
</item>
<item row="10" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
@ -373,6 +366,20 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="chkSeparateUserFolders">
<property name="text">
<string>Separate user folders</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="chkAutoRoot">
<property name="text">
<string>Portable root folder</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>

View File

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "ResMonModel.h"
#include "../MiscHelpers/Common/Common.h"
#include "../SbiePlusAPI.h"
CResMonModel::CResMonModel(QObject *parent)
:CListItemModel(parent)
@ -93,7 +94,12 @@ void CResMonModel::Sync(const QList<CResLogEntryPtr>& List, QSet<quint64> PIDs)
switch (section)
{
case eProcess: ColValue.Formated = QString::number(pEntry->GetProcessId()); break;
case eProcess:
{
CBoxedProcessPtr pProcess = theAPI->GetProcessById(pEntry->GetProcessId());
ColValue.Formated = QString("%1 (%2)").arg(pProcess.isNull() ? tr("Unknown") : pProcess->GetProcessName()).arg(pEntry->GetProcessId());
break;
}
case eTimeStamp: ColValue.Formated = pEntry->GetTimeStamp().toString("hh:mm:ss.zzz"); break;
//case eType: ColValue.Formated = ; break;
//case eValue: ColValue.Formated = ; break;

View File

@ -66,12 +66,22 @@ bool CSbieModel::TestProcPath(const QList<QVariant>& Path, const QString& BoxNam
return Path.size() == Index;
}
QString CSbieModel__AddGroupMark(const QString& Name)
{
return Name.isEmpty() ? "" : ("!" + Name);
}
QString CSbieModel__RemoveGroupMark(const QString& Name)
{
return Name.left(1) == "!" ? Name.mid(1) : Name;
}
QString CSbieModel::FindParent(const QVariant& Name, const QMap<QString, QStringList>& Groups)
{
for(auto I = Groups.begin(); I != Groups.end(); ++I)
{
if (I.value().contains(Name.toString(), Qt::CaseInsensitive))
return I.key();
if (I.value().contains(CSbieModel__RemoveGroupMark(Name.toString()), Qt::CaseInsensitive))
return CSbieModel__AddGroupMark(I.key());
}
return QString();
}
@ -99,7 +109,7 @@ QList<QVariant> CSbieModel::Sync(const QMap<QString, CSandBoxPtr>& BoxList, cons
{
if (Group.isEmpty())
continue;
QVariant ID = Group;
QVariant ID = CSbieModel__AddGroupMark(Group);
QHash<QVariant, STreeNode*>::iterator I = Old.find(ID);
SSandBoxNode* pNode = I != Old.end() ? static_cast<SSandBoxNode*>(I.value()) : NULL;
@ -299,7 +309,12 @@ bool CSbieModel::Sync(const CSandBoxPtr& pBox, const QList<QVariant>& Path, cons
//case eTitle: break; // todo
//case eLogCount: break; // todo Value = pProcess->GetResourceLog().count(); break;
case eTimeStamp: Value = pProcess->GetTimeStamp(); break;
case ePath: Value = pProcess->GetFileName(); break;
//case ePath: Value = pProcess->GetFileName(); break;
case ePath: {
QString CmdLine = pProcess->GetCommandLine();
Value = CmdLine.isEmpty() ? pProcess->GetFileName() : CmdLine;
break;
}
}
SSandBoxNode::SValue& ColValue = pNode->Values[section];
@ -400,7 +415,7 @@ QVariant CSbieModel::headerData(int section, Qt::Orientation orientation, int ro
//case eTitle: return tr("Title");
//case eLogCount: return tr("Log Count");
case eTimeStamp: return tr("Start Time");
case ePath: return tr("Path");
case ePath: return tr("Path / Command Line");
}
}
return QVariant();

View File

@ -689,9 +689,20 @@ void CSandMan::OnStatusChanged()
{
appTitle.append(tr(" - Portable"));
if (theConf->GetBool("Options/PortableRootDir", true))
int PortableRootDir = theConf->GetInt("Options/PortableRootDir", -1);
if (PortableRootDir == -1)
{
QString BoxPath = QDir::cleanPath(QApplication::applicationDirPath() + "/../SandBoxes").replace("/", "\\");
bool State = false;
PortableRootDir = CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Sandboxie-Plus was started in portable mode, do you want to put the SandBoxes folder into it's parrent directory?")
, tr("Don't show this message again."), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes, QMessageBox::Information) == QDialogButtonBox::Yes ? 1 : 0;
if (State)
theConf->SetValue("Options/PortableRootDir", PortableRootDir);
}
if (PortableRootDir)
{
QString BoxPath = QDir::cleanPath(QApplication::applicationDirPath() + "/../Sandbox/%SANDBOX%").replace("/", "\\");
theAPI->GetGlobalSettings()->SetText("FileRootPath", BoxPath);
}
}
@ -706,6 +717,8 @@ void CSandMan::OnStatusChanged()
}
}
m_pBoxView->Clear();
OnIniReloaded();
if (theConf->GetBool("Options/WatchIni", true))
@ -715,6 +728,8 @@ void CSandMan::OnStatusChanged()
{
appTitle.append(tr(" - NOT connected").arg(theAPI->GetVersion()));
m_pBoxView->Clear();
theAPI->WatchIni(false);
}
this->setWindowTitle(appTitle);
@ -1140,6 +1155,7 @@ void CSandMan::OnResetMsgs()
{
theConf->SetValue("Options/PortableStop", -1);
theConf->SetValue("Options/PortableStart", -1);
theConf->SetValue("Options/PortableRootDir", -1);
theConf->SetValue("Options/CheckForUpdates", 2);

View File

@ -15,7 +15,7 @@
#define VERSION_MJR 0
#define VERSION_MIN 5
#define VERSION_REV 3
#define VERSION_UPD 1
#define VERSION_UPD 2
//#include "../QSbieAPI/SbieAPI.h"
@ -46,6 +46,8 @@ public:
static QIcon GetIcon(const QString& Name);
bool IsFullyPortable();
protected:
SB_STATUS ConnectSbie();
SB_STATUS ConnectSbieImpl();
@ -54,8 +56,6 @@ protected:
static void RecoverFilesAsync(const CSbieProgressPtr& pProgress, const QList<QPair<QString, QString>>& FileList, int Action = 0);
bool IsFullyPortable();
void closeEvent(QCloseEvent *e);
void timerEvent(QTimerEvent* pEvent);
int m_uTimerID;

View File

@ -75,6 +75,11 @@
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(SolutionDir)$(Platform)\$(Configuration)\;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>

View File

@ -135,6 +135,12 @@ CSbieView::~CSbieView()
theConf->SetBlob("MainWindow/BoxTree_Columns", m_pSbieTree->saveState());
}
void CSbieView::Clear()
{
m_Groups.clear();
m_pSbieModel->Clear();
}
void CSbieView::Refresh()
{
QList<QVariant> Added = m_pSbieModel->Sync(theAPI->GetAllBoxes(), m_Groups);
@ -295,7 +301,10 @@ int CSbieView__ParseGroup(const QString& Grouping, QMap<QString, QStringList>& m
if (pos == -1)
break;
if (Grouping.at(pos) == "(")
{
m_Groups[Name] = QStringList();
Index = CSbieView__ParseGroup(Grouping, m_Groups, Name, Index);
}
else if (Grouping.at(pos) == ")")
break;
}
@ -355,8 +364,7 @@ void CSbieView::OnGroupAction()
if (m_pSbieModel->GetType(ModelIndex) == CSbieModel::eGroup)
Parent = m_pSbieModel->GetID(ModelIndex).toString();
if (!Parent.isEmpty())
m_Groups[Parent].append(Name);
m_Groups[Parent].append(Name);
}
else if (Action == m_pDelGroupe)
{

View File

@ -21,6 +21,7 @@ signals:
void RecoveryRequested(const QString& BoxName);
public slots:
void Clear();
void Refresh();
void ReloadGroups();

View File

@ -25,6 +25,8 @@ CNewBoxWindow::CNewBoxWindow(QWidget *parent)
connect(ui.radCopy, SIGNAL(toggled(bool)), this, SLOT(OnPreset()));
ui.radTemplate->setChecked(true);
ui.txtName->setFocus();
restoreGeometry(theConf->GetBlob("NewBoxWindow/Window_Geometry"));
}

View File

@ -1600,6 +1600,8 @@ void COptionsWindow::OnDelAccess()
void COptionsWindow::SaveAccessList()
{
CloseAccessEdit(true);
QStringList Keys = QStringList() << "OpenFilePath" << "OpenPipePath" << "ClosedFilePath" << "ReadFilePath" << "WriteFilePath"
<< "OpenKeyPath" << "ClosedKeyPath" << "ReadKeyPath" << "WriteKeyPath"
<< "OpenIpcPath" << "ClosedIpcPath" << "OpenWinClass" << "OpenClsid" << "ClosedClsid" << "ClosedRT";

View File

@ -112,6 +112,13 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
}
m_WarnProgsChanged = false;
int PortableRootDir = theConf->GetInt("Options/PortableRootDir", -1);
if (PortableRootDir != -1 && theConf->IsPortable())
ui.chkAutoRoot->setChecked(PortableRootDir == 0 ? Qt::Unchecked : Qt::Checked);
else
ui.chkAutoRoot->setVisible(false);
connect(ui.chkAutoRoot, SIGNAL(stateChanged(int)), this, SLOT(OnChange()));
connect(ui.btnAddCompat, SIGNAL(pressed()), this, SLOT(OnAddCompat()));
connect(ui.btnDelCompat, SIGNAL(pressed()), this, SLOT(OnDelCompat()));
@ -190,17 +197,20 @@ void CSettingsWindow::apply()
if (theAPI->IsConnected())
{
if (ui.fileRoot->text().isEmpty())
ui.fileRoot->setText("\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%");
theAPI->GetGlobalSettings()->SetText("FileRootPath", ui.fileRoot->text());
theAPI->GetGlobalSettings()->DelValue("FileRootPath"); //ui.fileRoot->setText("\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%");
else
theAPI->GetGlobalSettings()->SetText("FileRootPath", ui.fileRoot->text());
theAPI->GetGlobalSettings()->SetBool("SeparateUserFolders", ui.chkSeparateUserFolders->isChecked());
if (ui.regRoot->text().isEmpty())
ui.regRoot->setText("\\REGISTRY\\USER\\Sandbox_%USER%_%SANDBOX%");
theAPI->GetGlobalSettings()->SetText("KeyRootPath", ui.regRoot->text());
theAPI->GetGlobalSettings()->DelValue("KeyRootPath"); //ui.regRoot->setText("\\REGISTRY\\USER\\Sandbox_%USER%_%SANDBOX%");
else
theAPI->GetGlobalSettings()->SetText("KeyRootPath", ui.regRoot->text());
if (ui.ipcRoot->text().isEmpty())
ui.ipcRoot->setText("\\Sandbox\\%USER%\\%SANDBOX%\\Session_%SESSION%");
theAPI->GetGlobalSettings()->SetText("IpcRootPath", ui.ipcRoot->text());
theAPI->GetGlobalSettings()->DelValue("IpcRootPath"); //ui.ipcRoot->setText("\\Sandbox\\%USER%\\%SANDBOX%\\Session_%SESSION%");
else
theAPI->GetGlobalSettings()->SetText("IpcRootPath", ui.ipcRoot->text());
theAPI->GetGlobalSettings()->SetBool("EditAdminOnly", ui.chkAdminOnly->isChecked());
@ -262,6 +272,9 @@ void CSettingsWindow::apply()
}
}
if (ui.chkAutoRoot->isVisible())
theConf->SetValue("Options/PortableRootDir", ui.chkAutoRoot->checkState() != Qt::Checked ? 1 : 0);
theConf->SetValue("Options/AutoRunSoftCompat", !ui.chkNoCompat->isChecked());
emit OptionsChanged();
@ -287,6 +300,9 @@ void CSettingsWindow::OnChange()
QStandardItem *item = model->item(0);
item->setFlags((!ui.chkShowTray->isChecked()) ? item->flags() & ~Qt::ItemIsEnabled : item->flags() | Qt::ItemIsEnabled);
if (ui.chkAutoRoot->isVisible() && theGUI->IsFullyPortable())
ui.fileRoot->setEnabled(ui.chkAutoRoot->checkState() != Qt::Checked);
ui.btnSetPassword->setEnabled(ui.chkPassRequired->isChecked());
}