1.7.0c
This commit is contained in:
parent
75fcd511d7
commit
446fd25eed
|
@ -8,6 +8,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
## [1.7.1 / 5.62.1] - 2022-12-
|
||||
|
||||
### Added
|
||||
- added option to create a new sandbox to run in from the box picker dialog
|
||||
- added sandbox creation wizard (not available in vintage view mode)
|
||||
|
||||
|
||||
### Fixed
|
||||
- fixed BlockNetworkFiles=y not workign tigether with RestrictDevices=y [#2629](https://github.com/sandboxie-plus/Sandboxie/issues/2629)
|
||||
- fixed sandman crash issue introduced in 1.7.0
|
||||
|
@ -18,6 +23,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
## [1.7.0 / 5.62.0] - 2022-12-27
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2022-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2021-2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2021-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2022 David Xanatos, xanasoft.com
|
||||
* Copyright 2022-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>300</height>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -34,30 +34,13 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="7" column="0" colspan="5">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="txtName">
|
||||
<property name="maxLength">
|
||||
<number>32</number>
|
||||
</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="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Box Type Preset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="cmbBoxType"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -71,6 +54,37 @@
|
|||
</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">
|
||||
|
@ -81,13 +95,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<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="1" colspan="3">
|
||||
<widget class="QLabel" name="lblBoxInfo">
|
||||
<property name="text">
|
||||
|
@ -101,13 +108,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>280</width>
|
||||
<height>400</height>
|
||||
<width>263</width>
|
||||
<height>430</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -34,36 +34,10 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Select the sandbox in which to start the program, installer or document.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QTreeWidget" name="treeBoxes">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Sandbox</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="chkAdmin">
|
||||
<property name="text">
|
||||
<string>Run As UAC Administrator</string>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -77,24 +51,53 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QTreeWidget" name="treeBoxes">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Sandbox</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QRadioButton" name="radUnBoxed">
|
||||
<property name="text">
|
||||
<string>Run Outside the Sandbox</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="chkAdmin">
|
||||
<property name="text">
|
||||
<string>Run As UAC Administrator</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Select the sandbox in which to start the program, installer or document.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QRadioButton" name="radBoxedNew">
|
||||
<property name="text">
|
||||
<string>Run in a new Sandboxed</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -31,6 +31,7 @@ HEADERS += ./stdafx.h \
|
|||
./Windows/SelectBoxWindow.h \
|
||||
./Windows/SupportDialog.h\
|
||||
./OnlineUpdater.h \
|
||||
./Wizards/NewBoxWizard.h \
|
||||
./Wizards/SetupWizard.h
|
||||
|
||||
SOURCES += ./main.cpp \
|
||||
|
@ -63,6 +64,7 @@ SOURCES += ./main.cpp \
|
|||
./Windows/SelectBoxWindow.cpp \
|
||||
./Windows/SupportDialog.cpp\
|
||||
./OnlineUpdater.cpp \
|
||||
./Wizards/NewBoxWizard.cpp \
|
||||
./Wizards/SetupWizard.cpp
|
||||
|
||||
FORMS += ./Forms/NewBoxWindow.ui \
|
||||
|
|
|
@ -316,9 +316,11 @@
|
|||
<ClCompile Include="Windows\SettingsWindow.cpp" />
|
||||
<ClCompile Include="Windows\SnapshotsWindow.cpp" />
|
||||
<ClCompile Include="Windows\SupportDialog.cpp" />
|
||||
<ClCompile Include="Wizards\NewBoxWizard.cpp" />
|
||||
<ClCompile Include="Wizards\SetupWizard.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="Wizards\NewBoxWizard.h" />
|
||||
<QtMoc Include="OnlineUpdater.h" />
|
||||
<QtMoc Include="Views\FileView.h" />
|
||||
<QtMoc Include="Windows\SupportDialog.h" />
|
||||
|
|
|
@ -183,6 +183,9 @@
|
|||
<ClCompile Include="Helpers\WinHelper.cpp">
|
||||
<Filter>Helpers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Wizards\NewBoxWizard.cpp">
|
||||
<Filter>Helpers</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
|
@ -283,6 +286,9 @@
|
|||
<QtMoc Include="OnlineUpdater.h">
|
||||
<Filter>SandMan</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Wizards\NewBoxWizard.h">
|
||||
<Filter>Wizards</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRcc Include="Resources\SandMan.qrc">
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../Windows/RecoveryWindow.h"
|
||||
#include "../Windows/NewBoxWindow.h"
|
||||
#include "../Views/FileView.h"
|
||||
#include "../Wizards/NewBoxWizard.h"
|
||||
|
||||
#include "qt_windows.h"
|
||||
#include "qwindowdefs_win.h"
|
||||
|
@ -960,17 +961,24 @@ bool CSbieView::MoveItem(const QString& Name, const QString& To, int pos)
|
|||
|
||||
QString CSbieView::AddNewBox()
|
||||
{
|
||||
CNewBoxWindow NewBoxWindow(this);
|
||||
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
|
||||
NewBoxWindow.setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
|
||||
if (NewBoxWindow.exec() == 1)
|
||||
{
|
||||
QString BoxName;
|
||||
|
||||
bool bVintage = theConf->GetInt("Options/ViewMode", 1) == 2;
|
||||
|
||||
if (bVintage) {
|
||||
CNewBoxWindow NewBoxWindow(this);
|
||||
if (NewBoxWindow.exec() == 1)
|
||||
BoxName = NewBoxWindow.m_Name;
|
||||
}
|
||||
else
|
||||
BoxName = CNewBoxWizard::CreateNewBox(this);
|
||||
|
||||
if (!BoxName.isEmpty()) {
|
||||
theAPI->ReloadBoxes();
|
||||
Refresh();
|
||||
SelectBox(NewBoxWindow.m_Name);
|
||||
return NewBoxWindow.m_Name;
|
||||
SelectBox(BoxName);
|
||||
}
|
||||
return QString();
|
||||
return BoxName;
|
||||
}
|
||||
|
||||
QString CSbieView::AddNewGroup()
|
||||
|
|
|
@ -90,6 +90,7 @@ CSelectBoxWindow::CSelectBoxWindow(const QStringList& Commands, const QString& B
|
|||
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()));
|
||||
|
||||
connect(ui.buttonBox, SIGNAL(accepted()), SLOT(OnRun()));
|
||||
|
@ -162,7 +163,7 @@ void CSelectBoxWindow::closeEvent(QCloseEvent *e)
|
|||
|
||||
void CSelectBoxWindow::OnBoxType()
|
||||
{
|
||||
ui.treeBoxes->setEnabled(!ui.radUnBoxed->isChecked());
|
||||
ui.treeBoxes->setEnabled(ui.radBoxed->isChecked());
|
||||
}
|
||||
|
||||
void CSelectBoxWindow::OnBoxDblClick(QTreeWidgetItem*)
|
||||
|
@ -181,6 +182,14 @@ void CSelectBoxWindow::OnRun()
|
|||
return;
|
||||
pItem = NULL;
|
||||
}
|
||||
else if (ui.radBoxedNew->isChecked())
|
||||
{
|
||||
BoxName = theGUI->GetBoxView()->AddNewBox();
|
||||
if (BoxName.isEmpty()) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (pItem == NULL) {
|
||||
QMessageBox("Sandboxie-Plus", tr("Please select a sandbox."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this).exec();
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,556 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "NewBoxWizard.h"
|
||||
#include "../MiscHelpers/Common/Common.h"
|
||||
#include "../Windows/SettingsWindow.h"
|
||||
#include "../SandMan.h"
|
||||
#include "Helpers/WinAdmin.h"
|
||||
#include <QButtonGroup>
|
||||
#include "../QSbieAPI/SbieUtils.h"
|
||||
#include "../Views/SbieView.h"
|
||||
|
||||
|
||||
CNewBoxWizard::CNewBoxWizard(QWidget *parent)
|
||||
: QWizard(parent)
|
||||
{
|
||||
setPage(Page_Type, new CBoxTypePage);
|
||||
setPage(Page_Files, new CFilesPage);
|
||||
setPage(Page_Advanced, new CAdvancedPage);
|
||||
setPage(Page_Summary, new CSummaryPage);
|
||||
|
||||
m_bAdvanced = false;
|
||||
|
||||
setWizardStyle(ModernStyle);
|
||||
//setOption(HaveHelpButton, true);
|
||||
setPixmap(QWizard::LogoPixmap, QPixmap(":/SandMan.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
connect(this, &QWizard::helpRequested, this, &CNewBoxWizard::showHelp);
|
||||
|
||||
setWindowTitle(tr("New Box Wizard"));
|
||||
}
|
||||
|
||||
void CNewBoxWizard::showHelp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString CNewBoxWizard::CreateNewBox(QWidget* pParent)
|
||||
{
|
||||
CNewBoxWizard wizard(pParent);
|
||||
if (!wizard.exec())
|
||||
return QString();
|
||||
|
||||
QString BoxName = wizard.field("boxName").toString();
|
||||
BoxName.replace(" ", "_");
|
||||
return BoxName;
|
||||
}
|
||||
|
||||
SB_STATUS CNewBoxWizard::TryToCreateBox()
|
||||
{
|
||||
QString BoxName = field("boxName").toString();
|
||||
BoxName.replace(" ", "_");
|
||||
int BoxType = field("boxType").toInt();
|
||||
|
||||
SB_STATUS Status = theAPI->CreateBox(BoxName, true);
|
||||
|
||||
if (!Status.IsError())
|
||||
{
|
||||
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
|
||||
|
||||
switch (BoxType)
|
||||
{
|
||||
case CSandBoxPlus::eHardenedPlus:
|
||||
case CSandBoxPlus::eHardened:
|
||||
pBox->SetBool("UseSecurityMode", true);
|
||||
if(BoxType == CSandBoxPlus::eHardenedPlus)
|
||||
pBox->SetBool("UsePrivacyMode", true);
|
||||
break;
|
||||
case CSandBoxPlus::eDefaultPlus:
|
||||
case CSandBoxPlus::eDefault:
|
||||
pBox->SetBool("UseSecurityMode", false);
|
||||
if(BoxType == CSandBoxPlus::eDefaultPlus)
|
||||
pBox->SetBool("UsePrivacyMode", true);
|
||||
break;
|
||||
case CSandBoxPlus::eAppBoxPlus:
|
||||
case CSandBoxPlus::eAppBox:
|
||||
pBox->SetBool("NoSecurityIsolation", true);
|
||||
if(BoxType == CSandBoxPlus::eAppBoxPlus)
|
||||
pBox->SetBool("UsePrivacyMode", true);
|
||||
//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");
|
||||
|
||||
|
||||
QString Location = field("boxLocation").toString();
|
||||
if (!Location.isEmpty())
|
||||
pBox->SetText("FileRootPath", Location);
|
||||
|
||||
if (field("boxVersion").toInt() == 1) {
|
||||
pBox->SetBool("UseFileDeleteV2", true);
|
||||
pBox->SetBool("UseRegDeleteV2", true);
|
||||
}
|
||||
if(!field("separateUser").toBool())
|
||||
pBox->SetBool("SeparateUserFolders", false);
|
||||
if(field("useVolumeSN").toBool())
|
||||
pBox->SetBool("UseVolumeSerialNumbers", true);
|
||||
|
||||
if(field("autoDelete").toBool())
|
||||
pBox->SetBool("AutoDelete", true);
|
||||
if(field("autoRecover").toBool())
|
||||
pBox->SetBool("AutoRecover", true);
|
||||
|
||||
if (field("blockNetwork").toInt() == 1) // old style
|
||||
pBox->InsertText("AllowNetworkAccess", "!<InternetAccess>,n");
|
||||
else if (field("blockNetwork").toInt() == 2) // WFP
|
||||
pBox->InsertText("ClosedFilePath", "!<InternetAccess>,InternetAccessDevices");
|
||||
pBox->SetBool("BlockNetworkFiles", !field("shareAccess").toBool());
|
||||
|
||||
if(field("fakeAdmin").toBool())
|
||||
pBox->SetBool("FakeAdminRights", true);
|
||||
if(field("msiServer").toBool())
|
||||
pBox->SetBool("MsiInstallerExemptions", true);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
QString CNewBoxWizard::GetDefaultLocation()
|
||||
{
|
||||
QString DefaultPath = theAPI->GetGlobalSettings()->GetText("FileRootPath", "\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%", false, false);
|
||||
// HACK HACK: globally %SANDBOX% evaluates to GlobalSettings
|
||||
DefaultPath.replace("\\GlobalSettings", "\\" + field("boxName").toString());
|
||||
return theAPI->Nt2DosPath(DefaultPath);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBoxTypePage
|
||||
//
|
||||
|
||||
CBoxTypePage::CBoxTypePage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Create new Sandbox"));
|
||||
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/SideLogo.png"));
|
||||
|
||||
m_bInstant = theConf->GetBool("Options/InstantBoxWizard", false);
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
QLabel* pTopLabel = new QLabel(tr("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."));
|
||||
pTopLabel->setWordWrap(true);
|
||||
layout->addWidget(pTopLabel, row++ , 0, 1, 3);
|
||||
|
||||
|
||||
layout->addWidget(new QLabel(tr("Enter box name:")), row++, 0);
|
||||
|
||||
m_pBoxName = new QLineEdit();
|
||||
m_pBoxName->setMaxLength(32);
|
||||
QMap<QString, CSandBoxPtr> Boxes = theAPI->GetAllBoxes();
|
||||
for (int i=0;; i++) {
|
||||
QString NewName = tr("New Box");
|
||||
if (i > 0) NewName.append(" " + QString::number(i));
|
||||
if (Boxes.contains(NewName.toLower().replace(" ", "_")))
|
||||
continue;
|
||||
m_pBoxName->setText(NewName);
|
||||
break;
|
||||
}
|
||||
m_pBoxName->setFocus();
|
||||
layout->addWidget(m_pBoxName, row++, 1, 1, 2);
|
||||
registerField("boxName", m_pBoxName);
|
||||
|
||||
|
||||
layout->addWidget(new QLabel(tr("Sellect box type:")), row++, 0);
|
||||
|
||||
m_pBoxType = new QComboBox();
|
||||
m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eHardenedPlus), tr("Hardened Sandbox with Data Protection"), (int)CSandBoxPlus::eHardenedPlus);
|
||||
m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eHardened), tr("Security Hardened Sandbox"), (int)CSandBoxPlus::eHardened);
|
||||
m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eDefaultPlus), tr("Sandbox with Data Protection"), (int)CSandBoxPlus::eDefaultPlus);
|
||||
m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eDefault), tr("Standard Isolation Sandbox (Default)"), (int)CSandBoxPlus::eDefault);
|
||||
//m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eInsecure), tr("INSECURE Configuration (please change)"), (int)CSandBoxPlus::eInsecure);
|
||||
m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eAppBoxPlus), tr("Application Compartment with Data Protection"), (int)CSandBoxPlus::eAppBoxPlus);
|
||||
m_pBoxType->addItem(theGUI->GetBoxIcon(CSandBoxPlus::eAppBox), tr("Application Compartment (NO Isolation)"), (int)CSandBoxPlus::eAppBox);
|
||||
connect(m_pBoxType, SIGNAL(currentIndexChanged(int)), this, SLOT(OnBoxTypChanged()));
|
||||
layout->addWidget(m_pBoxType, row++, 1, 1, 2);
|
||||
registerField("boxType", m_pBoxType);
|
||||
|
||||
m_pInfoLabel = new QLabel();
|
||||
m_pInfoLabel->setWordWrap(true);
|
||||
layout->addWidget(m_pInfoLabel, row++, 0, 1, 3);
|
||||
|
||||
m_pBoxType->setCurrentIndex(3); // default
|
||||
|
||||
|
||||
|
||||
QWidget* pSpacer = new QWidget();
|
||||
pSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
layout->addWidget(pSpacer, row++, 1);
|
||||
|
||||
m_pAdvanced = new QCheckBox(tr("Configure advanced options"));
|
||||
layout->addWidget(m_pAdvanced, row++, 2);
|
||||
connect(m_pAdvanced, SIGNAL(toggled(bool)), this, SLOT(OnAdvanced()));
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void CBoxTypePage::OnBoxTypChanged()
|
||||
{
|
||||
int BoxType = m_pBoxType->currentData().toInt();
|
||||
|
||||
m_pInfoLabel->setText(theGUI->GetBoxDescription(BoxType));
|
||||
|
||||
if(BoxType != CSandBoxPlus::eDefault)
|
||||
theGUI->CheckCertificate(this);
|
||||
}
|
||||
|
||||
void CBoxTypePage::OnAdvanced()
|
||||
{
|
||||
((CNewBoxWizard*)wizard())->m_bAdvanced = m_pAdvanced->isChecked();
|
||||
if (m_bInstant)
|
||||
{
|
||||
QString BoxName = m_pBoxName->text();
|
||||
int BoxType = m_pBoxType->currentIndex();
|
||||
|
||||
wizard()->restart();
|
||||
|
||||
m_pBoxName->setText(BoxName);
|
||||
m_pBoxType->setCurrentIndex(BoxType);
|
||||
}
|
||||
}
|
||||
|
||||
int CBoxTypePage::nextId() const
|
||||
{
|
||||
if (!m_pAdvanced->isChecked()) {
|
||||
if(m_bInstant)
|
||||
return -1;
|
||||
return CNewBoxWizard::Page_Summary;
|
||||
}
|
||||
return CNewBoxWizard::Page_Files;
|
||||
}
|
||||
|
||||
bool CBoxTypePage::isComplete() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBoxTypePage::validatePage()
|
||||
{
|
||||
QString BoxName = field("boxName").toString();
|
||||
if (!theGUI->GetBoxView()->TestNameAndWarn(BoxName))
|
||||
return false;
|
||||
|
||||
if (m_bInstant && !m_pAdvanced->isChecked())
|
||||
return !((CNewBoxWizard*)wizard())->TryToCreateBox().IsError();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CFilesPage
|
||||
//
|
||||
|
||||
CFilesPage::CFilesPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Sandbox location and behavioure"));
|
||||
setSubTitle(tr("On this page the sandbox location and its behaviorue can be customized.\nYou can use %USER% to save each users sandbox to an own fodler."));
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
|
||||
QLabel* pFileLabel = new QLabel(tr("Sandboxed Files"), this);
|
||||
QFont fnt = pFileLabel->font();
|
||||
fnt.setBold(true);
|
||||
//fnt.setWeight(QFont::DemiBold);
|
||||
pFileLabel->setFont(fnt);
|
||||
layout->addWidget(pFileLabel, row++, 0);
|
||||
layout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2, 1, 1);
|
||||
|
||||
|
||||
// Location
|
||||
QLineEdit* pDummy = new QLineEdit();
|
||||
pDummy->setVisible(false);
|
||||
layout->addWidget(pDummy, row, 0);
|
||||
registerField("boxLocation", pDummy);
|
||||
|
||||
QHBoxLayout* pLayout = new QHBoxLayout();
|
||||
pLayout->setContentsMargins(0,0,0,0);
|
||||
m_pBoxLocation = new QComboBox();
|
||||
m_pBoxLocation->setEditable(true);
|
||||
pLayout->addWidget(m_pBoxLocation);
|
||||
QPushButton* pButton = new QPushButton("...");
|
||||
pButton->setMaximumWidth(25);
|
||||
connect(pButton, &QPushButton::clicked, [&]() {
|
||||
QString FilePath = QFileDialog::getExistingDirectory(this, tr("Select Directory"));
|
||||
if (!FilePath.isEmpty())
|
||||
this->m_pBoxLocation->setCurrentText(FilePath.replace("/", "\\"));
|
||||
});
|
||||
pLayout->addWidget(pButton);
|
||||
layout->addLayout(pLayout, row++, 1, 1, 3);
|
||||
//
|
||||
|
||||
QLabel* pVersionLbl = new QLabel(tr("Virtualization scheme"), this);
|
||||
layout->addWidget(pVersionLbl, row, 1);
|
||||
|
||||
QComboBox* pVersion = new QComboBox();
|
||||
pVersion->addItem(tr("Version 1"));
|
||||
pVersion->addItem(tr("Version 2"));
|
||||
layout->addWidget(pVersion, row++, 2);
|
||||
pVersion->setCurrentIndex(theConf->GetInt("BoxDefaults/BoxScheme", 2) - 1); // V2 default
|
||||
layout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 3, 1, 1);
|
||||
registerField("boxVersion", pVersion);
|
||||
|
||||
QCheckBox* pUserFolders = new QCheckBox(tr("Separate user folders"));
|
||||
pUserFolders->setChecked(theConf->GetBool("BoxDefaults/SeparateUser", true));
|
||||
layout->addWidget(pUserFolders, row++, 2, 1, 2);
|
||||
registerField("separateUser", pUserFolders);
|
||||
|
||||
QCheckBox* pUseVolumeSN = new QCheckBox(tr("Use volume serial numbers for drives"));
|
||||
pUseVolumeSN->setChecked(theConf->GetBool("BoxDefaults/UseVolumeSN", false));
|
||||
layout->addWidget(pUseVolumeSN, row++, 2, 1, 2);
|
||||
registerField("useVolumeSN", pUseVolumeSN);
|
||||
|
||||
QCheckBox* pAutoDelete = new QCheckBox(tr("Auto delete content when last process terminates"));
|
||||
pAutoDelete->setChecked(theConf->GetBool("BoxDefaults/AutoDelete", false));
|
||||
layout->addWidget(pAutoDelete, row++, 1, 1, 3);
|
||||
registerField("autoDelete", pAutoDelete);
|
||||
|
||||
QCheckBox* pAutoRecover = new QCheckBox(tr("Enable Immediate Recovery of files from recovery locations"));
|
||||
pAutoRecover->setChecked(theConf->GetBool("BoxDefaults/AutoRecover", true));
|
||||
layout->addWidget(pAutoRecover, row++, 1, 1, 3);
|
||||
registerField("autoRecover", pAutoRecover);
|
||||
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
|
||||
int size = 16.0;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
size *= (QApplication::desktop()->logicalDpiX() / 96.0); // todo Qt6
|
||||
#endif
|
||||
AddIconToLabel(pFileLabel, CSandMan::GetIcon("Folder").pixmap(size,size));
|
||||
}
|
||||
|
||||
int CFilesPage::nextId() const
|
||||
{
|
||||
return CNewBoxWizard::Page_Advanced;
|
||||
}
|
||||
|
||||
void CFilesPage::initializePage()
|
||||
{
|
||||
m_pBoxLocation->clear();
|
||||
QString Location = theAPI->GetGlobalSettings()->GetText("FileRootPath", "\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%");
|
||||
m_pBoxLocation->addItem(Location/*.replace("%SANDBOX%", field("boxName").toString())*/);
|
||||
}
|
||||
|
||||
bool CFilesPage::validatePage()
|
||||
{
|
||||
QString Location = m_pBoxLocation->currentText();
|
||||
if (Location == m_pBoxLocation->itemText(0))
|
||||
wizard()->setField("boxLocation", "");
|
||||
else {
|
||||
if (Location.mid(2).contains(QRegularExpression("[ <>:\"/\\|?*\\[\\]]"))){
|
||||
QMessageBox::critical(this, "Sandboxie-Plus", tr("The sellected box location is not a valid path."));
|
||||
return false;
|
||||
}
|
||||
QDir Dir(Location);
|
||||
if (Dir.exists() && !Dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries).isEmpty()) {
|
||||
if(QMessageBox::warning(this, "Sandboxie-Plus", tr("The sellected box location exists and is not empty, it is recomended to pick a new or empty folder. "
|
||||
"Are you sure you want to use an existing folder?"), QDialogButtonBox::Yes, QDialogButtonBox::No) != QDialogButtonBox::Yes)
|
||||
return false;
|
||||
}
|
||||
if (!QDir().exists(Location.left(3))) {
|
||||
QMessageBox::critical(this, "Sandboxie-Plus", tr("The sellected box location not placed on a currently available drive."));
|
||||
return false;
|
||||
}
|
||||
wizard()->setField("boxLocation", Location);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CAdvancedPage
|
||||
//
|
||||
|
||||
CAdvancedPage::CAdvancedPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Advanced Sandbox options"));
|
||||
setSubTitle(tr("On this page advanced sandbox options can be configured."));
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
|
||||
QLabel* pNetLabel = new QLabel(tr("Network Access"), this);
|
||||
QFont fnt = pNetLabel->font();
|
||||
fnt.setBold(true);
|
||||
//fnt.setWeight(QFont::DemiBold);
|
||||
pNetLabel->setFont(fnt);
|
||||
layout->addWidget(pNetLabel, row++, 0);
|
||||
|
||||
QComboBox* pNetAccess = new QComboBox();
|
||||
pNetAccess->addItem(tr("Allow network/internet access"));
|
||||
pNetAccess->addItem(tr("Block network/internet by denying access to Network devices"));
|
||||
if (theAPI->GetGlobalSettings()->GetBool("NetworkEnableWFP", false))
|
||||
pNetAccess->addItem(tr("Block network/internet using Windows Filtering Platform"));
|
||||
pNetAccess->setCurrentIndex(theConf->GetInt("BoxDefaults/BlockNetwork", 0));
|
||||
layout->addWidget(pNetAccess, row++, 1, 1, 3);
|
||||
registerField("blockNetwork", pNetAccess);
|
||||
|
||||
m_pShareAccess = new QCheckBox(tr("Allow access to network files and fodlers"));
|
||||
m_pShareAccess->setToolTip(tr("This option is not recomended for Hardened boxes"));
|
||||
m_pShareAccess->setChecked(theConf->GetBool("BoxDefaults/ShareAccess", false));
|
||||
layout->addWidget(m_pShareAccess, row++, 1, 1, 3);
|
||||
registerField("shareAccess", m_pShareAccess);
|
||||
|
||||
|
||||
QLabel* pAdminLabel = new QLabel(tr("Admin Options"), this);
|
||||
pAdminLabel->setFont(fnt);
|
||||
layout->addWidget(pAdminLabel, row++, 0);
|
||||
|
||||
QCheckBox* pFakeAdmin = new QCheckBox(tr("Make applications think they are running elevated"));
|
||||
pFakeAdmin->setChecked(theConf->GetBool("BoxDefaults/FakeAdmin", false));
|
||||
layout->addWidget(pFakeAdmin, row++, 1, 1, 3);
|
||||
registerField("fakeAdmin", pFakeAdmin);
|
||||
|
||||
m_pMSIServer = new QCheckBox(tr("Allow MSIServer to run with a sandboxed system token"));
|
||||
m_pMSIServer->setToolTip(tr("This option is not recomended for Hardened boxes"));
|
||||
m_pMSIServer->setChecked(theConf->GetBool("BoxDefaults/MsiExemptions", false));
|
||||
layout->addWidget(m_pMSIServer, row++, 1, 1, 3);
|
||||
registerField("msiServer", m_pMSIServer);
|
||||
|
||||
setLayout(layout);
|
||||
|
||||
|
||||
int size = 16.0;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
size *= (QApplication::desktop()->logicalDpiX() / 96.0); // todo Qt6
|
||||
#endif
|
||||
AddIconToLabel(pNetLabel, CSandMan::GetIcon("Network").pixmap(size,size));
|
||||
AddIconToLabel(pAdminLabel, CSandMan::GetIcon("Shield9").pixmap(size,size));
|
||||
}
|
||||
|
||||
int CAdvancedPage::nextId() const
|
||||
{
|
||||
return CNewBoxWizard::Page_Summary;
|
||||
}
|
||||
|
||||
void CAdvancedPage::initializePage()
|
||||
{
|
||||
int BoxType = wizard()->field("boxType").toInt();
|
||||
bool bHardened = (BoxType == CSandBoxPlus::eHardenedPlus || BoxType == CSandBoxPlus::eHardened);
|
||||
m_pMSIServer->setEnabled(!bHardened);
|
||||
m_pShareAccess->setEnabled(!bHardened);
|
||||
}
|
||||
|
||||
bool CAdvancedPage::validatePage()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSummaryPage
|
||||
//
|
||||
|
||||
CSummaryPage::CSummaryPage(QWidget *parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
setTitle(tr("Create the new Sandbox"));
|
||||
setPixmap(QWizard::WatermarkPixmap, QPixmap(":/SideLogo.png"));
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
|
||||
QLabel* pLabel = new QLabel;
|
||||
pLabel->setWordWrap(true);
|
||||
pLabel->setText(tr("Almost complete, click Finish to create a new sandbox and conclude the wizard."));
|
||||
layout->addWidget(pLabel, row++ , 0, 1, 3);
|
||||
|
||||
|
||||
m_pSummary = new QTextEdit();
|
||||
m_pSummary->setReadOnly(true);
|
||||
m_pSummary->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
layout->addWidget(m_pSummary, row++ , 0, 1, 3);
|
||||
|
||||
m_pSetDefault = new QCheckBox(tr("Save options as new defaults"));
|
||||
layout->addWidget(m_pSetDefault, row++, 2);
|
||||
|
||||
//QWidget* pSpacer = new QWidget();
|
||||
//pSpacer->setMinimumHeight(16);
|
||||
//layout->addWidget(pSpacer);
|
||||
|
||||
QWidget* pSpacer = new QWidget();
|
||||
pSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
layout->addWidget(pSpacer, row++, 1);
|
||||
|
||||
m_pSetInstant = new QCheckBox(tr("Don't show the summary page in future (unless advanced options were set)"));
|
||||
m_pSetInstant->setChecked(theConf->GetBool("Options/InstantBoxWizard", false));
|
||||
layout->addWidget(m_pSetInstant, row++, 1, 1, 2);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
int CSummaryPage::nextId() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CSummaryPage::initializePage()
|
||||
{
|
||||
m_pSummary->setText(theGUI->GetBoxDescription(wizard()->field("boxType").toInt()));
|
||||
|
||||
QString Location = field("boxLocation").toString();
|
||||
if (Location.isEmpty())
|
||||
Location = ((CNewBoxWizard*)wizard())->GetDefaultLocation();
|
||||
m_pSummary->append(tr("\nThis Sandbox will be saved to: %1").arg(Location));
|
||||
|
||||
if (field("autoDelete").toBool())
|
||||
m_pSummary->append(tr("\nThis box will DISCARD its content when its closed, its suitable only for temporary data."));
|
||||
if (field("blockNetwork").toInt())
|
||||
m_pSummary->append(tr("\nProcesses in this box will not be able to access the internet or the local network, this ensures all accessed data to stay confidential."));
|
||||
if (field("msiServer").toBool())
|
||||
m_pSummary->append(tr("\nThis box will run the MSIServer (*.msi installer service) with a system token, this improves the compatybility but reduces the security isolation."));
|
||||
else if(field("fakeAdmin").toBool())
|
||||
m_pSummary->append(tr("\nProcesses in this box will think they are run with administrative privileges, without actually having them, hence installers can be used even in a security hardened box."));
|
||||
|
||||
m_pSetDefault->setVisible(((CNewBoxWizard*)wizard())->m_bAdvanced);
|
||||
}
|
||||
|
||||
bool CSummaryPage::validatePage()
|
||||
{
|
||||
if (m_pSetDefault->isChecked())
|
||||
{
|
||||
theConf->SetValue("BoxDefaults/BoxScheme", field("boxVersion").toInt() + 1);
|
||||
theConf->SetValue("BoxDefaults/SeparateUser", field("separateUser").toBool());
|
||||
theConf->SetValue("BoxDefaults/UseVolumeSN", field("useVolumeSN").toBool());
|
||||
|
||||
|
||||
theConf->SetValue("BoxDefaults/AutoDelete", field("autoDelete").toBool());
|
||||
theConf->SetValue("BoxDefaults/AutoRecover", field("autoRecover").toBool());
|
||||
|
||||
theConf->SetValue("BoxDefaults/BlockNetwork", field("blockNetwork").toInt());
|
||||
theConf->SetValue("BoxDefaults/ShareAccess", field("shareAccess").toBool());
|
||||
|
||||
theConf->SetValue("BoxDefaults/FakeAdmin", field("fakeAdmin").toBool());
|
||||
theConf->SetValue("BoxDefaults/MsiExemptions", field("msiServer").toBool());
|
||||
}
|
||||
|
||||
theConf->SetValue("Options/InstantBoxWizard", m_pSetInstant->isChecked());
|
||||
|
||||
SB_STATUS Status = ((CNewBoxWizard*)wizard())->TryToCreateBox();
|
||||
if (Status.IsError()) {
|
||||
QMessageBox::critical(this, "Sandboxie-Plus", tr("Failed to create new box: %1").arg(theGUI->FormatError(Status)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWizard>
|
||||
#include "../../QSbieAPI/SbieStatus.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QRadioButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class CNewBoxWizard : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum { Page_Type, Page_Files, Page_Advanced, Page_Summary };
|
||||
|
||||
CNewBoxWizard(QWidget *parent = nullptr);
|
||||
|
||||
static QString CreateNewBox(QWidget* pParent = NULL);
|
||||
|
||||
QString GetDefaultLocation();
|
||||
|
||||
private slots:
|
||||
void showHelp();
|
||||
|
||||
protected:
|
||||
friend class CBoxTypePage;
|
||||
friend class CSummaryPage;
|
||||
|
||||
SB_STATUS TryToCreateBox();
|
||||
|
||||
bool m_bAdvanced;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CBoxTypePage
|
||||
//
|
||||
|
||||
class CBoxTypePage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CBoxTypePage(QWidget *parent = nullptr);
|
||||
|
||||
int nextId() const override;
|
||||
bool isComplete() const override;
|
||||
bool validatePage() override;
|
||||
|
||||
private slots:
|
||||
void OnBoxTypChanged();
|
||||
void OnAdvanced();
|
||||
|
||||
private:
|
||||
QComboBox* m_pBoxType;
|
||||
QLabel* m_pInfoLabel;
|
||||
QLineEdit* m_pBoxName;
|
||||
QCheckBox* m_pAdvanced;
|
||||
|
||||
bool m_bInstant;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CFilesPage
|
||||
//
|
||||
|
||||
class CFilesPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CFilesPage(QWidget *parent = nullptr);
|
||||
|
||||
int nextId() const override;
|
||||
void initializePage() override;
|
||||
bool validatePage() override;
|
||||
|
||||
private:
|
||||
QComboBox* m_pBoxLocation;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CAdvancedPage
|
||||
//
|
||||
|
||||
class CAdvancedPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CAdvancedPage(QWidget *parent = nullptr);
|
||||
|
||||
int nextId() const override;
|
||||
void initializePage() override;
|
||||
bool validatePage() override;
|
||||
|
||||
private:
|
||||
QCheckBox* m_pShareAccess;
|
||||
QCheckBox* m_pMSIServer;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CSummaryPage
|
||||
//
|
||||
|
||||
class CSummaryPage : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CSummaryPage(QWidget *parent = nullptr);
|
||||
|
||||
int nextId() const override;
|
||||
void initializePage() override;
|
||||
bool validatePage() override;
|
||||
|
||||
private:
|
||||
QTextEdit* m_pSummary;
|
||||
QCheckBox* m_pSetDefault;
|
||||
QCheckBox* m_pSetInstant;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue