#include "stdafx.h" #include "SetupWizard.h" #include "../MiscHelpers/Common/Common.h" #include "../Windows/SettingsWindow.h" #include "../SandMan.h" #include "Helpers/WinAdmin.h" #include QString emailRegExp = QStringLiteral(".+@.+"); CSetupWizard::CSetupWizard(QWidget *parent) : QWizard(parent) { 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_Finish, new CFinishPage); setWizardStyle(ModernStyle); //setOption(HaveHelpButton, true); setPixmap(QWizard::LogoPixmap, QPixmap(":/SandMan.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); connect(this, &QWizard::helpRequested, this, &CSetupWizard::showHelp); setWindowTitle(tr("Setup Wizard")); } void CSetupWizard::showHelp() { static QString lastHelpMessage; QString message; switch (currentId()) { case Page_Intro: message = tr("The decision you make here will affect which page you get to see next."); break; default: message = tr("This help is likely not to be of any help."); } if (lastHelpMessage == message) message = tr("Sorry, I already gave all the help I could."); QMessageBox::information(this, tr("Setup Wizard Help"), message); lastHelpMessage = message; } bool CSetupWizard::ShowWizard() { CSetupWizard wizard; if (!wizard.exec()) return false; //bool useBusiness = wizard.field("useBusiness").toBool(); //QString Certificate = wizard.field("useCertificate").toString(); //bool isEvaluate = wizard.field("isEvaluate").toBool(); if (wizard.field("useAdvanced").toBool()) theConf->SetValue("Options/ViewMode", 1); else if (wizard.field("useSimple").toBool()) theConf->SetValue("Options/ViewMode", 0); else if (wizard.field("useClassic").toBool()) theConf->SetValue("Options/ViewMode", 2); if (wizard.field("useBrightMode").toInt()) theConf->SetValue("Options/UseDarkTheme", 0); else if (wizard.field("useDarkMode").toInt()) theConf->SetValue("Options/UseDarkTheme", 1); AutorunEnable(wizard.field("isAutoStart").toBool()); if (wizard.field("useContecxtMenu").toBool()) CSettingsWindow__AddContextMenu(); if (wizard.field("useBrowserIcon").toBool()) CSettingsWindow__AddBrowserIcon(); if (wizard.field("useWFP").toBool()) theAPI->GetGlobalSettings()->SetBool("NetworkEnableWFP", true); if (wizard.field("isUpdate").toBool()) { theConf->SetValue("Options/CheckForUpdates", 1); theConf->SetValue("Options/DownloadUpdates", 1); theConf->SetValue("Options/InstallUpdates", 1); } theConf->SetValue("Options/WizardLevel", 1); theGUI->UpdateSettings(true); return true; } ////////////////////////////////////////////////////////////////////////////////////////// // CIntroPage // CIntroPage::CIntroPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Introduction")); setPixmap(QWizard::WatermarkPixmap, QPixmap(":/SideLogo.png")); QVBoxLayout *layout = new QVBoxLayout; QLabel* pTopLabel = new QLabel(tr("Welcome to the Setup Wizard. This wizard will help you to configure your copy of Sandboxie-Plus. " "You can start this wizard at any time from the Sandbox->Maintenance menu if you do not wish to complete it now.")); pTopLabel->setWordWrap(true); layout->addWidget(pTopLabel); QWidget* pSpace = new QWidget(); pSpace->setMinimumHeight(16); layout->addWidget(pSpace); int BusinessUse = theConf->GetInt("Options/BusinessUse", 2); m_pLabel = new QLabel(tr("Select how you would like to use Sandboxie-Plus")); layout->addWidget(m_pLabel); m_pPersonal = new QRadioButton(tr("&Personally, for private non-commercial use")); layout->addWidget(m_pPersonal); connect(m_pPersonal, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged())); registerField("usePersonal", m_pPersonal); m_pBusiness = new QRadioButton(tr("&Commercially, for business or enterprise use")); layout->addWidget(m_pBusiness); connect(m_pBusiness, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged())); registerField("useBusiness", m_pBusiness); QLabel* pNote = new QLabel(tr("Note: this option is immutable")); layout->addWidget(pNote); if (BusinessUse != 2) { m_pLabel->setEnabled(false); m_pPersonal->setChecked(BusinessUse == 0); m_pPersonal->setEnabled(false); m_pBusiness->setChecked(BusinessUse == 1); m_pBusiness->setEnabled(false); pNote->setEnabled(false); } setLayout(layout); } int CIntroPage::nextId() const { if(g_Certificate.isEmpty()) return CSetupWizard::Page_Certificate; return CSetupWizard::Page_UI; } bool CIntroPage::isComplete() const { if (m_pLabel->isEnabled() && !m_pPersonal->isChecked() && !m_pBusiness->isChecked()) return false; return QWizardPage::isComplete(); } ////////////////////////////////////////////////////////////////////////////////////////// // CCertificatePage // CCertificatePage::CCertificatePage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Install your Sandboxie-Plus support certificate")); setSubTitle(tr("If you have a supporter certificate, please fill it into the field below.")); QGridLayout *layout = new QGridLayout; m_pTopLabel = new QLabel(); m_pTopLabel->setWordWrap(true); connect(m_pTopLabel, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); layout->addWidget(m_pTopLabel); m_pCertificate = new QPlainTextEdit(); m_pCertificate->setMaximumSize(QSize(16777215, 73)); m_pCertificate->setPlaceholderText( "NAME: User Name\n" "LEVEL: ULTIMATE\n" "DATE: dd.mm.yyyy\n" "UPDATEKEY: 00000000000000000000000000000000\n" "SIGNATURE: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" ); layout->addWidget(m_pCertificate); connect(m_pCertificate, SIGNAL(textChanged()), this, SIGNAL(completeChanged())); registerField("useCertificate", m_pCertificate, "plainText"); m_pEvaluate = new QCheckBox(tr("Start evaluation without a certificate for a limited period of time.")); layout->addWidget(m_pEvaluate); connect(m_pEvaluate, SIGNAL(toggled(bool)), this, SIGNAL(completeChanged())); registerField("isEvaluate", m_pEvaluate); layout->addWidget(new QWidget()); setLayout(layout); } void CCertificatePage::initializePage() { m_pCertificate->setPlainText(g_Certificate); if (field("useBusiness").toBool()) { theConf->SetValue("Options/BusinessUse", 1); m_pTopLabel->setText( tr("To use Sandboxie-Plus in a business setting, an appropriate support certificate for business use is required. " "If you do not yet have the required certificate(s), you can get those from the xanasoft.com web shop.") ); m_pEvaluate->setVisible(true); } else { theConf->SetValue("Options/BusinessUse", 0); m_pTopLabel->setText( tr("Sandboxie-Plus provides additional features and box types exclusively to project supporters. " "Boxes like the Privacy Enhanced boxes protect user data from illicit access by the sandboxed programs. " "If you are not yet a supporter, then please consider supporting the project " "to ensure further development of Sandboxie and to receive a supporter certificate.") ); m_pEvaluate->setVisible(false); } } int CCertificatePage::nextId() const { return CSetupWizard::Page_UI; } bool CCertificatePage::isComplete() const { if (field("useBusiness").toBool()) { m_pCertificate->setEnabled(!(m_pEvaluate->isChecked() && m_pEvaluate->isEnabled())); if (m_pCertificate->toPlainText().isEmpty() && !(m_pEvaluate->isChecked() && m_pEvaluate->isEnabled())) return false; } return QWizardPage::isComplete(); } bool CCertificatePage::validatePage() { QByteArray Certificate = m_pCertificate->toPlainText().toLatin1(); if (!m_pEvaluate->isChecked() && !Certificate.isEmpty() && g_Certificate != Certificate) { return CSettingsWindow::ApplyCertificate(Certificate, this); } return true; } ////////////////////////////////////////////////////////////////////////////////////////// // CUIPage // CUIPage::CUIPage(QWidget* parent) : QWizardPage(parent) { setTitle(tr("Configure Sandboxie-Plus UI")); setSubTitle(tr("Select the user interface style you prefer.")); QGridLayout* layout = new QGridLayout; m_pAdvanced = new QRadioButton(tr("&Advanced UI for experts")); m_pAdvanced->setChecked(theConf->GetInt("Options/ViewMode", 1) == 1); layout->addWidget(m_pAdvanced, 0, 0); registerField("useAdvanced", m_pAdvanced); m_pSimple = new QRadioButton(tr("&Simple UI for beginners")); m_pSimple->setChecked(theConf->GetInt("Options/ViewMode", 1) == 0); layout->addWidget(m_pSimple, 1, 0); registerField("useSimple", m_pSimple); m_pClassic = new QRadioButton(tr("&Vintage SbieCtrl.exe UI")); m_pClassic->setChecked(theConf->GetInt("Options/ViewMode", 1) == 2); layout->addWidget(m_pClassic, 2, 0); registerField("useClassic", m_pClassic); QButtonGroup *buttonGroup1 = new QButtonGroup(); buttonGroup1->addButton(m_pAdvanced, 0); buttonGroup1->addButton(m_pSimple, 1); buttonGroup1->addButton(m_pClassic, 2); connect(buttonGroup1, SIGNAL(buttonClicked(int)), this, SLOT(UpdatePreview())); QLabel* pDummy = new QLabel(); pDummy->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); layout->addWidget(pDummy, 0, 1, 6, 4); pDummy->setStyleSheet("QLabel { background-color : " + QApplication::palette().color(QPalette::Base).name() + "; }"); m_pPreview = new QLabel(); m_pPreview->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); m_pPreview->setAlignment(Qt::AlignLeft | Qt::AlignTop); layout->addWidget(m_pPreview, 0, 1, 6, 4); QWidget* pSpacer = new QWidget(); pSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layout->addWidget(pSpacer, 3, 0); m_pBrightMode = new QRadioButton(tr("Use Bright Mode")); layout->addWidget(m_pBrightMode, 4, 0); registerField("useBrightMode", m_pBrightMode); m_pDarkMode = new QRadioButton(tr("Use Dark Mode")); layout->addWidget(m_pDarkMode, 5, 0); registerField("useDarkMode", m_pDarkMode); QButtonGroup *buttonGroup2 = new QButtonGroup(); buttonGroup2->addButton(m_pBrightMode, 0); buttonGroup2->addButton(m_pDarkMode, 1); connect(buttonGroup2, SIGNAL(buttonClicked(int)), this, SLOT(UpdatePreview())); layout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 1, 1, 1); layout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2, 1, 1); layout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 3, 1, 1); layout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 4, 1, 1); setLayout(layout); } void CUIPage::initializePage() { QTimer::singleShot(10, this, SLOT(UpdatePreview())); } void CUIPage::UpdatePreview() { bool bDark; if (m_pDarkMode->isChecked()) bDark = true; else if (m_pBrightMode->isChecked()) bDark = false; else { // same as os QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", QSettings::NativeFormat); bDark = (settings.value("AppsUseLightTheme") == 0); } QPixmap preview; if(m_pAdvanced->isChecked() && !bDark) preview = QPixmap::fromImage(QImage(":/Assets/Advanced.png")); else if(m_pAdvanced->isChecked() && bDark) preview = QPixmap::fromImage(QImage(":/Assets/AdvancedD.png")); else if(m_pSimple->isChecked() && !bDark) preview = QPixmap::fromImage(QImage(":/Assets/Simple.png")); else if(m_pSimple->isChecked() && bDark) preview = QPixmap::fromImage(QImage(":/Assets/SimpleD.png")); else if(m_pClassic->isChecked() && !bDark) preview = QPixmap::fromImage(QImage(":/Assets/Classic.png")); else if(m_pClassic->isChecked() && bDark) preview = QPixmap::fromImage(QImage(":/Assets/ClassicD.png")); //QRect rect(0, 0, m_pPreview->width(), m_pPreview->height()); //m_pPreview->setPixmap(preview.scaled(preview.width()*5/10, preview.height()*5/10, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy(rect)); //m_pPreview->setPixmap(preview.scaled(min(m_pPreview->width(), preview.width()), min(m_pPreview->height(), preview.height()), Qt::KeepAspectRatio, Qt::SmoothTransformation)); //m_pPreview->setPixmap(preview); //m_pPreview->setPixmap(preview.scaled(preview.width()*7/10, preview.height()*7/10, Qt::KeepAspectRatio, Qt::SmoothTransformation)); m_pPreview->setPixmap(preview.scaled(min(preview.width(), max(preview.width()*7/10, m_pPreview->width())), min(preview.height(),max(preview.height()*7/10, m_pPreview->height())), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } int CUIPage::nextId() const { return CSetupWizard::Page_Shell; } ////////////////////////////////////////////////////////////////////////////////////////// // CShellPage // CShellPage::CShellPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Configure Sandboxie-Plus shell integration")); setSubTitle(tr("Configure how Sandboxie-Plus should integrate with your system.")); QVBoxLayout *layout = new QVBoxLayout; m_pAutoStart = new QCheckBox(tr("Start UI with Windows")); m_pAutoStart->setChecked(true); layout->addWidget(m_pAutoStart); registerField("isAutoStart", m_pAutoStart); m_pContecxtMenu = new QCheckBox(tr("Add 'Run Sandboxed' to the explorer context menu")); m_pContecxtMenu->setChecked(true); layout->addWidget(m_pContecxtMenu); registerField("useContecxtMenu", m_pContecxtMenu); m_pBrowserIcon = new QCheckBox(tr("Add desktop shortcut for starting Web browser under Sandboxie")); m_pBrowserIcon->setChecked(true); layout->addWidget(m_pBrowserIcon); registerField("useBrowserIcon", m_pBrowserIcon); setLayout(layout); } int CShellPage::nextId() const { return CSetupWizard::Page_WFP; //return CSetupWizard::Page_Finish; } ////////////////////////////////////////////////////////////////////////////////////////// // CWFPPage // CWFPPage::CWFPPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Configure Sandboxie-Plus network filtering")); setSubTitle(tr("Sandboxie can use the Windows Filtering Platform (WFP) to restrict network access.")); QVBoxLayout *layout = new QVBoxLayout; QLabel* pLabel = new QLabel; pLabel->setWordWrap(true); pLabel->setText(tr("Using WFP allows Sandboxie to reliably enforce IP/Port based rules for network access. " "Unlike system level application firewalls, Sandboxie can use different rules in each box for the same application. " "If you already have a good and reliable application firewall and do not need per box rules, you can leave this option unchecked. " "Without WFP enabled, Sandboxie will still be able to reliably and entirely block processes from accessing the network. " "However, this can cause the process to crash, as the driver blocks the required network device endpoints. " "Even with WFP disabled, Sandboxie offers to set IP/Port based rules, however these will be applied in user mode only and not be enforced by the driver. " "Hence, without WFP enabled, an intentionally malicious process could bypass those rules, but not the entire network block.")); layout->addWidget(pLabel); m_pUseWFP = new QCheckBox(tr("Enable Windows Filtering Platform (WFP) support")); m_pUseWFP->setChecked(theAPI->GetGlobalSettings()->GetBool("NetworkEnableWFP", false)); layout->addWidget(m_pUseWFP); registerField("useWFP", m_pUseWFP); setLayout(layout); } int CWFPPage::nextId() const { return CSetupWizard::Page_Finish; } ////////////////////////////////////////////////////////////////////////////////////////// // CFinishPage // CFinishPage::CFinishPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Complete your configuration")); setPixmap(QWizard::WatermarkPixmap, QPixmap(":/SideLogo.png")); QVBoxLayout *layout = new QVBoxLayout; m_pLabel = new QLabel; m_pLabel->setWordWrap(true); 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); //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); setLayout(layout); } int CFinishPage::nextId() const { return -1; } void CFinishPage::initializePage() { } //void ConclusionPage::setVisible(bool visible) //{ // QWizardPage::setVisible(visible); // // if (visible) { // wizard()->setButtonText(QWizard::CustomButton1, tr("&Print")); // wizard()->setOption(QWizard::HaveCustomButton1, true); // connect(wizard(), &QWizard::customButtonClicked, // this, &ConclusionPage::printButtonClicked); // } else { // wizard()->setOption(QWizard::HaveCustomButton1, false); // disconnect(wizard(), &QWizard::customButtonClicked, // this, &ConclusionPage::printButtonClicked); // } //}