This commit is contained in:
DavidXanatos 2024-07-21 20:41:14 +02:00
parent 05b0ff6302
commit 9360fd5ee7
6 changed files with 289 additions and 171 deletions

View File

@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- added Language Spoof "CustomLCID=1033" [#4024](https://github.com/sandboxie-plus/Sandboxie/pull/4024) (thanks Yeyixiao)
- added option to always run the sandman UI as admin [#4090](https://github.com/sandboxie-plus/Sandboxie/issues/4090)
- added Proxy exclusion [#4036](https://github.com/sandboxie-plus/Sandboxie/issues/4036)
- added "ForceChildren=Program.exe" [#4070](https://github.com/sandboxie-plus/Sandboxie/issues/4070)
### Fixed
- fixed two supporter certificate popping up every time a Sandboxes' settings are opened [#4074](https://github.com/sandboxie-plus/Sandboxie/issues/4074)

View File

@ -43,6 +43,7 @@ typedef struct _FORCE_BOX {
BOX *box;
LIST ForceFolder;
LIST ForceProcess;
LIST ForceChildren;
LIST AlertFolder;
LIST AlertProcess;
LIST HostInjectProcess;
@ -108,12 +109,12 @@ static void Process_GetDocArg(
static BOOLEAN Process_IsDcomLaunchParent(HANDLE ParentId);
static BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId);
//static BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId);
static BOOLEAN Process_IsImmersiveProcess(
PEPROCESS ProcessObject, HANDLE ParentId, ULONG SessionId);
static BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name);
//static BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name);
void Process_CreateForceData(
LIST *boxes, const WCHAR *SidString, ULONG SessionId);
@ -126,7 +127,7 @@ static BOX *Process_CheckForceFolder(
LIST *boxes, const WCHAR *path, BOOLEAN alert, ULONG *IsAlert);
static BOX *Process_CheckForceProcess(
LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, HANDLE parent);
LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, const WCHAR *ParentName);
static void Process_CheckAlertFolder(
LIST *boxes, const WCHAR *path, ULONG *IsAlert);
@ -166,6 +167,11 @@ _FX BOX *Process_GetForcedStartBox(
BOOLEAN dfp_already_added;
BOOLEAN same_image_name;
void* nbuf;
ULONG nlen;
WCHAR* ParentName;
check_force = TRUE;
//
@ -215,6 +221,9 @@ _FX BOX *Process_GetForcedStartBox(
return NULL;
}
Process_GetProcessName(
Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &ParentName);
//
// initialize some more state before checking process
//
@ -261,7 +270,7 @@ _FX BOX *Process_GetForcedStartBox(
if ((! box) && (! alert)) {
box = Process_CheckForceProcess(
&boxes, ImageName, force_alert, &alert, ParentId);
&boxes, ImageName, force_alert, &alert, ParentName);
}
if ((! box) && CurDir && !is_start_exe && (! alert)) {
@ -368,6 +377,9 @@ _FX BOX *Process_GetForcedStartBox(
Process_DeleteForceData(&boxes);
if (nbuf)
Mem_Free(nbuf, nlen);
if (DocArg)
Mem_Free(DocArg, DocArg_len);
@ -795,32 +807,31 @@ _FX BOOLEAN Process_IsDcomLaunchParent(HANDLE ParentId)
//---------------------------------------------------------------------------
// Process_IsProcessParent
//
//---------------------------------------------------------------------------
_FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name)
{
BOOLEAN retval = FALSE;
void* nbuf;
ULONG nlen;
WCHAR* nptr;
Process_GetProcessName(
Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &nptr);
if (nbuf) {
if (_wcsicmp(nptr, Name) == 0) {
retval = TRUE;
}
Mem_Free(nbuf, nlen);
}
return retval;
}
//_FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name)
//{
// BOOLEAN retval = FALSE;
//
// void* nbuf;
// ULONG nlen;
// WCHAR* nptr;
//
// Process_GetProcessName(
// Driver_Pool, (ULONG_PTR)ParentId, &nbuf, &nlen, &nptr);
// if (nbuf) {
//
// if (_wcsicmp(nptr, Name) == 0) {
//
// retval = TRUE;
// }
//
// Mem_Free(nbuf, nlen);
// }
//
// return retval;
//}
//---------------------------------------------------------------------------
@ -828,10 +839,10 @@ _FX BOOLEAN Process_IsProcessParent(HANDLE ParentId, WCHAR* Name)
//---------------------------------------------------------------------------
_FX BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId)
{
return Process_IsProcessParent(ParentId,L"explorer.exe");
}
//_FX BOOLEAN Process_IsWindowsExplorerParent(HANDLE ParentId)
//{
// return Process_IsProcessParent(ParentId,L"explorer.exe");
//}
//---------------------------------------------------------------------------
@ -1112,6 +1123,7 @@ _FX void Process_CreateForceData(
List_Init(&box->ForceFolder);
List_Init(&box->ForceProcess);
List_Init(&box->ForceChildren);
List_Init(&box->AlertFolder);
List_Init(&box->AlertProcess);
List_Init(&box->HostInjectProcess);
@ -1130,6 +1142,12 @@ _FX void Process_CreateForceData(
Process_AddForceProcesses(&box->ForceProcess, L"ForceProcess", section);
//
// scan list of ForceChildren settings for the box
//
Process_AddForceProcesses(&box->ForceChildren, L"ForceChildren", section);
//
// scan list of AlertFolder settings for the box
//
@ -1220,6 +1238,7 @@ _FX void Process_DeleteForceData(LIST *boxes)
Process_DeleteForceDataFolders(&box->ForceFolder);
Process_DeleteForceDataProcesses(&box->ForceProcess);
Process_DeleteForceDataProcesses(&box->ForceChildren);
Process_DeleteForceDataFolders(&box->AlertFolder);
Process_DeleteForceDataProcesses(&box->AlertProcess);
Process_DeleteForceDataProcesses(&box->HostInjectProcess);
@ -1415,7 +1434,7 @@ _FX BOOLEAN Process_CheckForceProcessList(
_FX BOX *Process_CheckForceProcess(
LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, HANDLE ParentId)
LIST *boxes, const WCHAR *name, BOOLEAN alert, ULONG *IsAlert, const WCHAR *ParentName)
{
FORCE_BOX *box;
@ -1435,10 +1454,19 @@ _FX BOX *Process_CheckForceProcess(
return box->box;
}
//if (Process_IsWindowsExplorerParent(ParentId) && Conf_Get_Boolean(box->box->name, L"ForceExplorerChild", 0, FALSE)) {
// if(_wcsicmp(name,L"Sandman.exe")!=0)
// return box->box;
//}
if (ParentName && Process_CheckForceProcessList(box->box, &box->ForceChildren, ParentName) && _wcsicmp(name, L"Sandman.exe") != 0) { // except for sandman exe
if (alert) {
*IsAlert = 1;
return NULL;
}
return box->box;
}
//if (Process_IsWindowsExplorerParent(ParentId) && Conf_Get_Boolean(box->box->name, L"ForceExplorerChild", 0, FALSE)) {
// if (_wcsicmp(name, L"Sandman.exe") != 0)
// return box->box;
//}
box = List_Next(box);
}

View File

@ -45,7 +45,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>3</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
@ -1981,7 +1981,7 @@
<item row="0" column="1">
<widget class="QTabWidget" name="tabsForce">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabForceProgs">
<attribute name="title">
@ -2012,60 +2012,18 @@
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_5">
<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="3" column="1">
<widget class="QToolButton" name="btnForceDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Force Folder</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QCheckBox" name="chkShowForceTmpl">
<property name="text">
<string>Show Templates</string>
</property>
</widget>
</item>
<item row="2" column="0" rowspan="5">
<widget class="QTreeWidget" name="treeForced">
<property name="sortingEnabled">
<bool>true</bool>
<item row="7" column="1">
<widget class="QPushButton" name="btnDelForce">
<property name="text">
<string>Remove</string>
</property>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
</widget>
</item>
<item row="2" column="1">
@ -2087,20 +2045,81 @@
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="btnDelForce">
<property name="text">
<string>Remove</string>
<item row="2" column="0" rowspan="6">
<widget class="QTreeWidget" name="treeForced">
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QCheckBox" name="chkDisableForced">
<property name="text">
<string>Disable forced Process and Folder for this sandbox</string>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_5">
<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="4" column="1">
<widget class="QToolButton" name="btnForceDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Force Folder</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="btnForceChild">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Force Children</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -2124,55 +2143,6 @@
</property>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_55">
<item row="2" column="1">
<widget class="QToolButton" name="btnBreakoutProg">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Breakout Program</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_69">
<property name="text">
<string>Programs entered here will be allowed to break out of this sandbox when they start. It is also possible to capture them into another sandbox, for example to have your web browser always open in a dedicated box.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_26">
<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="5" column="1">
<widget class="QCheckBox" name="chkShowBreakoutTmpl">
<property name="text">
<string>Show Templates</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="lblBreakOut">
<property name="text">
@ -2186,25 +2156,6 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="btnBreakoutDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Breakout Folder</string>
</property>
</widget>
</item>
<item row="2" column="0" rowspan="5">
<widget class="QTreeWidget" name="treeBreakout">
<property name="sortingEnabled">
@ -2222,6 +2173,16 @@
</column>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_69">
<property name="text">
<string>Programs entered here will be allowed to break out of this sandbox when they start. It is also possible to capture them into another sandbox, for example to have your web browser always open in a dedicated box.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="btnDelBreakout">
<property name="text">
@ -2229,6 +2190,64 @@
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="verticalSpacer_26">
<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="1">
<widget class="QToolButton" name="btnBreakoutProg">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Breakout Program</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="chkShowBreakoutTmpl">
<property name="text">
<string>Show Templates</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="btnBreakoutDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>Breakout Folder</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -4684,6 +4703,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
<widget class="QWidget" name="tabHideProc">
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
<kerning>true</kerning>
</font>
@ -4763,6 +4783,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
<widget class="QLabel" name="lblProcessHiding">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
@ -4797,6 +4818,7 @@ This is done to prevent rogue processes inside the sandbox from creating a renam
<widget class="QLabel" name="lblPrivacyProtection">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>

View File

@ -19,6 +19,12 @@ void COptionsWindow::LoadForced()
foreach(const QString& Value, m_pBox->GetTextList("ForceProcessDisabled", m_Template))
AddForcedEntry(Value, (int)eProcess, true);
foreach(const QString& Value, m_pBox->GetTextList("ForceChildren", m_Template))
AddForcedEntry(Value, (int)eParent);
foreach(const QString& Value, m_pBox->GetTextList("ForceChildrenDisabled", m_Template))
AddForcedEntry(Value, (int)eParent, true);
foreach(const QString& Value, m_pBox->GetTextList("ForceFolder", m_Template))
AddForcedEntry(Value, (int)ePath);
@ -41,6 +47,11 @@ void COptionsWindow::LoadForced()
foreach(const QString& Value, m_pBox->GetTextList("BreakoutFolderDisabled", m_Template))
AddBreakoutEntry(Value, (int)ePath, true);
foreach(const QString& Value, m_pBox->GetTextList("BreakoutDocument", m_Template))
AddBreakoutEntry(Value, (int)eText);
foreach(const QString& Value, m_pBox->GetTextList("BreakoutDocumentDisabled", m_Template))
AddBreakoutEntry(Value, (int)eText, true);
LoadForcedTmpl();
LoadBreakoutTmpl();
@ -57,6 +68,9 @@ void COptionsWindow::LoadForcedTmpl(bool bUpdate)
foreach(const QString& Value, m_pBox->GetTextListTmpl("ForceProcess", Template))
AddForcedEntry(Value, (int)eProcess, false, Template);
foreach(const QString& Value, m_pBox->GetTextListTmpl("ForceChildren", Template))
AddForcedEntry(Value, (int)eParent, false, Template);
foreach(const QString& Value, m_pBox->GetTextListTmpl("ForceFolder", Template))
AddForcedEntry(Value, (int)ePath, false, Template);
}
@ -108,9 +122,16 @@ void COptionsWindow::AddForcedEntry(const QString& Name, int type, bool disabled
{
QTreeWidgetItem* pItem = new QTreeWidgetItem();
pItem->setCheckState(0, disabled ? Qt::Unchecked : Qt::Checked);
pItem->setText(0, (type == (int)eProcess ? tr("Process") : tr("Folder")) + (Template.isEmpty() ? "" : (" (" + Template + ")")));
QString Type;
switch (type)
{
case eProcess: Type = tr("Process"); break;
case ePath: Type = tr("Folder"); break;
case eParent: Type = tr("Children"); break;
}
pItem->setText(0, Type + (Template.isEmpty() ? "" : (" (" + Template + ")")));
pItem->setData(0, Qt::UserRole, Template.isEmpty() ? type : (int)eTemplate);
SetProgramItem(Name, pItem, (int)eProcess);
SetProgramItem(Name, pItem, 1);
pItem->setFlags(pItem->flags() | Qt::ItemIsEditable);
ui.treeForced->addTopLevelItem(pItem);
}
@ -119,9 +140,16 @@ void COptionsWindow::AddBreakoutEntry(const QString& Name, int type, bool disabl
{
QTreeWidgetItem* pItem = new QTreeWidgetItem();
pItem->setCheckState(0, disabled ? Qt::Unchecked : Qt::Checked);
pItem->setText(0, (type == (int)eProcess ? tr("Process") : tr("Folder")) + (Template.isEmpty() ? "" : (" (" + Template + ")")));
QString Type;
switch (type)
{
case eProcess: Type = tr("Process"); break;
case ePath: Type = tr("Folder"); break;
}
pItem->setText(0, Type + (Template.isEmpty() ? "" : (" (" + Template + ")")));
pItem->setData(0, Qt::UserRole, Template.isEmpty() ? type : (int)eTemplate);
SetProgramItem(Name, pItem, (int)eProcess);
SetProgramItem(Name, pItem, 1, QString(), type == eProcess);
pItem->setFlags(pItem->flags() | Qt::ItemIsEditable);
ui.treeBreakout->addTopLevelItem(pItem);
}
@ -130,6 +158,8 @@ void COptionsWindow::SaveForced()
{
QStringList ForceProcess;
QStringList ForceProcessDisabled;
QStringList ForceChildren;
QStringList ForceChildrenDisabled;
QStringList ForceFolder;
QStringList ForceFolderDisabled;
@ -143,19 +173,22 @@ void COptionsWindow::SaveForced()
if (pItem->checkState(0) == Qt::Checked) {
switch (Type) {
case eProcess: ForceProcess.append(pItem->data(1, Qt::UserRole).toString()); break;
case ePath: ForceFolder.append(pItem->data(1, Qt::UserRole).toString()); break;
case eParent: ForceChildren.append(pItem->data(1, Qt::UserRole).toString()); break;
case ePath: ForceFolder.append(pItem->data(1, Qt::UserRole).toString()); break;
}
}
else {
switch (Type) {
case eProcess: ForceProcessDisabled.append(pItem->data(1, Qt::UserRole).toString()); break;
case ePath: ForceFolderDisabled.append(pItem->data(1, Qt::UserRole).toString()); break;
case ePath: ForceFolderDisabled.append(pItem->data(1, Qt::UserRole).toString()); break;
}
}
}
WriteTextList("ForceProcess", ForceProcess);
WriteTextList("ForceProcessDisabled", ForceProcessDisabled);
WriteTextList("ForceChildren", ForceChildren);
WriteTextList("ForceChildrenDisabled", ForceChildrenDisabled);
WriteTextList("ForceFolder", ForceFolder);
WriteTextList("ForceFolderDisabled", ForceFolderDisabled);
@ -237,6 +270,28 @@ void COptionsWindow::OnBreakoutBrowse()
OnForcedChanged();
}
void COptionsWindow::OnForceChild()
{
QString Value = SelectProgram();
if (Value.isEmpty())
return;
if (!CheckForcedItem(Value, (int)eParent))
return;
AddForcedEntry(Value, (int)eParent);
OnForcedChanged();
}
void COptionsWindow::OnForceBrowseChild()
{
QString Value = QFileDialog::getOpenFileName(this, tr("Select Executable File"), "", tr("Executable Files (*.exe)"));
if (Value.isEmpty())
return;
if (!CheckForcedItem(Value, (int)eParent))
return;
AddForcedEntry(Split2(Value, "/", true).second, (int)eParent);
OnForcedChanged();
}
void COptionsWindow::OnForceDir()
{
QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
@ -281,7 +336,7 @@ bool COptionsWindow::CheckForcedItem(const QString& Value, int type)
QString winPath = QString::fromUtf8(qgetenv("SystemRoot"));
if (type == eProcess)
if (type == eProcess || type == eParent)
{
if (Value.compare("explorer.exe", Qt::CaseInsensitive) == 0 || Value.compare(winPath + "\\explorer.exe", Qt::CaseInsensitive) == 0)
bDangerous = true;
@ -292,7 +347,7 @@ bool COptionsWindow::CheckForcedItem(const QString& Value, int type)
else if (Value.contains("sandman.exe", Qt::CaseInsensitive))
bDangerous = true;
}
else
else if (type == ePath)
{
if (Value.compare(winPath.left(3), Qt::CaseInsensitive) == 0)
bDangerous = true; // SystemDrive (C:\)

View File

@ -463,9 +463,15 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
// Force
connect(ui.btnForceProg, SIGNAL(clicked(bool)), this, SLOT(OnForceProg()));
QMenu* pFileBtnMenu = new QMenu(ui.btnForceProg);
pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowse()));
pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowseProg()));
ui.btnForceProg->setPopupMode(QToolButton::MenuButtonPopup);
ui.btnForceProg->setMenu(pFileBtnMenu);
connect(ui.btnForceChild, SIGNAL(clicked(bool)), this, SLOT(OnForceChild()));
pFileBtnMenu = new QMenu(ui.btnForceChild);
pFileBtnMenu->addAction(tr("Browse for File"), this, SLOT(OnForceBrowseChild()));
ui.btnForceChild->setPopupMode(QToolButton::MenuButtonPopup);
ui.btnForceChild->setMenu(pFileBtnMenu);
connect(ui.btnForceDir, SIGNAL(clicked(bool)), this, SLOT(OnForceDir()));
connect(ui.btnDelForce, SIGNAL(clicked(bool)), this, SLOT(OnDelForce()));
connect(ui.chkShowForceTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowForceTmpl()));
@ -631,8 +637,11 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
if (iOptionTree == 2)
iOptionTree = iViewMode == 2 ? 1 : 0;
if (iOptionTree)
if (iOptionTree) {
m_HoldChange = true;
OnSetTree();
m_HoldChange = false;
}
else {
//this->setMinimumHeight(490);
this->setMinimumHeight(390);
@ -1193,7 +1202,7 @@ void COptionsWindow::UpdateCurrentTab()
}
else if (m_pCurrentTab == ui.tabDNS || m_pCurrentTab == ui.tabNetProxy)
{
if (!m_pCurrentTab->isEnabled())
if (!m_HoldChange && !m_pCurrentTab->isEnabled())
theGUI->CheckCertificate(this, 2);
}
else if (m_pCurrentTab == ui.tabCOM) {

View File

@ -29,7 +29,8 @@ public:
eProcess,
ePath,
eText,
eTemplate
eTemplate,
eParent
};
signals:
@ -84,7 +85,9 @@ private slots:
void OnGroupsChanged(QTreeWidgetItem* pItem, int Index) { m_GroupsChanged = true; OnOptChanged(); }
void OnForceProg();
void OnForceBrowse();
void OnForceBrowseProg();
void OnForceChild();
void OnForceBrowseChild();
void OnForceDir();
void OnDelForce();
void OnShowForceTmpl() { LoadForcedTmpl(true); }