From cf1de5fbdb6f2cc03c48d0719196bbeb0197f357 Mon Sep 17 00:00:00 2001 From: DavidXanatos Date: Fri, 4 Feb 2022 22:08:25 +0100 Subject: [PATCH] 1.0.10 --- SandboxiePlus/QSbieAPI/SbieUtils.cpp | 38 ++- SandboxiePlus/QSbieAPI/SbieUtils.h | 8 +- SandboxiePlus/SandMan/Forms/OptionsWindow.ui | 313 +++++++++++------- SandboxiePlus/SandMan/Forms/SettingsWindow.ui | 108 +++--- SandboxiePlus/SandMan/SandMan.cpp | 39 ++- SandboxiePlus/SandMan/SandMan.h | 2 + SandboxiePlus/SandMan/Views/SbieView.cpp | 4 +- .../SandMan/Windows/NewBoxWindow.cpp | 2 +- .../SandMan/Windows/OptionsAdvanced.cpp | 159 +++++++-- .../SandMan/Windows/OptionsGeneral.cpp | 86 +---- .../SandMan/Windows/OptionsWindow.cpp | 6 +- SandboxiePlus/SandMan/Windows/OptionsWindow.h | 31 +- .../SandMan/Windows/SettingsWindow.cpp | 27 +- .../SandMan/Windows/SettingsWindow.h | 2 + 14 files changed, 521 insertions(+), 304 deletions(-) diff --git a/SandboxiePlus/QSbieAPI/SbieUtils.cpp b/SandboxiePlus/QSbieAPI/SbieUtils.cpp index 651c22d2..abbef2f5 100644 --- a/SandboxiePlus/QSbieAPI/SbieUtils.cpp +++ b/SandboxiePlus/QSbieAPI/SbieUtils.cpp @@ -212,12 +212,12 @@ QString CSbieUtils::GetContextMenuStartCmd() return QString::fromWCharArray(path); } -void CSbieUtils::AddContextMenu(const QString& StartPath, const QString& IconPath) +void CSbieUtils::AddContextMenu(const QString& StartPath, const QString& RunStr, const QString& ExploreStr, const QString& IconPath) { wstring start_path = L"\"" + StartPath.toStdWString() + L"\""; wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\""; - CreateShellEntry(L"*", L"Run &Sandboxed", icon_path, start_path + L" /box:__ask__ \"%1\" %*"); + CreateShellEntry(L"*", L"sandbox", RunStr.toStdWString(), icon_path, start_path + L" /box:__ask__ \"%1\" %*"); wstring explorer_path(512, L'\0'); @@ -242,13 +242,13 @@ void CSbieUtils::AddContextMenu(const QString& StartPath, const QString& IconPat explorer_path.append(L"\\explorer.exe"); } - CreateShellEntry(L"Folder", L"Explore &Sandboxed", icon_path, start_path + L" /box:__ask__ " + explorer_path + L" \"%1\""); + CreateShellEntry(L"Folder", L"sandbox", ExploreStr.toStdWString(), icon_path, start_path + L" /box:__ask__ " + explorer_path + L" \"%1\""); } -void CSbieUtils::CreateShellEntry(const wstring& classname, const wstring& cmdtext, const wstring& iconpath, const wstring& startcmd) +void CSbieUtils::CreateShellEntry(const wstring& classname, const wstring& key, const wstring& cmdtext, const wstring& iconpath, const wstring& startcmd) { HKEY hkey; - LONG rc = RegCreateKeyEx(HKEY_CURRENT_USER, (L"software\\classes\\" + classname + L"\\shell\\sandbox").c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL); + LONG rc = RegCreateKeyEx(HKEY_CURRENT_USER, (L"software\\classes\\" + classname + L"\\shell\\" + key).c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL); if (rc != 0) return; @@ -259,7 +259,7 @@ void CSbieUtils::CreateShellEntry(const wstring& classname, const wstring& cmdte if (rc != 0) return; - rc = RegCreateKeyEx(HKEY_CURRENT_USER, (L"software\\classes\\" + classname + L"\\shell\\sandbox\\command").c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL); + rc = RegCreateKeyEx(HKEY_CURRENT_USER, (L"software\\classes\\" + classname + L"\\shell\\" + key + L"\\command").c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL); if (rc != 0) return; @@ -274,6 +274,32 @@ void CSbieUtils::RemoveContextMenu() RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\folder\\shell\\sandbox"); } +bool CSbieUtils::HasContextMenu2() +{ + const wchar_t* key = L"Software\\Classes\\*\\shell\\unbox\\command"; + HKEY hkey; + LONG rc = RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey); + if (rc != 0) + return false; + + RegCloseKey(hkey); + + return true; +} + +void CSbieUtils::AddContextMenu2(const QString& StartPath, const QString& RunStr, const QString& IconPath) +{ + wstring start_path = L"\"" + StartPath.toStdWString() + L"\""; + wstring icon_path = L"\"" + (IconPath.isEmpty() ? StartPath : IconPath).toStdWString() + L"\",-104"; + + CreateShellEntry(L"*", L"unbox", RunStr.toStdWString(), icon_path, start_path + L" /disable_force \"%1\" %*"); +} + +void CSbieUtils::RemoveContextMenu2() +{ + RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\*\\shell\\unbox"); +} + ////////////////////////////////////////////////////////////////////////////// // Shortcuts diff --git a/SandboxiePlus/QSbieAPI/SbieUtils.h b/SandboxiePlus/QSbieAPI/SbieUtils.h index cfb7fbe1..188dd990 100644 --- a/SandboxiePlus/QSbieAPI/SbieUtils.h +++ b/SandboxiePlus/QSbieAPI/SbieUtils.h @@ -27,9 +27,13 @@ public: static bool IsInstalled(EComponent Component); static QString GetContextMenuStartCmd(); - static void AddContextMenu(const QString& StartPath, const QString& IconPath = QString()); + static void AddContextMenu(const QString& StartPath, const QString& RunStr, const QString& ExploreStr, const QString& IconPath = QString()); static void RemoveContextMenu(); + static bool HasContextMenu2(); + static void AddContextMenu2(const QString& StartPath, const QString& RunStr, const QString& IconPath = QString()); + static void RemoveContextMenu2(); + static bool CreateShortcut(class CSbieAPI* pApi, QString LinkPath, const QString &LinkName, const QString &boxname, const QString &arguments, const QString &iconPath = QString(), int iconIndex = 0, const QString &workdir = QString(), bool bRunElevated = false); static bool GetStartMenuShortcut(class CSbieAPI* pApi, QString &BoxName, QString &LinkPath, QString &IconPath, quint32& IconIndex, QString &WorkDir); @@ -43,7 +47,7 @@ private: static void Install(EComponent Component, QStringList& Ops); static void Uninstall(EComponent Component, QStringList& Ops); - static void CreateShellEntry(const wstring& classname, const wstring& cmdtext, const wstring& iconpath, const wstring& startcmd); + static void CreateShellEntry(const wstring& classname, const wstring& key, const wstring& cmdtext, const wstring& iconpath, const wstring& startcmd); }; diff --git a/SandboxiePlus/SandMan/Forms/OptionsWindow.ui b/SandboxiePlus/SandMan/Forms/OptionsWindow.ui index 0d870332..24b3daa6 100644 --- a/SandboxiePlus/SandMan/Forms/OptionsWindow.ui +++ b/SandboxiePlus/SandMan/Forms/OptionsWindow.ui @@ -7,7 +7,7 @@ 0 0 659 - 479 + 498 @@ -808,107 +808,6 @@ - - - Auto Start - - - - - - Here you can specify programs and/or services that are to be started automatically in the sandbox when it is activated - - - true - - - - - - - - Type - - - - - Program/Service - - - - - - - - - 0 - 0 - - - - - 0 - 23 - - - - Remove - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - - 0 - 23 - - - - Add program - - - - - - - - 0 - 0 - - - - - 0 - 23 - - - - Add service - - - - - @@ -2329,17 +2228,23 @@ The process match level has a higher priority than the specificity and describes - Auto Exec + Triggers - - - - - Add Command + + + + + Qt::Vertical - + + + 20 + 40 + + + - + Qt::Vertical @@ -2352,25 +2257,188 @@ The process match level has a higher priority than the specificity and describes - - + + + + + 0 + 0 + + + + + 0 + 23 + + Remove - - + + + + + Event + + + + + Action + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 23 + + - Here you can specify a list of commands that are executed every time the sandbox is initially populated. + Run Command + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Start Service + + + + + + + This events are executed each time a boxed is started + + + On Box Start + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Run Command + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + This commands are run UNBOXED just before the box content is deleted + + + On Box Delete + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 23 + + + + Run Command + + + + + + + This commands are only executed when a box gets initialized, to have them re-run the box content must be deleted. + + + On Box Init + + + Qt::AlignCenter + + + + + + + Here you can specify actions to be executed automatically on various box events. true - - + + + + Show Templates + + @@ -2715,8 +2783,8 @@ instead of "*". 0 0 - 98 - 28 + 63 + 16 @@ -3054,8 +3122,8 @@ Please note that this values are currently user specific and saved globally for chkNoCopyWarn chkAutoEmpty chkProtectBox - treeAutoStart - btnAddAutoExe + treeTriggers + btnAddAutoRun btnAddAutoSvc btnDelAuto treeGroups @@ -3102,9 +3170,6 @@ Please note that this values are currently user specific and saved globally for tabsAdvanced chkPreferExternalManifest chkNoWindowRename - lstAutoExec - btnAddAutoExec - btnDelAutoExec chkHideOtherBoxes lstProcesses btnAddProcess diff --git a/SandboxiePlus/SandMan/Forms/SettingsWindow.ui b/SandboxiePlus/SandMan/Forms/SettingsWindow.ui index 06b1042a..0e7b84fd 100644 --- a/SandboxiePlus/SandMan/Forms/SettingsWindow.ui +++ b/SandboxiePlus/SandMan/Forms/SettingsWindow.ui @@ -45,7 +45,7 @@ QTabWidget::North - 0 + 1 @@ -229,19 +229,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -256,33 +243,6 @@ - - - - Start UI with Windows - - - - - - - Always use DefaultBox - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -297,10 +257,10 @@ - - + + - Start UI when a sandboxed process is started + Start UI with Windows @@ -311,6 +271,66 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Start UI when a sandboxed process is started + + + + + + + Add 'Run Un-Sandboxed' to the context menu + + + + + + + Always use DefaultBox + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/SandboxiePlus/SandMan/SandMan.cpp b/SandboxiePlus/SandMan/SandMan.cpp index 93ec2467..156d79ef 100644 --- a/SandboxiePlus/SandMan/SandMan.cpp +++ b/SandboxiePlus/SandMan/SandMan.cpp @@ -463,7 +463,7 @@ void CSandMan::CreateMenus() m_pMenuOptions = menuBar()->addMenu(tr("&Options")); m_pMenuSettings = m_pMenuOptions->addAction(CSandMan::GetIcon("Settings"), tr("Global Settings"), this, SLOT(OnSettings())); m_pMenuResetMsgs = m_pMenuOptions->addAction(tr("Reset all hidden messages"), this, SLOT(OnResetMsgs())); - m_pMenuResetGUI = m_pMenuOptions->addAction(tr("Reset all GUI elements"), this, SLOT(OnResetGUI())); + m_pMenuResetGUI = m_pMenuOptions->addAction(tr("Reset all GUI options"), this, SLOT(OnResetGUI())); m_pMenuOptions->addSeparator(); m_pEditIni = m_pMenuOptions->addAction(CSandMan::GetIcon("EditIni"), tr("Edit ini file"), this, SLOT(OnEditIni())); m_pReloadIni = m_pMenuOptions->addAction(CSandMan::GetIcon("ReloadIni"), tr("Reload ini file"), this, SLOT(OnReloadIni())); @@ -881,6 +881,33 @@ void CSandMan::timerEvent(QTimerEvent* pEvent) } } +void CSandMan::DoDeleteCmd(const CSandBoxPtr &pBox) +{ + foreach(const QString& Value, pBox->GetTextList("OnBoxDelete", true, false, true)) { + + QString Value2 = Value; + + QRegExp rx("%([a-zA-Z0-9 ]+)%"); + for(int pos = 0; (pos = rx.indexIn(Value, pos)) != -1; ) { + QString var = rx.cap(1); + QString val; + if (var.compare("Sandbox", Qt::CaseInsensitive) == 0) + val = pBox->GetFileRoot(); + else if (var.compare("SandboxName", Qt::CaseInsensitive) == 0) + val = pBox->GetName(); + else + val = theAPI->SbieIniGet(pBox->GetName(), "%" + var + "%", 0x80000000); // CONF_JUST_EXPAND + Value2.replace("%" + var + "%", val); + pos += rx.matchedLength(); + } + + // todo add progress dialog + QProcess Process; + Process.execute(Value2); + Process.waitForFinished(); + } +} + void CSandMan::OnBoxClosed(const QString& BoxName) { CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); @@ -894,6 +921,8 @@ void CSandMan::OnBoxClosed(const QString& BoxName) if(!theGUI->OpenRecovery(pBox, DeleteShapshots, true)) // unless no files are found than continue silently return; + DoDeleteCmd(pBox); + SB_PROGRESS Status; if (!DeleteShapshots && pBox->HasSnapshots()) { // in auto delete mdoe always return to last snapshot QString Current; @@ -979,10 +1008,8 @@ void CSandMan::OnStatusChanged() theAPI->GetUserSettings()->SetText("SbieCtrl_AutoStartAgent", "SandMan.exe"); QString cmd = CSbieUtils::GetContextMenuStartCmd(); - if (!cmd.isEmpty() && !cmd.contains("sandman.exe", Qt::CaseInsensitive)) { - CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe", - QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); - } + if (!cmd.isEmpty() && !cmd.contains("SandMan.exe", Qt::CaseInsensitive)) + CSettingsWindow__AddContextMenu(); } m_pBoxView->Clear(); @@ -1785,7 +1812,7 @@ void CSandMan::OnResetGUI() LoadState(); - show(); + SafeShow(this); } void CSandMan::OnEditIni() diff --git a/SandboxiePlus/SandMan/SandMan.h b/SandboxiePlus/SandMan/SandMan.h index 9c9d3a00..05869edf 100644 --- a/SandboxiePlus/SandMan/SandMan.h +++ b/SandboxiePlus/SandMan/SandMan.h @@ -38,6 +38,8 @@ public: SB_PROGRESS RecoverFiles(const QList>& FileList, int Action = 0); + void DoDeleteCmd(const CSandBoxPtr &pBox); + bool AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait = false); static QString FormatError(const SB_STATUS& Error); static void CheckResults(QList Results); diff --git a/SandboxiePlus/SandMan/Views/SbieView.cpp b/SandboxiePlus/SandMan/Views/SbieView.cpp index 828a4ae2..2866225d 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.cpp +++ b/SandboxiePlus/SandMan/Views/SbieView.cpp @@ -991,8 +991,10 @@ void CSbieView::OnSandBoxAction(QAction* Action) , tr("Also delete all Snapshots"), &DeleteShapshots, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes) return; - foreach(const CSandBoxPtr & pBox, SandBoxes) + foreach(const CSandBoxPtr &pBox, SandBoxes) { + theGUI->DoDeleteCmd(pBox); + SB_PROGRESS Status; if (!DeleteShapshots && pBox->HasSnapshots()) { QString Default = pBox->GetDefaultSnapshot(); diff --git a/SandboxiePlus/SandMan/Windows/NewBoxWindow.cpp b/SandboxiePlus/SandMan/Windows/NewBoxWindow.cpp index 924c3e4c..1f8c8bb9 100644 --- a/SandboxiePlus/SandMan/Windows/NewBoxWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/NewBoxWindow.cpp @@ -101,7 +101,7 @@ void CNewBoxWindow::CreateBox() pBox->SetBool("NoSecurityIsolation", true); //pBox->SetBool("RunServicesAsSystem", true); pBox->SetBool("UsePrivacyMode", BoxType == CSandBoxPlus::eAppBoxPlus); - pBox->InsertText("Template", "NoUACProxy"); + //pBox->InsertText("Template", "NoUACProxy"); // proxy is always needed for exes in the box break; } } diff --git a/SandboxiePlus/SandMan/Windows/OptionsAdvanced.cpp b/SandboxiePlus/SandMan/Windows/OptionsAdvanced.cpp index 35e8cf79..c3632020 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsAdvanced.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsAdvanced.cpp @@ -48,8 +48,13 @@ void COptionsWindow::CreateAdvanced() connect(ui.chkDbgTrace, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged())); connect(ui.chkErrTrace, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged())); + connect(ui.treeStop, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(OnTriggerChanged(QTreeWidgetItem *, int))); + connect(ui.btnAddAutoRun, SIGNAL(clicked(bool)), this, SLOT(OnAddAutoRun())); + connect(ui.btnAddAutoSvc, SIGNAL(clicked(bool)), this, SLOT(OnAddAutoSvc())); connect(ui.btnAddAutoExec, SIGNAL(clicked(bool)), this, SLOT(OnAddAutoExec())); - connect(ui.btnDelAutoExec, SIGNAL(clicked(bool)), this, SLOT(OnDelAutoExec())); + connect(ui.btnAddDeleteCmd, SIGNAL(clicked(bool)), this, SLOT(OnAddDeleteCmd())); + connect(ui.btnDelAuto, SIGNAL(clicked(bool)), this, SLOT(OnDelAuto())); + connect(ui.chkShowTriggersTmpl, SIGNAL(clicked(bool)), this, SLOT(OnShowTriggersTmpl())); connect(ui.chkHideOtherBoxes, SIGNAL(clicked(bool)), this, SLOT(OnAdvancedChanged())); connect(ui.btnAddProcess, SIGNAL(clicked(bool)), this, SLOT(OnAddProcess())); @@ -85,11 +90,6 @@ void COptionsWindow::LoadAdvanced() ui.chkOpenLsaEndpoint->setChecked(m_pBox->GetBool("OpenLsaEndpoint", false)); - QStringList AutoExec = m_pBox->GetTextList("AutoExec", m_Template); - ui.lstAutoExec->clear(); - ui.lstAutoExec->addItems(AutoExec); - - bool bGlobalNoMon = m_pBox->GetAPI()->GetGlobalSettings()->GetBool("DisableResourceMonitor", false); ui.chkDisableMonitor->setChecked(m_pBox->GetBool("DisableResourceMonitor", bGlobalNoMon)); ReadAdvancedCheck("CallTrace", ui.chkCallTrace, "*"); @@ -106,6 +106,20 @@ void COptionsWindow::LoadAdvanced() if (pBoxPlus) ui.chkApiTrace->setChecked(pBoxPlus->HasLogApi()); + // triggers + ui.treeTriggers->clear(); + foreach(const QString & Value, m_pBox->GetTextList("StartProgram", m_Template)) + AddTriggerItem(Value, eOnStartCmd); + foreach(const QString & Value, m_pBox->GetTextList("StartService", m_Template)) + AddTriggerItem(Value, eOnStartSvc); + foreach(const QString & Value, m_pBox->GetTextList("AutoExec", m_Template)) + AddTriggerItem(Value, eAutoExec); + foreach(const QString & Value, m_pBox->GetTextList("OnBoxDelete", m_Template)) + AddTriggerItem(Value, eDeleteCmd); + + ShowTriggersTmpl(); + // + ui.chkHideOtherBoxes->setChecked(m_pBox->GetBool("HideOtherBoxes", false)); QStringList Processes = m_pBox->GetTextList("HideHostProcess", m_Template); ui.lstProcesses->clear(); @@ -127,6 +141,37 @@ void COptionsWindow::LoadAdvanced() m_AdvancedChanged = false; } +void COptionsWindow::ShowTriggersTmpl(bool bUpdate) +{ + if (ui.chkShowRecoveryTmpl->isChecked()) + { + foreach(const QString& Template, m_pBox->GetTemplates()) + { + foreach(const QString & Value, m_pBox->GetTextListTmpl("StartProgram", Template)) + AddTriggerItem(Value, eOnStartCmd, Template); + foreach(const QString & Value, m_pBox->GetTextListTmpl("StartService", Template)) + AddTriggerItem(Value, eOnStartSvc, Template); + foreach(const QString & Value, m_pBox->GetTextListTmpl("AutoExec", Template)) + AddTriggerItem(Value, eAutoExec, Template); + foreach(const QString & Value, m_pBox->GetTextListTmpl("OnBoxDelete", Template)) + AddTriggerItem(Value, eDeleteCmd, Template); + } + } + else if (bUpdate) + { + for (int i = 0; i < ui.treeRecovery->topLevelItemCount(); ) + { + QTreeWidgetItem* pItem = ui.treeRecovery->topLevelItem(i); + int Type = pItem->data(0, Qt::UserRole).toInt(); + if (Type == -1) { + delete pItem; + continue; // entry from template + } + i++; + } + } +} + void COptionsWindow::SaveAdvanced() { WriteAdvancedCheck(ui.chkPreferExternalManifest, "PreferExternalManifest", "y", ""); @@ -151,11 +196,6 @@ void COptionsWindow::SaveAdvanced() WriteAdvancedCheck(ui.chkOpenLsaEndpoint, "OpenLsaEndpoint", "y", ""); - QStringList AutoExec; - for (int i = 0; i < ui.lstAutoExec->count(); i++) - AutoExec.append(ui.lstAutoExec->item(i)->text()); - WriteTextList("AutoExec", AutoExec); - bool bGlobalNoMon = m_pBox->GetAPI()->GetGlobalSettings()->GetBool("DisableResourceMonitor", false); WriteAdvancedCheck(ui.chkDisableMonitor, "DisableResourceMonitor", bGlobalNoMon ? "" : "y", bGlobalNoMon ? "n" : ""); WriteAdvancedCheck(ui.chkCallTrace, "CallTrace", "*"); @@ -172,6 +212,27 @@ void COptionsWindow::SaveAdvanced() if (pBoxPlus) pBoxPlus->SetLogApi(ui.chkApiTrace->isChecked()); + // triggers + QStringList StartProgram; + QStringList StartService; + QStringList DeleteCommand; + QStringList AutoExec; + for (int i = 0; i < ui.treeTriggers->topLevelItemCount(); i++) { + QTreeWidgetItem* pItem = ui.treeTriggers->topLevelItem(i); + switch (pItem->data(0, Qt::UserRole).toInt()) + { + case eOnStartCmd: StartProgram.append(pItem->text(2)); break; + case eOnStartSvc: StartService.append(pItem->text(2)); break; + case eAutoExec: AutoExec.append(pItem->text(2)); break; + case eDeleteCmd: DeleteCommand.append(pItem->text(2)); break; + } + } + WriteTextList("StartProgram", StartProgram); + WriteTextList("StartService", StartService); + WriteTextList("AutoExec", AutoExec); + WriteTextList("OnBoxDelete", DeleteCommand); + // + WriteAdvancedCheck(ui.chkHideOtherBoxes, "HideOtherBoxes"); QStringList Processes; @@ -264,27 +325,87 @@ void COptionsWindow::OnNoWindowRename() OnOptChanged(); } -void COptionsWindow::OnAddAutoExec() +// triggers +void COptionsWindow::AddTriggerItem(const QString& Value, ETriggerAction Type, const QString& Template) { - QString Process = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter an auto exec command")); - if (Process.isEmpty()) + QTreeWidgetItem* pItem = new QTreeWidgetItem(); + pItem->setData(0, Qt::UserRole, Template.isEmpty() ? Type : -1); + switch (Type) + { + case eOnStartCmd: + pItem->setText(0, tr("On Start")); + pItem->setText(1, tr("Run Command")); + break; + case eOnStartSvc: + pItem->setText(0, tr("On Start")); + pItem->setText(1, tr("Start Service")); + break; + case eAutoExec: + pItem->setText(0, tr("On Init")); + pItem->setText(1, tr("Run Command")); + break; + case eDeleteCmd: + pItem->setText(0, tr("On Delete")); + pItem->setText(1, tr("Run Command")); + break; + } + pItem->setText(2, Value); + pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); + ui.treeTriggers->addTopLevelItem(pItem); +} + +void COptionsWindow::OnAddAutoRun() +{ + QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter the command line to be executed"), QLineEdit::Normal); + if (Value.isEmpty()) return; - ui.lstAutoExec->addItem(Process); - + AddTriggerItem(Value, eOnStartCmd); m_AdvancedChanged = true; OnOptChanged(); } -void COptionsWindow::OnDelAutoExec() +void COptionsWindow::OnAddAutoSvc() { - foreach(QListWidgetItem * pItem, ui.lstAutoExec->selectedItems()) - delete pItem; + QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a service identifier"), QLineEdit::Normal); + if (Value.isEmpty()) + return; + AddTriggerItem(Value, eOnStartSvc); m_AdvancedChanged = true; OnOptChanged(); } +void COptionsWindow::OnAddAutoExec() +{ + QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter the command line to be executed"), QLineEdit::Normal); + if (Value.isEmpty()) + return; + + AddTriggerItem(Value, eAutoExec); + m_AdvancedChanged = true; + OnOptChanged(); +} + +void COptionsWindow::OnAddDeleteCmd() +{ + QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter the command line to be executed"), QLineEdit::Normal); + if (Value.isEmpty()) + return; + + AddTriggerItem(Value, eDeleteCmd); + m_AdvancedChanged = true; + OnOptChanged(); +} + +void COptionsWindow::OnDelAuto() +{ + DeleteAccessEntry(ui.treeTriggers->currentItem()); + m_AdvancedChanged = true; + OnOptChanged(); +} +// + void COptionsWindow::OnAddProcess() { QString Process = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a program file name")); diff --git a/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp b/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp index 8deb1d19..a7986d6a 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsGeneral.cpp @@ -90,14 +90,6 @@ void COptionsWindow::CreateGeneral() ui.btnAddCmd->setPopupMode(QToolButton::MenuButtonPopup); ui.btnAddCmd->setMenu(pRunBtnMenu); connect(ui.btnDelCmd, SIGNAL(clicked(bool)), this, SLOT(OnDelCommand())); - - connect(ui.btnAddAutoExe, SIGNAL(clicked(bool)), this, SLOT(OnAddAutoCmd())); - QMenu* pAutoBtnMenu = new QMenu(ui.btnAddFile); - pAutoBtnMenu->addAction(tr("Browse for Program"), this, SLOT(OnAddAutoExe())); - ui.btnAddAutoExe->setPopupMode(QToolButton::MenuButtonPopup); - ui.btnAddAutoExe->setMenu(pAutoBtnMenu); - connect(ui.btnAddAutoSvc, SIGNAL(clicked(bool)), this, SLOT(OnDelAutoSvc())); - connect(ui.btnDelAuto, SIGNAL(clicked(bool)), this, SLOT(OnDelAuto())); } void COptionsWindow::LoadGeneral() @@ -131,12 +123,6 @@ void COptionsWindow::LoadGeneral() //ui.chkOpenSmartCard->setChecked(m_pBox->GetBool("OpenSmartCard", true)); //ui.chkOpenBluetooth->setChecked(m_pBox->GetBool("OpenBluetooth", false)); - ui.treeAutoStart->clear(); - foreach(const QString & Value, m_pBox->GetTextList("StartCommand", m_Template)) - AddAutoRunItem(Value, 0); - foreach(const QString & Value, m_pBox->GetTextList("StartService", m_Template)) - AddAutoRunItem(Value, 1); - ui.treeRun->clear(); foreach(const QString& Value, m_pBox->GetTextList("RunCommand", m_Template)) { @@ -193,18 +179,6 @@ void COptionsWindow::SaveGeneral() //WriteAdvancedCheck(ui.chkOpenBluetooth, "OpenBluetooth", "y", ""); - QStringList StartProgram; - QStringList StartService; - for (int i = 0; i < ui.treeAutoStart->topLevelItemCount(); i++) { - QTreeWidgetItem* pItem = ui.treeAutoStart->topLevelItem(i); - if (pItem->data(0, Qt::UserRole).toInt()) - StartService.append(pItem->text(1)); - else - StartProgram.append(pItem->text(1)); - } - WriteTextList("StartCommand", StartProgram); - WriteTextList("StartService", StartService); - QStringList RunCommands; for (int i = 0; i < ui.treeRun->topLevelItemCount(); i++) { QTreeWidgetItem* pItem = ui.treeRun->topLevelItem(i); @@ -257,60 +231,6 @@ void COptionsWindow::OnPickColor() ui.btnBorderColor->setStyleSheet("background-color: " + m_BorderColor.name()); } -void COptionsWindow::OnAddAutoCmd() -{ - QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a program path"), QLineEdit::Normal); - if (Value.isEmpty()) - return; - - AddAutoRunItem(Value, 0); - m_GeneralChanged = true; - OnOptChanged(); -} - -void COptionsWindow::OnAddAutoExe() -{ - QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd);;All files (*.*)")).replace("/", "\\"); - if (Value.isEmpty()) - return; - - AddAutoRunItem(Value, 0); - m_GeneralChanged = true; - OnOptChanged(); -} - -void COptionsWindow::OnDelAutoSvc() -{ - QString Value = QInputDialog::getText(this, "Sandboxie-Plus", tr("Please enter a service identifier"), QLineEdit::Normal); - if (Value.isEmpty()) - return; - - AddAutoRunItem(Value, 1); - m_GeneralChanged = true; - OnOptChanged(); -} - -void COptionsWindow::AddAutoRunItem(const QString& Value, int Type) -{ - QTreeWidgetItem* pItem = new QTreeWidgetItem(); - pItem->setText(0, Type ? tr("Service") : tr("Program")); - pItem->setData(0, Qt::UserRole, Type); - pItem->setText(1, Value); - pItem->setFlags(pItem->flags() | Qt::ItemIsEditable); - ui.treeAutoStart->addTopLevelItem(pItem); -} - -void COptionsWindow::OnDelAuto() -{ - QTreeWidgetItem* pItem = ui.treeAutoStart->currentItem(); - if (!pItem) - return; - - delete pItem; - m_GeneralChanged = true; - OnOptChanged(); -} - void COptionsWindow::OnBrowsePath() { QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd)")).replace("/", "\\"); @@ -401,7 +321,7 @@ void COptionsWindow::OnBoxTypChanged() ui.chkMsiExemptions->setChecked(false); //ui.chkRestrictServices->setChecked(true); ui.chkPrivacy->setChecked(BoxType == CSandBoxPlus::eHardenedPlus); - SetTemplate("NoUACProxy", false); + //SetTemplate("NoUACProxy", false); //SetTemplate("DeviceSecurity", true); break; case CSandBoxPlus::eDefaultPlus: @@ -412,7 +332,7 @@ void COptionsWindow::OnBoxTypChanged() ui.chkMsiExemptions->setChecked(false); //ui.chkRestrictServices->setChecked(true); ui.chkPrivacy->setChecked(BoxType == CSandBoxPlus::eDefaultPlus); - SetTemplate("NoUACProxy", false); + //SetTemplate("NoUACProxy", false); //SetTemplate("DeviceSecurity", false); break; case CSandBoxPlus::eAppBoxPlus: @@ -420,7 +340,7 @@ void COptionsWindow::OnBoxTypChanged() ui.chkNoSecurityIsolation->setChecked(true); //ui.chkRestrictServices->setChecked(false); ui.chkPrivacy->setChecked(BoxType == CSandBoxPlus::eAppBoxPlus); - SetTemplate("NoUACProxy", true); + //SetTemplate("NoUACProxy", true); //SetTemplate("DeviceSecurity", false); break; } diff --git a/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp b/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp index 5e7111b6..95f86acf 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp @@ -297,8 +297,8 @@ COptionsWindow::COptionsWindow(const QSharedPointer& pBox, const QStri QByteArray Columns = theConf->GetBlob("OptionsWindow/Run_Columns"); if (!Columns.isEmpty()) ui.treeRun->header()->restoreState(Columns); - Columns = theConf->GetBlob("OptionsWindow/AutoRun_Columns"); - if (!Columns.isEmpty()) ui.treeAutoStart->header()->restoreState(Columns); + Columns = theConf->GetBlob("OptionsWindow/Triggers_Columns"); + if (!Columns.isEmpty()) ui.treeTriggers->header()->restoreState(Columns); Columns = theConf->GetBlob("OptionsWindow/Groups_Columns"); if (!Columns.isEmpty()) ui.treeGroups->header()->restoreState(Columns); Columns = theConf->GetBlob("OptionsWindow/Forced_Columns"); @@ -330,7 +330,7 @@ COptionsWindow::~COptionsWindow() theConf->SetBlob("OptionsWindow/Window_Geometry",saveGeometry()); theConf->SetBlob("OptionsWindow/Run_Columns", ui.treeRun->header()->saveState()); - theConf->SetBlob("OptionsWindow/AutoRun_Columns", ui.treeAutoStart->header()->saveState()); + theConf->SetBlob("OptionsWindow/Triggers_Columns", ui.treeTriggers->header()->saveState()); theConf->SetBlob("OptionsWindow/Groups_Columns", ui.treeGroups->header()->saveState()); theConf->SetBlob("OptionsWindow/Forced_Columns", ui.treeForced->header()->saveState()); theConf->SetBlob("OptionsWindow/Stop_Columns", ui.treeStop->header()->saveState()); diff --git a/SandboxiePlus/SandMan/Windows/OptionsWindow.h b/SandboxiePlus/SandMan/Windows/OptionsWindow.h index 096095e9..8479eca7 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsWindow.h +++ b/SandboxiePlus/SandMan/Windows/OptionsWindow.h @@ -51,11 +51,6 @@ private slots: void OnAddCommand(); void OnDelCommand(); - void OnAddAutoCmd(); - void OnAddAutoExe(); - void OnDelAutoSvc(); - void OnDelAuto(); - void OnAddGroup(); void OnAddProg(); void OnDelProg(); @@ -122,16 +117,23 @@ private slots: void OnDelRecEntry(); void OnShowRecoveryTmpl() { LoadRecoveryListTmpl(true); } + // advanced + void OnNoWindowRename(); + + void OnTriggerChanged() { m_AdvancedChanged = true; OnOptChanged(); } + void OnShowTriggersTmpl() { ShowTriggersTmpl(true); } + void OnAddAutoRun(); + void OnAddAutoSvc(); void OnAddAutoExec(); - void OnDelAutoExec(); + void OnAddDeleteCmd(); + void OnDelAuto(); void OnAddProcess(); void OnDelProcess(); - void OnNoWindowRename(); - void OnAddUser(); void OnDelUser(); + // void OnFilterTemplates() { ShowTemplates(); } void OnTemplateClicked(QTreeWidgetItem* pItem, int Column); @@ -230,6 +232,13 @@ protected: eWriteOnly }; + enum ETriggerAction { + eOnStartCmd, + eOnStartSvc, + eAutoExec, + eDeleteCmd + }; + void SetProgramItem(QString Program, QTreeWidgetItem* pItem, int Column); QString SelectProgram(bool bOrGroup = true); @@ -248,8 +257,6 @@ protected: void SaveConfig(); void UpdateCurrentTab(); - void AddAutoRunItem(const QString& Value, int Type); - void AddRunItem(const QString& Name, const QString& Command); void CreateGeneral(); @@ -324,10 +331,14 @@ protected: void AddRecoveryEntry(const QString& Name, int type, const QString& Template = QString()); void SaveRecoveryList(); + // advanced void CreateAdvanced(); void LoadAdvanced(); void SaveAdvanced(); void UpdateBoxIsolation(); + void ShowTriggersTmpl(bool bUpdate = false); + void AddTriggerItem(const QString& Value, ETriggerAction Type, const QString& Template = QString()); + // void CreateDebug(); void LoadDebug(); diff --git a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp index 3e7ad899..63f5e9e1 100644 --- a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp @@ -203,13 +203,20 @@ void CSettingsWindow::closeEvent(QCloseEvent *e) Qt::CheckState CSettingsWindow__IsContextMenu() { QString cmd = CSbieUtils::GetContextMenuStartCmd(); - if (cmd.contains("sandman.exe", Qt::CaseInsensitive)) + if (cmd.contains("SandMan.exe", Qt::CaseInsensitive)) return Qt::Checked; // set up and sandman if (!cmd.isEmpty()) // ... probably sbiectrl.exe return Qt::PartiallyChecked; return Qt::Unchecked; // not set up } +void CSettingsWindow__AddContextMenu() +{ + CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe", + CSettingsWindow::tr("Run &Sandboxed"), CSettingsWindow::tr("Explore &Sandboxed"), + QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); +} + void CSettingsWindow::LoadSettings() { ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/UiLanguage"))); @@ -230,6 +237,7 @@ void CSettingsWindow::LoadSettings() } ui.chkShellMenu->setCheckState(CSettingsWindow__IsContextMenu()); + ui.chkShellMenu2->setChecked(CSbieUtils::HasContextMenu2()); ui.chkAlwaysDefault->setChecked(theConf->GetBool("Options/RunInDefaultBox", false)); ui.chkDarkTheme->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/UseDarkTheme", 2))); @@ -370,12 +378,21 @@ void CSettingsWindow::SaveSettings() if (ui.chkShellMenu->checkState() != CSettingsWindow__IsContextMenu()) { - if (ui.chkShellMenu->isChecked()) { - CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\SandMan.exe", - QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); - } else + if (ui.chkShellMenu->isChecked()) + CSettingsWindow__AddContextMenu(); + else CSbieUtils::RemoveContextMenu(); } + + if (ui.chkShellMenu2->isChecked() != CSbieUtils::HasContextMenu2()) { + if (ui.chkShellMenu2->isChecked()) { + CSbieUtils::AddContextMenu2(QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe", + tr("Run &Un-Sandboxed"), + QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); + } else + CSbieUtils::RemoveContextMenu2(); + } + theConf->SetValue("Options/RunInDefaultBox", ui.chkAlwaysDefault->isChecked()); theConf->SetValue("Options/ShowNotifications", ui.chkNotifications->isChecked()); diff --git a/SandboxiePlus/SandMan/Windows/SettingsWindow.h b/SandboxiePlus/SandMan/Windows/SettingsWindow.h index 02c3e1d8..7377fab3 100644 --- a/SandboxiePlus/SandMan/Windows/SettingsWindow.h +++ b/SandboxiePlus/SandMan/Windows/SettingsWindow.h @@ -87,6 +87,8 @@ private: Ui::SettingsWindow ui; }; +void CSettingsWindow__AddContextMenu(); + void WindowsMoveFile(const QString& from, const QString& to); extern quint32 g_FeatureFlags;