diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e9f3d5f7..8a1dd93dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.4.1 / 5.43.5] - 2020-09-12 + +### Added +- added core version compatybility check to sandman UI +- added shell integration options to SbiePlus + +### Changed +- SbieCtrl does not longer auto show the tutorian on first start +- when hooking, the to the trampoline migrated section of the original function is not longer noped out +-- it caused issues with unity games, will be investigated and re enabled later + +### Fixed +- fixed color issue with vertical tabs in dark mode +- fixed wrong path separators when adding new forced folders +- fixed directroy listing bug intriduced in 5.43 +- fixed issues with settings window when not being connected to driver +- fixed issue when starting sandman ui as admin +- fixed auto content delete not working with sandman ui + + + ## [0.4.0 / 5.43] - 2020-09-05 ### Added diff --git a/Sandboxie/apps/com/RpcSs/rpcss.c b/Sandboxie/apps/com/RpcSs/rpcss.c index e769ea6961..02c2a8885d 100644 --- a/Sandboxie/apps/com/RpcSs/rpcss.c +++ b/Sandboxie/apps/com/RpcSs/rpcss.c @@ -466,12 +466,12 @@ _FX int __stdcall WinMain( } } - if (1) { + /*if (1) { MSG_HEADER req; req.length = sizeof(req); req.msgid = MSGID_SBIE_INI_RUN_SBIE_CTRL; SbieDll_CallServer(&req); - } + }*/ return DoLingerLeader(); } diff --git a/Sandboxie/apps/control/MyFrame.cpp b/Sandboxie/apps/control/MyFrame.cpp index 9e68376a69..9c11990291 100644 --- a/Sandboxie/apps/control/MyFrame.cpp +++ b/Sandboxie/apps/control/MyFrame.cpp @@ -190,7 +190,7 @@ CMyFrame::CMyFrame(BOOL ForceVisible, BOOL ForceSync) m_view = m_view_old = 0; m_hidden = FALSE; - CUserSettings::GetInstance().GetBool(_ShowWelcome, m_ShowWelcome, TRUE); + //CUserSettings::GetInstance().GetBool(_ShowWelcome, m_ShowWelcome, TRUE); CUserSettings::GetInstance().GetBool(_AlwaysOnTop, m_AlwaysOnTop, FALSE); m_ReSyncShortcuts = ForceSync; @@ -1975,7 +1975,7 @@ void CMyFrame::OnTimer(UINT_PTR nIDEvent) // first time? // - if (m_ShowWelcome && (! inModalState)) { + /*if (m_ShowWelcome && (! inModalState)) { m_ShowWelcome = FALSE; CUserSettings::GetInstance().SetBool(_ShowWelcome, FALSE); @@ -1985,7 +1985,7 @@ void CMyFrame::OnTimer(UINT_PTR nIDEvent) CGettingStartedWizard wizard(this); return; - } + }*/ // // resync shortcuts? usually Sandboxie Control does not resync diff --git a/Sandboxie/apps/control/MyFrame.h b/Sandboxie/apps/control/MyFrame.h index 2c1bb475c9..7dc5618c33 100644 --- a/Sandboxie/apps/control/MyFrame.h +++ b/Sandboxie/apps/control/MyFrame.h @@ -55,7 +55,7 @@ class CMyFrame : public CFrameWnd CPoint m_TrayPoint; BOOL m_hidden; - BOOL m_ShowWelcome; + //BOOL m_ShowWelcome; BOOL m_ReSyncShortcuts; BOOL m_AutoRunSoftCompat; BOOL m_AlwaysOnTop; diff --git a/Sandboxie/common/my_version.h b/Sandboxie/common/my_version.h index 24b24b4f2e..099fffc7bb 100644 --- a/Sandboxie/common/my_version.h +++ b/Sandboxie/common/my_version.h @@ -20,9 +20,9 @@ #ifndef _MY_VERSION_H #define _MY_VERSION_H -#define MY_VERSION_BINARY 5,43 -#define MY_VERSION_STRING "5.43" -#define MY_VERSION_COMPAT "5.43" +#define MY_VERSION_BINARY 5,43,5 +#define MY_VERSION_STRING "5.43.5" +#define MY_VERSION_COMPAT "5.43.5" // These #defines are used by either Resource Compiler, or by NSIC installer #define SBIE_INSTALLER_PATH "..\\Bin\\" diff --git a/Sandboxie/core/dll/dllhook.c b/Sandboxie/core/dll/dllhook.c index 690c1545f2..cffb0c07d1 100644 --- a/Sandboxie/core/dll/dllhook.c +++ b/Sandboxie/core/dll/dllhook.c @@ -435,8 +435,9 @@ skip_e9_rewrite: ; #endif // just in case nop out the rest of the code we moved to the trampoline - for(; UsedCount < ByteCount; UsedCount++) - func[UsedCount] = 0x90; // nop + // ToDo: why does this break unity games + //for(; UsedCount < ByteCount; UsedCount++) + // func[UsedCount] = 0x90; // nop VirtualProtect(&func[-8], 20, prot, &dummy_prot); diff --git a/Sandboxie/core/dll/file_dir.c b/Sandboxie/core/dll/file_dir.c index e42bf8a487..847558e2d8 100644 --- a/Sandboxie/core/dll/file_dir.c +++ b/Sandboxie/core/dll/file_dir.c @@ -309,7 +309,7 @@ _FX NTSTATUS File_NtQueryDirectoryFile( // we get an error return value, and have to add the trailing backslash // - if (status == STATUS_BAD_INITIAL_PC && TruePath) { + if (status == STATUS_BAD_INITIAL_PC && CopyPath) { WCHAR *ptr = TruePath + wcslen(TruePath); ptr[0] = L'\\'; diff --git a/Sandboxie/install/kmdutil/kmdutil.c b/Sandboxie/install/kmdutil/kmdutil.c index 3f26b412cc..9d4f3b7f3d 100644 --- a/Sandboxie/install/kmdutil/kmdutil.c +++ b/Sandboxie/install/kmdutil/kmdutil.c @@ -720,11 +720,15 @@ int __stdcall WinMain( int path_len = wcslen(Driver_Path); if (path_len > 8 && wcscmp(Driver_Path + path_len - 8, L".sys.rc4") == 0) { - FILE* inFile = _wfopen(Driver_Path, L"rb"); + PWSTR Driver_Path_tmp = Driver_Path; // strip \??\ if present + if (Driver_Path_tmp[0] == L'\\' && Driver_Path_tmp[1] == L'?' && Driver_Path_tmp[2] == L'?' && Driver_Path_tmp[3] == L'\\') + Driver_Path_tmp += 4; + + FILE* inFile = _wfopen(Driver_Path_tmp, L"rb"); if (inFile) { - Driver_Path[path_len - 4] = L'\0'; - FILE* outFile = _wfopen(Driver_Path, L"wb"); + Driver_Path_tmp[path_len - 4] = L'\0'; // strip .rc4 + FILE* outFile = _wfopen(Driver_Path_tmp, L"wb"); if (outFile) { fseek(inFile, 0, SEEK_END); diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp index b6915f546d..ece13a2441 100644 --- a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp +++ b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.cpp @@ -35,6 +35,8 @@ CSandBox::CSandBox(const QString& BoxName, class CSbieAPI* pAPI) : CSbieIni(BoxN { //m = new SSandBox; + m_ActiveProcessCount = 0; + // when loading a sandbox that is not initialized, initialize it int cfglvl = GetNum("ConfigLevel"); if (cfglvl >= 7) diff --git a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h index 1f0c91060a..83aa5e88c1 100644 --- a/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h +++ b/SandboxiePlus/QSbieAPI/Sandboxie/SandBox.h @@ -48,6 +48,8 @@ class QSBIEAPI_EXPORT CSandBox : public CSbieIni virtual QMap GetProcessList() const { return m_ProcessList; } + virtual int GetActiveProcessCount() const { return m_ActiveProcessCount; } + virtual SB_STATUS RunStart(const QString& Command); virtual SB_STATUS RunCommand(const QString& Command); virtual SB_STATUS TerminateAll(); @@ -78,6 +80,7 @@ class QSBIEAPI_EXPORT CSandBox : public CSbieIni QString m_IpcPath; QMap m_ProcessList; + int m_ActiveProcessCount; //private: // struct SSandBox* m; diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.cpp b/SandboxiePlus/QSbieAPI/SbieAPI.cpp index 8545d0a77a..d1d4ea4802 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.cpp +++ b/SandboxiePlus/QSbieAPI/SbieAPI.cpp @@ -185,7 +185,7 @@ SB_STATUS CSbieAPI::Connect() if (status != STATUS_SUCCESS) { m->SbieApiHandle = INVALID_HANDLE_VALUE; - return SB_ERR("Failed to connect to driver", status); + return SB_ERR(tr("Failed to connect to driver"), status); } UpdateDriveLetters(); @@ -196,6 +196,17 @@ SB_STATUS CSbieAPI::Connect() m->lastMessageNum = 0; m->lastRecordNum = 0; +#ifndef _DEBUG + QStringList CompatVersions = QStringList () << "5.43" << "5.43.5"; + QString CurVersion = GetVersion(); + if (!CompatVersions.contains(CurVersion)) + { + NtClose(m->SbieApiHandle); + m->SbieApiHandle = INVALID_HANDLE_VALUE; + return SB_ERR(tr("Incompatible Version, found Sandboxie %1, compatible versions: %2").arg(CurVersion).arg(CompatVersions.join(", "))); + } +#endif + m_bTerminate = false; start(); @@ -835,6 +846,11 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox) } } + bool WasBoxClosed = pBox->m_ActiveProcessCount > 0 && boxed_pids[0] == 0; + pBox->m_ActiveProcessCount = boxed_pids[0]; + if (WasBoxClosed) + emit BoxClosed(pBox->GetName()); + return SB_OK; } diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.h b/SandboxiePlus/QSbieAPI/SbieAPI.h index 59a030fa05..14a0792fbe 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.h +++ b/SandboxiePlus/QSbieAPI/SbieAPI.h @@ -136,6 +136,7 @@ class QSBIEAPI_EXPORT CSbieAPI : public QThread void StatusChanged(); void LogMessage(const QString& Message, bool bNotify = true); void FileToRecover(const QString& BoxName, const QString& FilePath); + void BoxClosed(const QString& BoxName); void NotAuthorized(bool bLoginRequired, bool &bRetry); private slots: diff --git a/SandboxiePlus/QSbieAPI/SbieUtils.cpp b/SandboxiePlus/QSbieAPI/SbieUtils.cpp index 79aca3f911..553490a9fb 100644 --- a/SandboxiePlus/QSbieAPI/SbieUtils.cpp +++ b/SandboxiePlus/QSbieAPI/SbieUtils.cpp @@ -109,8 +109,8 @@ SB_STATUS CSbieUtils::Install(EComponent Component) void CSbieUtils::Install(EComponent Component, QStringList& Ops) { QString HomePath = QCoreApplication::applicationDirPath().replace("/", "\\"); // "C:\\Program Files\\Sandboxie " - if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) == 0) - Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIEDRV L"|") + "\"" + HomePath + "\\" + QString::fromWCharArray(SBIEDRV_SYS) + "\"" + "|type=kernel|start=demand|altitude=86900"); + if ((Component & eDriver) != 0 && GetServiceStatus(SBIEDRV) == 0) // todo: why when we are admin we need \??\ and else not and why knd util from console as admin also does not need that??? + Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIEDRV L"|") + "\"\\??\\" + HomePath + "\\" + QString::fromWCharArray(SBIEDRV_SYS) + "\"" + "|type=kernel|start=demand|altitude=86900"); if ((Component & eService) != 0 && GetServiceStatus(SBIESVC) == 0) { Ops.append(QString::fromWCharArray(L"kmdutil.exe|install|" SBIESVC L"|") + "\"" + HomePath + "\\" + QString::fromWCharArray(SBIESVC_EXE) + "\"" + "|type=own|start=auto|display=\"Sandboxie Service\"|group=UIGroup"); Ops.append("reg.exe|ADD|HKLM\\SYSTEM\\ControlSet001\\Services\\SbieSvc|/v|PreferExternalManifest|/t|REG_DWORD|/d|1|/f"); @@ -183,4 +183,95 @@ SB_STATUS CSbieUtils::ExecOps(const QStringList& Ops) return SB_ERR("Failed to execute: " + Args.join(" ")); } return SB_OK; -} \ No newline at end of file +} + +////////////////////////////////////////////////////////////////////////////// +// Shell integration + +int CSbieUtils::IsContextMenu() +{ + if (!CheckRegValue(L"Software\\Classes\\*\\shell\\sandbox\\command")) + return 0; + if (!CheckRegValue(L"software\\classes\\folder\\shell\\sandbox\\command")) + return 1; + return 2; +} + +bool CSbieUtils::CheckRegValue(const wchar_t* key) +{ + HKEY hkey; + LONG rc = RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey); + if (rc != 0) + return false; + + ULONG type; + WCHAR path[512]; + ULONG path_len = sizeof(path) - sizeof(WCHAR) * 4; + rc = RegQueryValueEx(hkey, NULL, NULL, &type, (BYTE *)path, &path_len); + RegCloseKey(hkey); + if (rc != 0) + return false; + + return true; +} + +void CSbieUtils::AddContextMenu(const QString& StartPath) +{ + wstring start_path = L"\"" + StartPath.toStdWString() + L"\""; + + CreateShellEntry(L"*", L"Run &Sandboxed", start_path, start_path + L" /box:__ask__ \"%1\" %*"); + + wstring explorer_path(512, L'\0'); + + HKEY hkeyWinlogon; + LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"software\\microsoft\\windows nt\\currentversion\\winlogon", 0, KEY_READ, &hkeyWinlogon); + if (rc == 0) + { + ULONG path_len = explorer_path.size() * sizeof(WCHAR); + ULONG type; + rc = RegQueryValueEx(hkeyWinlogon, L"Shell", NULL, &type, (BYTE *)explorer_path.c_str(), &path_len); + if (rc == 0 && (type == REG_SZ || type == REG_EXPAND_SZ)) + explorer_path.resize(path_len / sizeof(WCHAR)); + RegCloseKey(hkeyWinlogon); + } + + // get default explorer path + if (*explorer_path.c_str() == L'\0' || _wcsicmp(explorer_path.c_str(), L"explorer.exe") == 0) + { + GetWindowsDirectory((wchar_t*)explorer_path.c_str(), MAX_PATH); + ULONG path_len = wcslen(explorer_path.c_str()); + explorer_path.resize(path_len); + explorer_path.append(L"\\explorer.exe"); + } + + CreateShellEntry(L"Folder", L"Explore &Sandboxed", start_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) +{ + 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); + if (rc != 0) + return; + + RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)cmdtext.c_str(), (cmdtext.length() + 1) * sizeof(WCHAR)); + RegSetValueEx(hkey, L"Icon", 0, REG_SZ, (BYTE *)iconpath.c_str(), (iconpath.length() + 1) * sizeof(WCHAR)); + + RegCloseKey(hkey); + 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); + if (rc != 0) + return; + + RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)startcmd.c_str(), (startcmd.length() + 1) * sizeof(WCHAR)); + + RegCloseKey(hkey); +} + +void CSbieUtils::RemoveContextMenu() +{ + RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\*\\shell\\sandbox"); + RegDeleteTreeW(HKEY_CURRENT_USER, L"software\\classes\\folder\\shell\\sandbox"); +} diff --git a/SandboxiePlus/QSbieAPI/SbieUtils.h b/SandboxiePlus/QSbieAPI/SbieUtils.h index 7c3cc5e011..dc921afb0e 100644 --- a/SandboxiePlus/QSbieAPI/SbieUtils.h +++ b/SandboxiePlus/QSbieAPI/SbieUtils.h @@ -26,6 +26,10 @@ class QSBIEAPI_EXPORT CSbieUtils static SB_STATUS Uninstall(EComponent Component); static bool IsInstalled(EComponent Component); + static int IsContextMenu(); + static void AddContextMenu(const QString& StartPath); + static void RemoveContextMenu(); + private: static SB_STATUS ElevateOps(const QStringList& Ops); static SB_STATUS ExecOps(const QStringList& Ops); @@ -35,5 +39,8 @@ class QSBIEAPI_EXPORT CSbieUtils static void Install(EComponent Component, QStringList& Ops); static void Uninstall(EComponent Component, QStringList& Ops); + + static bool CheckRegValue(const wchar_t* key); + static void CreateShellEntry(const wstring& classname, const wstring& cmdtext, const wstring& iconpath, const wstring& startcmd); }; diff --git a/SandboxiePlus/SandMan/Forms/SettingsWindow.ui b/SandboxiePlus/SandMan/Forms/SettingsWindow.ui index 8ccbc50bf3..b6d427c277 100644 --- a/SandboxiePlus/SandMan/Forms/SettingsWindow.ui +++ b/SandboxiePlus/SandMan/Forms/SettingsWindow.ui @@ -54,40 +54,34 @@ - - - - Qt::Horizontal - - - - 40 - 20 - + + + + Use Dark Theme - + - + Show Sys-Tray - - + + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 40 + 20 - + @@ -117,30 +111,7 @@ - - - - - - - - - - Use Dark Theme - - - - - - - Show Notifications for relevant log Messages - - - false - - - - + On main window close: @@ -150,7 +121,7 @@ - + Qt::Horizontal @@ -163,13 +134,49 @@ - + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Watch Sandboxie.ini for changes + + + + Show Notifications for relevant log Messages + + + false + + + + + + + Add 'Run Sandboxed' to the explorer context menu + + + diff --git a/SandboxiePlus/SandMan/SandMan.cpp b/SandboxiePlus/SandMan/SandMan.cpp index daf1943495..bf67cfccb6 100644 --- a/SandboxiePlus/SandMan/SandMan.cpp +++ b/SandboxiePlus/SandMan/SandMan.cpp @@ -94,6 +94,7 @@ CSandMan::CSandMan(QWidget *parent) theAPI = new CSbiePlusAPI(this); connect(theAPI, SIGNAL(StatusChanged()), this, SLOT(OnStatusChanged())); + connect(theAPI, SIGNAL(BoxClosed(const QString&)), this, SLOT(OnBoxClosed(const QString&))); QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion()); this->setWindowTitle(appTitle); @@ -328,7 +329,10 @@ CSandMan::CSandMan(QWidget *parent) show(); if (CSbieUtils::IsRunning(CSbieUtils::eAll) || theConf->GetBool("Options/StartIfStopped", true)) - ConnectSbie(); + { + SB_STATUS Status = ConnectSbie(); + CheckResults(QList() << Status); + } connect(theAPI, SIGNAL(LogMessage(const QString&, bool)), this, SLOT(OnLogMessage(const QString&, bool))); connect(theAPI, SIGNAL(NotAuthorized(bool, bool&)), this, SLOT(OnNotAuthorized(bool, bool&)), Qt::DirectConnection); @@ -484,6 +488,16 @@ void CSandMan::timerEvent(QTimerEvent* pEvent) OnSelectionChanged(); } +void CSandMan::OnBoxClosed(const QString& BoxName) +{ + CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); + if (pBox && !pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false)) + { + SB_PROGRESS Status = pBox->CleanBox(); + if (Status.GetStatus() == OP_ASYNC) + theGUI->AddAsyncOp(Status.GetValue()); + } +} void CSandMan::OnSelectionChanged() { @@ -681,6 +695,9 @@ SB_STATUS CSandMan::ConnectSbieImpl() if (Status) Status = theAPI->ReloadBoxes(); + if (!Status) + return Status; + if (theAPI->GetAllBoxes().count() == 0) { OnLogMessage(tr("No sandboxes found; creating: %1").arg("DefaultBox")); theAPI->CreateBox("DefaultBox"); diff --git a/SandboxiePlus/SandMan/SandMan.h b/SandboxiePlus/SandMan/SandMan.h index c016b4bfa6..d8a276eace 100644 --- a/SandboxiePlus/SandMan/SandMan.h +++ b/SandboxiePlus/SandMan/SandMan.h @@ -12,7 +12,7 @@ #define VERSION_MJR 0 #define VERSION_MIN 4 -#define VERSION_REV 0 +#define VERSION_REV 1 #define VERSION_UPD 0 @@ -74,6 +74,8 @@ public slots: void OnAsyncMessage(const QString& Text); void OnCancelAsync(); + void OnBoxClosed(const QString& BoxName); + private slots: void OnSelectionChanged(); diff --git a/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp b/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp index 118415e45b..a6c0db1109 100644 --- a/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/OptionsWindow.cpp @@ -9,6 +9,8 @@ class CustomTabStyle : public QProxyStyle { public: + CustomTabStyle(QStyle* style = 0) : QProxyStyle(style) {} + QSize sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const { QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); @@ -48,7 +50,7 @@ COptionsWindow::COptionsWindow(const QSharedPointer& pBox, const QStri this->setWindowTitle(tr("Sandboxie Plus - '%1' Options").arg(Name)); ui.tabs->setTabPosition(QTabWidget::West); - ui.tabs->tabBar()->setStyle(new CustomTabStyle()); + ui.tabs->tabBar()->setStyle(new CustomTabStyle(ui.tabs->tabBar()->style())); if (m_Template) { @@ -638,7 +640,7 @@ void COptionsWindow::OnForceDir() QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")); if (Value.isEmpty()) return; - AddForcedEntry(Value, 2); + AddForcedEntry(Value.replace("/","\\"), 2); m_ForcedChanged = true; } diff --git a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp index b616871bbc..75aec2b434 100644 --- a/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/SettingsWindow.cpp @@ -4,6 +4,7 @@ #include "../MiscHelpers/Common/Settings.h" #include "Helpers/WinAdmin.h" #include "../QSbieAPI/Sandboxie/SbieTemplates.h" +#include "../QSbieAPI/SbieUtils.h" CSettingsWindow::CSettingsWindow(QWidget *parent) @@ -14,7 +15,7 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) this->setCentralWidget(centralWidget); this->setWindowTitle(tr("Sandboxie Plus - Settings")); - ui.uiLang->addItem("International Englisch", ""); + ui.uiLang->addItem("International English", ""); QDir langDir(QApplication::applicationDirPath() + "/translations/"); foreach(const QString& langFile, langDir.entryList(QStringList("taskexplorer_*.qm"), QDir::Files)) { @@ -27,6 +28,8 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) ui.chkAutoStart->setChecked(IsAutorunEnabled()); + ui.chkShellMenu->setCheckState((Qt::CheckState)CSbieUtils::IsContextMenu()); + ui.chkDarkTheme->setChecked(theConf->GetBool("Options/DarkTheme", false)); ui.chkNotifications->setChecked(theConf->GetBool("Options/ShowNotifications", true)); @@ -43,27 +46,47 @@ CSettingsWindow::CSettingsWindow(QWidget *parent) connect(ui.chkShowTray, SIGNAL(stateChanged(int)), this, SLOT(OnChange())); //connect(ui.chkUseCycles, SIGNAL(stateChanged(int)), this, SLOT(OnChange())); - - ui.fileRoot->setText(theAPI->GetGlobalSettings()->GetText("FileRootPath")); - ui.chkSeparateUserFolders->setChecked(theAPI->GetGlobalSettings()->GetBool("SeparateUserFolders", true)); - ui.regRoot->setText(theAPI->GetGlobalSettings()->GetText("KeyRootPath")); - ui.ipcRoot->setText(theAPI->GetGlobalSettings()->GetText("IpcRootPath")); - - ui.chkAdminOnly->setChecked(theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false)); - ui.chkPassRequired->setChecked(!theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty()); - connect(ui.chkPassRequired, SIGNAL(stateChanged(int)), this, SLOT(OnChange())); - connect(ui.btnSetPassword, SIGNAL(pressed()), this, SLOT(OnSetPassword())); - ui.chkAdminOnlyFP->setChecked(theAPI->GetGlobalSettings()->GetBool("ForceDisableAdminOnly", false)); - ui.chkClearPass->setChecked(theAPI->GetGlobalSettings()->GetBool("ForgetPassword", false)); - - connect(ui.btnAddWarnProg, SIGNAL(pressed()), this, SLOT(OnAddWarnProg())); - connect(ui.btnDelWarnProg, SIGNAL(pressed()), this, SLOT(OnDelWarnProg())); - - QStringList WarnProgs = theAPI->GetGlobalSettings()->GetTextList("AlertProcess"); - foreach(const QString& Value, WarnProgs) { - QTreeWidgetItem* pItem = new QTreeWidgetItem(); - pItem->setText(0, Value); - ui.treeWarnProgs->addTopLevelItem(pItem); + if (theAPI->IsConnected()) + { + ui.fileRoot->setText(theAPI->GetGlobalSettings()->GetText("FileRootPath")); + ui.chkSeparateUserFolders->setChecked(theAPI->GetGlobalSettings()->GetBool("SeparateUserFolders", true)); + ui.regRoot->setText(theAPI->GetGlobalSettings()->GetText("KeyRootPath")); + ui.ipcRoot->setText(theAPI->GetGlobalSettings()->GetText("IpcRootPath")); + + ui.chkAdminOnly->setChecked(theAPI->GetGlobalSettings()->GetBool("EditAdminOnly", false)); + ui.chkPassRequired->setChecked(!theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty()); + connect(ui.chkPassRequired, SIGNAL(stateChanged(int)), this, SLOT(OnChange())); + connect(ui.btnSetPassword, SIGNAL(pressed()), this, SLOT(OnSetPassword())); + ui.chkAdminOnlyFP->setChecked(theAPI->GetGlobalSettings()->GetBool("ForceDisableAdminOnly", false)); + ui.chkClearPass->setChecked(theAPI->GetGlobalSettings()->GetBool("ForgetPassword", false)); + + connect(ui.btnAddWarnProg, SIGNAL(pressed()), this, SLOT(OnAddWarnProg())); + connect(ui.btnDelWarnProg, SIGNAL(pressed()), this, SLOT(OnDelWarnProg())); + + QStringList WarnProgs = theAPI->GetGlobalSettings()->GetTextList("AlertProcess"); + foreach(const QString& Value, WarnProgs) { + QTreeWidgetItem* pItem = new QTreeWidgetItem(); + pItem->setText(0, Value); + ui.treeWarnProgs->addTopLevelItem(pItem); + } + } + else + { + ui.fileRoot->setEnabled(false); + ui.chkSeparateUserFolders->setEnabled(false); + ui.regRoot->setEnabled(false); + ui.ipcRoot->setEnabled(false); + ui.chkAdminOnly->setEnabled(false); + ui.chkPassRequired->setEnabled(false); + ui.chkAdminOnlyFP->setEnabled(false); + ui.chkClearPass->setEnabled(false); + ui.btnSetPassword->setEnabled(false); + ui.treeWarnProgs->setEnabled(false); + ui.btnAddWarnProg->setEnabled(false); + ui.btnDelWarnProg->setEnabled(false); + ui.treeCompat->setEnabled(false); + ui.btnAddCompat->setEnabled(false); + ui.btnDelCompat->setEnabled(false); } m_WarnProgsChanged = false; @@ -113,6 +136,14 @@ void CSettingsWindow::apply() AutorunEnable(ui.chkAutoStart->isChecked()); + if (ui.chkShellMenu->checkState() != CSbieUtils::IsContextMenu()) + { + if (ui.chkShellMenu->isChecked()) + CSbieUtils::AddContextMenu(QApplication::applicationDirPath().replace("/", "\\") + "\\Start.exe"); + else + CSbieUtils::RemoveContextMenu(); + } + theConf->SetValue("Options/ShowNotifications", ui.chkNotifications->isChecked()); theConf->SetValue("Options/WatchIni", ui.chkWatchConfig->isChecked()); @@ -121,65 +152,69 @@ void CSettingsWindow::apply() theConf->SetValue("Options/ShowSysTray", ui.chkShowTray->isChecked()); - if (ui.fileRoot->text().isEmpty()) - ui.fileRoot->setText("\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%"); - theAPI->GetGlobalSettings()->SetText("FileRootPath", ui.fileRoot->text()); - theAPI->GetGlobalSettings()->SetBool("SeparateUserFolders", ui.chkSeparateUserFolders->isChecked()); - if (ui.regRoot->text().isEmpty()) - ui.regRoot->setText("\\REGISTRY\\USER\\Sandbox_%USER%_%SANDBOX%"); - theAPI->GetGlobalSettings()->SetText("KeyRootPath", ui.regRoot->text()); + if (theAPI->IsConnected()) + { + if (ui.fileRoot->text().isEmpty()) + ui.fileRoot->setText("\\??\\%SystemDrive%\\Sandbox\\%USER%\\%SANDBOX%"); + theAPI->GetGlobalSettings()->SetText("FileRootPath", ui.fileRoot->text()); + theAPI->GetGlobalSettings()->SetBool("SeparateUserFolders", ui.chkSeparateUserFolders->isChecked()); - if (ui.ipcRoot->text().isEmpty()) - ui.ipcRoot->setText("\\Sandbox\\%USER%\\%SANDBOX%\\Session_%SESSION%"); - theAPI->GetGlobalSettings()->SetText("IpcRootPath", ui.ipcRoot->text()); + if (ui.regRoot->text().isEmpty()) + ui.regRoot->setText("\\REGISTRY\\USER\\Sandbox_%USER%_%SANDBOX%"); + theAPI->GetGlobalSettings()->SetText("KeyRootPath", ui.regRoot->text()); + if (ui.ipcRoot->text().isEmpty()) + ui.ipcRoot->setText("\\Sandbox\\%USER%\\%SANDBOX%\\Session_%SESSION%"); + theAPI->GetGlobalSettings()->SetText("IpcRootPath", ui.ipcRoot->text()); - theAPI->GetGlobalSettings()->SetBool("EditAdminOnly", ui.chkAdminOnly->isChecked()); - bool isPassSet = !theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty(); - if (ui.chkPassRequired->isChecked()) - { - if (!isPassSet && m_NewPassword.isEmpty()) - OnSetPassword(); // request password entry if it wasn't already - if (!m_NewPassword.isEmpty()) { - theAPI->LockConfig(m_NewPassword); // set new/changed password - m_NewPassword.clear(); - } - } - else if (isPassSet) - theAPI->LockConfig(QString()); // clear password + theAPI->GetGlobalSettings()->SetBool("EditAdminOnly", ui.chkAdminOnly->isChecked()); - theAPI->GetGlobalSettings()->SetBool("ForceDisableAdminOnly", ui.chkAdminOnlyFP->isChecked()); - theAPI->GetGlobalSettings()->SetBool("ForgetPassword", ui.chkClearPass->isChecked()); - - if (m_WarnProgsChanged) - { - QStringList WarnProgs; - for (int i = 0; i < ui.treeWarnProgs->topLevelItemCount(); i++) { - QTreeWidgetItem* pItem = ui.treeWarnProgs->topLevelItem(i); - WarnProgs.append(pItem->text(0)); + bool isPassSet = !theAPI->GetGlobalSettings()->GetText("EditPassword", "").isEmpty(); + if (ui.chkPassRequired->isChecked()) + { + if (!isPassSet && m_NewPassword.isEmpty()) + OnSetPassword(); // request password entry if it wasn't already + if (!m_NewPassword.isEmpty()) { + theAPI->LockConfig(m_NewPassword); // set new/changed password + m_NewPassword.clear(); + } } + else if (isPassSet) + theAPI->LockConfig(QString()); // clear password - theAPI->GetGlobalSettings()->UpdateTextList("AlertProcess", WarnProgs); - m_WarnProgsChanged = false; - } + theAPI->GetGlobalSettings()->SetBool("ForceDisableAdminOnly", ui.chkAdminOnlyFP->isChecked()); + theAPI->GetGlobalSettings()->SetBool("ForgetPassword", ui.chkClearPass->isChecked()); - if (m_CompatChanged) - { - QStringList Used; - QStringList Rejected; - for (int i = 0; i < ui.treeCompat->topLevelItemCount(); i++) { - QTreeWidgetItem* pItem = ui.treeCompat->topLevelItem(i); - if (pItem->checkState(0) == Qt::Checked) - Used.append(pItem->text(0)); - else - Rejected.append(pItem->text(0)); + if (m_WarnProgsChanged) + { + QStringList WarnProgs; + for (int i = 0; i < ui.treeWarnProgs->topLevelItemCount(); i++) { + QTreeWidgetItem* pItem = ui.treeWarnProgs->topLevelItem(i); + WarnProgs.append(pItem->text(0)); + } + + theAPI->GetGlobalSettings()->UpdateTextList("AlertProcess", WarnProgs); + m_WarnProgsChanged = false; } - theAPI->GetGlobalSettings()->UpdateTextList("Template", Used); - theAPI->GetGlobalSettings()->UpdateTextList("TemplateReject", Rejected); - m_CompatChanged = false; + if (m_CompatChanged) + { + QStringList Used; + QStringList Rejected; + for (int i = 0; i < ui.treeCompat->topLevelItemCount(); i++) { + QTreeWidgetItem* pItem = ui.treeCompat->topLevelItem(i); + if (pItem->checkState(0) == Qt::Checked) + Used.append(pItem->text(0)); + else + Rejected.append(pItem->text(0)); + } + + theAPI->GetGlobalSettings()->UpdateTextList("Template", Used); + theAPI->GetGlobalSettings()->UpdateTextList("TemplateReject", Rejected); + m_CompatChanged = false; + } } theConf->SetValue("Options/AutoRunSoftCompat", !ui.chkNoCompat->isChecked()); @@ -212,7 +247,7 @@ void CSettingsWindow::OnChange() void CSettingsWindow::OnTab() { - if (ui.tabs->currentWidget() == ui.tabCompat && m_CompatLoaded != 1) + if (ui.tabs->currentWidget() == ui.tabCompat && m_CompatLoaded != 1 && theAPI->IsConnected()) { if(m_CompatLoaded == 0) theGUI->GetCompat()->RunCheck();