From f61ac60b2e88af275b7b6f7f9c1dd704c5d8141b Mon Sep 17 00:00:00 2001 From: DavidXanatos Date: Mon, 13 Jun 2022 20:12:53 +0200 Subject: [PATCH] 1.1.2 --- CHANGELOG.md | 33 +++++- Sandboxie/core/dll/custom.c | 40 +++++++ SandboxiePlus/QSbieAPI/SbieAPI.cpp | 14 ++- SandboxiePlus/QSbieAPI/SbieAPI.h | 8 +- SandboxiePlus/SandMan/BoxMonitor.cpp | 103 ++++++++++++++---- SandboxiePlus/SandMan/BoxMonitor.h | 16 ++- SandboxiePlus/SandMan/Models/SbieModel.cpp | 4 +- .../SandMan/Resources/Actions/Refresh.png | Bin 0 -> 2297 bytes SandboxiePlus/SandMan/Resources/SandMan.qrc | 1 + SandboxiePlus/SandMan/SandMan.cpp | 41 ++++--- SandboxiePlus/SandMan/SandMan.h | 4 +- SandboxiePlus/SandMan/SbiePlusAPI.cpp | 41 +++++-- SandboxiePlus/SandMan/SbiePlusAPI.h | 8 +- SandboxiePlus/SandMan/Views/SbieView.cpp | 29 ++++- SandboxiePlus/SandMan/Views/SbieView.h | 2 + .../SandMan/Windows/RecoveryWindow.cpp | 10 +- .../SandMan/Windows/RecoveryWindow.h | 3 +- 17 files changed, 286 insertions(+), 71 deletions(-) create mode 100644 SandboxiePlus/SandMan/Resources/Actions/Refresh.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 55155653..fe0b22c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,31 @@ This project adheres to [Semantic Versioning](http://semver.org/). + +## [1.1.2 / 5.56.2] - 2022-06-?? + +### Added +- added missing file recovery log from sbiectrl to sandman [#425](https://github.com/sandboxie-plus/Sandboxie/issues/425) +- Imminent recovery window will now auto close when all files are recovered [#1498](https://github.com/sandboxie-plus/Sandboxie/issues/1498) +- the imminent recovery window of sandman is now by default alway on top like in sbiectrl this can be disabled with "Options/RecoveryOnTop=n" [#1465](https://github.com/sandboxie-plus/Sandboxie/issues/1465) +- added option to toggle Imminent recovery from the presets sub menu [#1653](https://github.com/sandboxie-plus/Sandboxie/issues/1653) +- added option to disable file recovery and or message pop up globally +- added per box refresh opzion [#1945](https://github.com/sandboxie-plus/Sandboxie/issues/1945) + +### Changed +- desktop security workaround used for chrome, firefox and acrobat can now be enabled for all processes using "UseSbieDeskHack=y" +- inproved double click behavioure [#1935](https://github.com/sandboxie-plus/Sandboxie/issues/1935) +- box size info is refreshed on file recovery + +### Fixed +- fixed issue with unnececery sandboxie config reloads introduced in 1.1.1 +- fixed issue with recovery window focus [#1374](https://github.com/sandboxie-plus/Sandboxie/issues/1374) +- fixed issues with desktop objects introduced in 1.1.1 [#1934](https://github.com/sandboxie-plus/Sandboxie/issues/1934) +- fixed issues with edge startup boost using a gpo preset + + + + ## [1.1.1 / 5.56.1] - 2022-06-07 ### Added @@ -169,7 +194,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - EnableObjectFiltering is now set enabled by default, and replaces Sbie's old process/thread handle filter -- the `$:` syntax now accepts a wildcard `$:*` no more specialized wildcards, though +- the $: syntax now accepts a wildcard $:* no more specialized wildcards though ### Fixed - fixed NtGetNextProcess being fully disabled instead of properly filtered @@ -1013,8 +1038,8 @@ Fixed issue with Windows 7 ### Changed - replaced the Process List used by the driver with a much faster Hash Map implementation --- Note: this change provides an almost static system call speed of 1.2µs regardless of the running process count --- The old list, with 100 programs running required 4.5µs; with 200: 12µs; and with 300: 18µs per syscall +-- Note: this change provides an almost static system call speed of 1.2µs regardless of the running process count +-- The old list, with 100 programs running required 4.5µs; with 200: 12µs; and with 300: 18µs per syscall -- Note: some of the slowdown was also affecting non-sandboxed applications due to how the driver handles certain callbacks - replaced the per-process Thread List used by the driver with a much faster Hash Map implementation - replaced configuration section list with a hash map to improve configuration performance, and increased line limit to 100000 @@ -1641,7 +1666,7 @@ Fixed issue with Windows 7 - added text filter to templates view - added new compatibility templates: -- Windows 10 core UI component: OpenIpcPath=\BaseNamedObjects\[CoreUI]-* solving issues with Chinese Input and Emojis [#120](https://github.com/sandboxie-plus/Sandboxie/issues/120) [#88](https://github.com/sandboxie-plus/Sandboxie/issues/88) --- Firefox Quantum, access to Windows’ FontCachePort for compatibility with Windows 7 +-- Firefox Quantum, access to Windows's FontCachePort for compatibility with Windows 7 - added experimental debug option "OriginalToken=y" which lets sandboxed processes retain their original unrestricted token -- This option is comparable with "OpenToken=y" and is intended only for testing and debugging, it BREAKS most SECURITY guarantees (!) - added debug option "NoSandboxieDesktop=y" it disables the desktop proxy mechanism diff --git a/Sandboxie/core/dll/custom.c b/Sandboxie/core/dll/custom.c index 9dce878f..ad8d5b42 100644 --- a/Sandboxie/core/dll/custom.c +++ b/Sandboxie/core/dll/custom.c @@ -41,6 +41,7 @@ static BOOLEAN DisableRecycleBin(void); static BOOLEAN DisableWinRS(void); static BOOLEAN DisableWerFaultUI(void); static BOOLEAN EnableMsiDebugging(void); +static BOOLEAN DisableEdgeBoost(void); static BOOLEAN Custom_EnableBrowseNewProcess(void); static BOOLEAN Custom_DisableBHOs(void); static BOOLEAN Custom_OpenWith(void); @@ -87,6 +88,7 @@ _FX BOOLEAN CustomizeSandbox(void) DisableWinRS(); DisableWerFaultUI(); EnableMsiDebugging(); + DisableEdgeBoost(); Custom_EnableBrowseNewProcess(); DeleteShellAssocKeys(0); Custom_DisableBHOs(); @@ -461,6 +463,44 @@ _FX BOOLEAN EnableMsiDebugging(void) } +//--------------------------------------------------------------------------- +// DisableEdgeBoost +// +// Disable esge startup boost +//--------------------------------------------------------------------------- + + +_FX BOOLEAN DisableEdgeBoost(void) +{ + NTSTATUS status; + OBJECT_ATTRIBUTES objattrs; + UNICODE_STRING uni; + HANDLE hKeyRoot; + HANDLE hKeyEdge; + + // Open HKLM + RtlInitUnicodeString(&uni, Custom_PrefixHKLM); + InitializeObjectAttributes(&objattrs, &uni, OBJ_CASE_INSENSITIVE, NULL, NULL); + if (NtOpenKey(&hKeyRoot, KEY_READ, &objattrs) == STATUS_SUCCESS) + { + // open/create WER parent key + RtlInitUnicodeString(&uni, L"SOFTWARE\\Policies\\Microsoft\\Edge"); + InitializeObjectAttributes(&objattrs, &uni, OBJ_CASE_INSENSITIVE, hKeyRoot, NULL); + if (Key_OpenOrCreateIfBoxed(&hKeyEdge, KEY_ALL_ACCESS, &objattrs) == STATUS_SUCCESS) + { + DWORD StartupBoostEnabled = 0; + RtlInitUnicodeString(&uni, L"StartupBoostEnabled"); + status = NtSetValueKey(hKeyEdge, &uni, 0, REG_DWORD, &StartupBoostEnabled, sizeof(StartupBoostEnabled)); + + NtClose(hKeyEdge); + } + NtClose(hKeyRoot); + } + + return TRUE; +} + + //--------------------------------------------------------------------------- // Custom_OpenWith // diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.cpp b/SandboxiePlus/QSbieAPI/SbieAPI.cpp index 85ea9635..f1fc7898 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.cpp +++ b/SandboxiePlus/QSbieAPI/SbieAPI.cpp @@ -1145,6 +1145,7 @@ SB_STATUS CSbieAPI::ReloadBoxes(bool bForceUpdate) { pBox = CSandBoxPtr(NewSandBox(BoxName, this)); m_SandBoxes.insert(BoxName.toLower(), pBox); + emit BoxAdded(pBox); } UpdateBoxPaths(pBox); @@ -1153,8 +1154,11 @@ SB_STATUS CSbieAPI::ReloadBoxes(bool bForceUpdate) pBox->UpdateDetails(); } - foreach(const QString& BoxName, OldSandBoxes.keys()) - m_SandBoxes.remove(BoxName); + foreach(const QString & BoxName, OldSandBoxes.keys()) { + CSandBoxPtr pBox = m_SandBoxes.take(BoxName); + pBox->SetBoxPaths(QString(), QString(), QString()); + emit BoxRemoved(pBox); + } return SB_OK; } @@ -1419,7 +1423,7 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions) if (pBox->m_ActiveProcessCount == 0) { pBox->m_ActiveProcessCount = 1; pBox->OpenBox(); - emit BoxOpened(pBox->GetName()); + emit BoxOpened(pBox); } pProcess->m_pBox = pBox.data(); @@ -1459,7 +1463,7 @@ SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions) pBox->m_ActiveProcessCount = ActiveProcessCount; if (WasBoxClosed) { pBox->CloseBox(); - emit BoxClosed(pBox->GetName()); + emit BoxClosed(pBox); } } } @@ -2337,7 +2341,7 @@ CBoxedProcessPtr CSbieAPI::OnProcessBoxed(quint32 ProcessId, const QString& Path if (pBox->m_ActiveProcessCount == 0) { pBox->m_ActiveProcessCount = 1; pBox->OpenBox(); - emit BoxOpened(pBox->GetName()); + emit BoxOpened(pBox); } pProcess = CBoxedProcessPtr(NewBoxedProcess(ProcessId, pBox.data())); diff --git a/SandboxiePlus/QSbieAPI/SbieAPI.h b/SandboxiePlus/QSbieAPI/SbieAPI.h index 68f30f61..62c73242 100644 --- a/SandboxiePlus/QSbieAPI/SbieAPI.h +++ b/SandboxiePlus/QSbieAPI/SbieAPI.h @@ -158,8 +158,12 @@ signals: void LogSbieMessage(quint32 MsgCode, const QStringList& MsgData, quint32 ProcessId); void ProcessBoxed(quint32 ProcessId, const QString& Path, const QString& Box, quint32 ParentId); void FileToRecover(const QString& BoxName, const QString& FilePath, const QString& BoxPath, quint32 ProcessId); - void BoxOpened(const QString& BoxName); - void BoxClosed(const QString& BoxName); + + void BoxAdded(const CSandBoxPtr& pBox); + void BoxOpened(const CSandBoxPtr& pBox); + void BoxClosed(const CSandBoxPtr& pBox); + void BoxRemoved(const CSandBoxPtr& pBox); + void NotAuthorized(bool bLoginRequired, bool &bRetry); void QueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 RequestId, const QVariantMap& Data); diff --git a/SandboxiePlus/SandMan/BoxMonitor.cpp b/SandboxiePlus/SandMan/BoxMonitor.cpp index 1182c28a..a662ef61 100644 --- a/SandboxiePlus/SandMan/BoxMonitor.cpp +++ b/SandboxiePlus/SandMan/BoxMonitor.cpp @@ -5,14 +5,11 @@ CBoxMonitor::CBoxMonitor() { m_bTerminate = false; - start(); } CBoxMonitor::~CBoxMonitor() { - m_bTerminate = true; - if (!wait(10 * 1000)) - terminate(); + Stop(); } void CBoxMonitor::Notify(const wstring& strDirectory) @@ -25,7 +22,7 @@ void CBoxMonitor::Notify(const wstring& strDirectory) quint64 CBoxMonitor::CounDirSize(const QString& Directory, SBox* Box) { quint64 TotalSize = 0; - if (Box->pBox.isNull() || m_bTerminate) + if (m_bTerminate || Box->pBox.isNull()) return TotalSize; QDir Dir(Directory); @@ -44,6 +41,8 @@ void CBoxMonitor::run() { while (!m_bTerminate) { + Sleep(1000); + m_Mutex.lock(); QList Keys = m_Boxes.keys(); m_Mutex.unlock(); @@ -62,12 +61,14 @@ void CBoxMonitor::run() if (MinScanInterval > 30 * 60 * 1000) MinScanInterval = 30 * 60 * 1000; - if (Box->Changed && (Box->Closed || Box->LastScan == 0 || (CurTick - Box->LastScan) > MinScanInterval)) { + if ((Box->Changed && (!Box->IsWatched || Box->LastScan == 0 || (CurTick - Box->LastScan) > MinScanInterval)) || Box->ForceUpdate) { qDebug() << "Rescanning:" << Key << "(" + QDateTime::currentDateTime().toString() + ")"; quint64 ScanStart = GetCurTick(); + Box->ScanDuration = -1; + Box->TotalSize = CounDirSize(Key, Box); Box->ScanDuration = GetCurTick() - ScanStart; @@ -79,6 +80,7 @@ void CBoxMonitor::run() ); Box->Changed = false; + Box->ForceUpdate = false; } m_Mutex.lock(); @@ -86,14 +88,12 @@ void CBoxMonitor::run() m_Boxes.remove(Key); m_Mutex.unlock(); } - - Sleep(1000); } } void CBoxMonitor::UpdateBox(const QString& Path) { - // Note: this functin runs in the main thread + // Note: this private functin runs in the main thread m_Mutex.lock(); SBox Box = m_Boxes.value(Path); @@ -103,27 +103,86 @@ void CBoxMonitor::UpdateBox(const QString& Path) Box.pBox->SetSize(Box.TotalSize); } -void CBoxMonitor::AddBox(CSandBoxPlus* pBox, bool AndWatch) +void CBoxMonitor::WatchBox(CSandBoxPlus* pBox) { QMutexLocker Lock(&m_Mutex); + if (!isRunning()) start(); - m_Boxes[pBox->GetFileRoot()].pBox = pBox; + SBox& Box = m_Boxes[pBox->GetFileRoot()]; + Box.pBox = pBox; - if (AndWatch) { - m_Boxes[pBox->GetFileRoot()].Closed = false; - AddDirectory(pBox->GetFileRoot().toStdWString().c_str(), true, FILE_NOTIFY_CHANGE_SIZE); - } - else - m_Boxes[pBox->GetFileRoot()].Changed = true; + Box.IsWatched = true; + AddDirectory(pBox->GetFileRoot().toStdWString().c_str(), true, FILE_NOTIFY_CHANGE_SIZE); } -void CBoxMonitor::CloseBox(CSandBoxPlus* pBox, bool AndClear) +void CBoxMonitor::ScanBox(CSandBoxPlus* pBox) { QMutexLocker Lock(&m_Mutex); + if (!isRunning()) start(); - if(AndClear) - m_Boxes[pBox->GetFileRoot()].pBox.clear(); - m_Boxes[pBox->GetFileRoot()].Closed = true; + SBox& Box = m_Boxes[pBox->GetFileRoot()]; + Box.pBox = pBox; - DetachDirectory(pBox->GetFileRoot().toStdWString().c_str()); + Box.ForceUpdate = true; +} + +void CBoxMonitor::CloseBox(CSandBoxPlus* pBox) +{ + QMutexLocker Lock(&m_Mutex); + if (!isRunning()) return; + + SBox& Box = m_Boxes[pBox->GetFileRoot()]; + + if(Box.IsWatched) + DetachDirectory(pBox->GetFileRoot().toStdWString().c_str()); + Box.IsWatched = false; + + //Box.Changed = true; +} + +void CBoxMonitor::RemoveBox(CSandBoxPlus* pBox) +{ + QMutexLocker Lock(&m_Mutex); + if (!isRunning()) return; + + auto I = m_Boxes.find(pBox->GetFileRoot()); + if (I == m_Boxes.end()) + return; + + if(I->IsWatched) + DetachDirectory(pBox->GetFileRoot().toStdWString().c_str()); + I->pBox.clear(); +} + +bool CBoxMonitor::IsScanPending(const CSandBoxPlus* pBox) +{ + QMutexLocker Lock(&m_Mutex); + if (!isRunning()) false; + + auto I = m_Boxes.find(pBox->GetFileRoot()); + if (I == m_Boxes.end()) + return false; + + return (I->Changed && !I->IsWatched) || I->ForceUpdate || I->ScanDuration == -1; +} + +void CBoxMonitor::Stop() +{ + QMutexLocker Lock(&m_Mutex); + if (!isRunning()) return; + + m_bTerminate = true; + + if (!wait(10 * 1000)) { + terminate(); + qDebug() << "Failed to stop monitor thread, terminating!!!"; + } + + while (!m_Boxes.isEmpty()) { + SBox Box = m_Boxes.take(m_Boxes.firstKey()); + if(Box.IsWatched && Box.pBox) + DetachDirectory(Box.pBox->GetFileRoot().toStdWString().c_str()); + } + + m_bTerminate = false; } \ No newline at end of file diff --git a/SandboxiePlus/SandMan/BoxMonitor.h b/SandboxiePlus/SandMan/BoxMonitor.h index 3862c557..596d64ab 100644 --- a/SandboxiePlus/SandMan/BoxMonitor.h +++ b/SandboxiePlus/SandMan/BoxMonitor.h @@ -14,8 +14,14 @@ public: virtual void run(); - void AddBox(CSandBoxPlus* pBox, bool AndWatch = false); - void CloseBox(CSandBoxPlus* pBox, bool AndClear = false); + void WatchBox(CSandBoxPlus* pBox); + void ScanBox(CSandBoxPlus* pBox); + void CloseBox(CSandBoxPlus* pBox); + void RemoveBox(CSandBoxPlus* pBox); + + bool IsScanPending(const CSandBoxPlus* pBox); + + void Stop(); private slots: void UpdateBox(const QString& Path); @@ -25,16 +31,18 @@ protected: struct SBox { SBox() { + ForceUpdate = false; Changed = false; - Closed = false; + IsWatched = false; LastScan = 0; ScanDuration = 0; TotalSize = 0; } QPointer pBox; + bool ForceUpdate; bool Changed; - bool Closed; + bool IsWatched; quint64 LastScan; quint64 ScanDuration; diff --git a/SandboxiePlus/SandMan/Models/SbieModel.cpp b/SandboxiePlus/SandMan/Models/SbieModel.cpp index 59c1aa43..3f50f932 100644 --- a/SandboxiePlus/SandMan/Models/SbieModel.cpp +++ b/SandboxiePlus/SandMan/Models/SbieModel.cpp @@ -233,7 +233,7 @@ QList CSbieModel::Sync(const QMap& BoxList, cons { case eName: Value = pBox->GetName(); break; case eStatus: Value = pBox.objectCast()->GetStatusStr(); break; - case eInfo: Value = bWatchSize ? pBox.objectCast()->GetSize() : 0; break; + case eInfo: Value = pBox.objectCast()->IsEmptyCached() ? -2 : (bWatchSize ? pBox.objectCast()->GetSize() : 0); break; case ePath: Value = pBox->GetFileRoot(); break; } @@ -248,7 +248,7 @@ QList CSbieModel::Sync(const QMap& BoxList, cons switch (section) { case eName: ColValue.Formatted = Value.toString().replace("_", " "); break; - case eInfo: ColValue.Formatted = Value.toULongLong() > 0 ? FormatSize(Value.toULongLong()) : ""; break; + case eInfo: ColValue.Formatted = Value.toULongLong() == -2 ? tr("Empty") : (Value.toULongLong() > 0 ? FormatSize(Value.toULongLong()) : ""); break; } } diff --git a/SandboxiePlus/SandMan/Resources/Actions/Refresh.png b/SandboxiePlus/SandMan/Resources/Actions/Refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..dcd67c440ec9e3e3a13e48c8f6f8c2536e8cf234 GIT binary patch literal 2297 zcmV?iFj8D5Mr8=q*X|yCPFc7 z2}Nx~C0Z$zLYpRS`Ou&|nn+QbG)mM^rG(HtTL`Vf8vzyqECXqvX@KwuI5sv08?U|Z zz4x5yhuv%TVX(n#K6xbT+SWNU^E-29&YXLJVHuWTxt>ryl{Gx;on&{*$J}nd+v(xa zO2XN&)qADsxFZBmNPt@fa7F-!4M_)AoxISQFWZ9#Ir^NdN)+Pd($U6)WtFB60Hi@^ z+~UEZtv;|pun9mD3_*aPUZWDAeWt=+fBtFf2ZQzFra^W;=O0s95&K~5)c9=O&IAR3 zf%fw{wy*Ug(5k~O7`g`71YjeE5E&p~1{4EIQQeOZwQU*8BO0Jc={Cxd~wA&>*By;CbD#TrYiOgGD< z6RZGb61J@IqxqN<9-WgQ8lY={E*Lg}HXGp-2^a(f3G4*Z7!bw)a4M$vI{fW}&XECu z?DxAQ2-}l_Ix-3$LqcD=nSvUXY4vX zQ$%g=-&YUwMxD2$`&~>B3Mau3tN>zs#S$9%c2(O)EZe9I$l%xIi!2np&^LMNwh3BmWOJ6vET9u?tV71X-ihcBbNNe78w^rjH z+^^P5iPTs*VL|kCXxRO30h~IYvXfZ&!-lq_g9WgJBo?GESh6CLWxo>4%b;jkR~s4u zzN=r5eXHCfC(evN-dmm0R%g$L1wcZaa@&o2mK?r(F<%gYwHU_=cce#wnR4v20+XcA zkd`{)T1rbss|}t4sX-VzGqk2=rVgmzy(Apk%q)TNhoR)lQ(tguyqXBR%9 zmZs0`Ga~zb=Pj+C7^$@my7bj(-0ous;YZ6qZEnpc1d{5%3wg~bAdw(G*x+7Lw<&Zf zXA$~R=q}(_91cajtB`tjwAj$}h2u|8{IB(3z9Bl-Vl*V~WJSH5LbiRoU@G?W3w_P+ z6Qpun{NY|@R+uGl`lvHv6Y}YNLjZtCppGR`uj3L5S@u~02v4HLjeH*N>fh}^DO^zp5tGMUEN*cnRNTslK?nu#$)}0j3_kcrcbn#U1_&P zR-L?XYN$Ypeui%UavZV#{`TA9oxvW>$k<+~AFoT!?H9zRp*npcQd=w(5G_LmaV_cY zv0cngc$R=m=keKNb3mL9<;|+w){5ly%ovEoqSVA$5rG0Uz?VHX=N!@P%9(yyvTC?A zscYz6&lF`+SGpfo+oEa8kv%pCge7ryZ`Io>+-hNP#z~*@g_v`8QqDgTQHrP6Z7bmk zs&ME%&lDmqN-sE8bc}=+%^sTrV#X<)+3x_5fYZe_L+^T~XpD-C>Y2*hxPf5y*c^~Z zSe)sjQA1&YIr0|xo*_=Vs!C6C>vw5TQ});#kl+=4e@5L-!FaqwnnR)Ca*D?PS#{enF5M&NvVi{9N=!jB&tt0jet0kJINvV_0JJsRH)Xd4sq!b#8){-D@zGF#n1*_pompSESu@LX9E|1of`4TxTQY5a)j-Y2DkaHFS$l6*;Vj2`E z^JYky7p&y-KmK3h%X~qsn>})diqQdRYSQfS!JL~Z6mb5Md7dCd3uNRDk0HRL!c8H^tcSLQ26X7&)EBFC ziE3pFg^5K100uy@HiuW-s2_O% z5&JdbmFeFH8P-QmT#beV5{lq+8n|~t0DhO5c2N@C7PRjVN9fUcyTUj1DmE|o*Vk^Z zd{h%yO5l3{XuTi|NRJ+ TuO|oz00000NkvXXu0mjf-JwU^ literal 0 HcmV?d00001 diff --git a/SandboxiePlus/SandMan/Resources/SandMan.qrc b/SandboxiePlus/SandMan/Resources/SandMan.qrc index a716bc30..fecee6dd 100644 --- a/SandboxiePlus/SandMan/Resources/SandMan.qrc +++ b/SandboxiePlus/SandMan/Resources/SandMan.qrc @@ -69,6 +69,7 @@ IconOffCx.png Actions/Monitor.png SideLogo.png + Actions/Refresh.png Boxes/sandbox-b-empty.png diff --git a/SandboxiePlus/SandMan/SandMan.cpp b/SandboxiePlus/SandMan/SandMan.cpp index 3a71d48f..8581d650 100644 --- a/SandboxiePlus/SandMan/SandMan.cpp +++ b/SandboxiePlus/SandMan/SandMan.cpp @@ -134,7 +134,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&))); + connect(theAPI, SIGNAL(BoxClosed(const CSandBoxPtr&)), this, SLOT(OnBoxClosed(const CSandBoxPtr&))); m_RequestManager = NULL; @@ -322,6 +322,10 @@ void CSandMan::CreateMenus() m_pWndFinder = m_pMenuFile->addAction(CSandMan::GetIcon("finder"), tr("Window Finder"), this, SLOT(OnWndFinder())); m_pDisableForce = m_pMenuFile->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce())); m_pDisableForce->setCheckable(true); + m_pDisableRecovery = m_pMenuFile->addAction(tr("Disable File Recovery")); + m_pDisableRecovery->setCheckable(true); + m_pDisableMessages = m_pMenuFile->addAction(tr("Disable Message PopUp")); + m_pDisableMessages->setCheckable(true); m_pMenuFile->addSeparator(); m_pMaintenance = m_pMenuFile->addMenu(CSandMan::GetIcon("Maintenance"), tr("&Maintenance")); m_pConnect = m_pMaintenance->addAction(CSandMan::GetIcon("Connect"), tr("Connect"), this, SLOT(OnMaintenance())); @@ -369,7 +373,7 @@ void CSandMan::CreateMenus() m_pMenuView->addSeparator(); - m_pRefreshAll = m_pMenuView->addAction(CSandMan::GetIcon("Recover"), tr("Refresh View"), this, SLOT(OnRefresh())); + m_pRefreshAll = m_pMenuView->addAction(CSandMan::GetIcon("Refresh"), tr("Refresh View"), this, SLOT(OnRefresh())); m_pRefreshAll->setShortcut(QKeySequence("F5")); m_pRefreshAll->setShortcutContext(Qt::WidgetWithChildrenShortcut); this->addAction(m_pRefreshAll); @@ -600,6 +604,8 @@ void CSandMan::CreateTrayMenu() m_pTrayMenu->addAction(m_pEmptyAll); m_pDisableForce2 = m_pTrayMenu->addAction(tr("Pause Forcing Programs"), this, SLOT(OnDisableForce2())); m_pDisableForce2->setCheckable(true); + m_pTrayMenu->addAction(m_pDisableRecovery); + m_pTrayMenu->addAction(m_pDisableMessages); m_pTrayMenu->addSeparator(); /*QWidgetAction* pBoxWidget = new QWidgetAction(m_pTrayMenu); @@ -1064,12 +1070,8 @@ finish: return Ret; } -void CSandMan::OnBoxClosed(const QString& BoxName) +void CSandMan::OnBoxClosed(const CSandBoxPtr& pBox) { - CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); - if (!pBox) - return; - if (!pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false) && !pBox->IsEmpty()) { bool DeleteShapshots = false; @@ -1078,7 +1080,7 @@ void CSandMan::OnBoxClosed(const QString& BoxName) return; if(theConf->GetBool("Options/AutoBoxOpsNotify", false)) - OnLogMessage(tr("Auto deleting content of %1").arg(BoxName), true); + OnLogMessage(tr("Auto deleting content of %1").arg(pBox->GetName()), true); if (theConf->GetBool("Options/UseAsyncBoxOps", false)) { @@ -1218,6 +1220,8 @@ void CSandMan::OnStatusChanged() m_pBoxView->Clear(); theAPI->WatchIni(false); + + theAPI->StopMonitor(); } m_pSupport->setVisible(g_Certificate.isEmpty()); @@ -1314,9 +1318,10 @@ void CSandMan::OnLogMessage(const QString& Message, bool bNotify) void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, quint32 ProcessId) { - if ((MsgCode & 0xFFFF) == 2198) // file migration progress + if ((MsgCode & 0xFFFF) == 2198 ) // file migration progress { - m_pPopUpWindow->ShowProgress(MsgCode, MsgData, ProcessId); + if (!m_pDisableMessages->isChecked()) + m_pPopUpWindow->ShowProgress(MsgCode, MsgData, ProcessId); return; } @@ -1326,7 +1331,7 @@ void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, qui m_MissingTemplates.append(MsgData[2]); } - if ((MsgCode & 0xFFFF) == 6004) // certificat error + if ((MsgCode & 0xFFFF) == 6004) // certificate error { static quint64 iLastCertWarning = 0; if (iLastCertWarning + 60 < QDateTime::currentDateTime().toTime_t()) { // reset after 60 seconds @@ -1378,7 +1383,7 @@ void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, qui if ((MsgCode & 0xFFFF) == 2111) // process open denided return; // dont pop that one up - if(MsgCode != 0 && theConf->GetBool("Options/ShowNotifications", true)) + if(MsgCode != 0 && theConf->GetBool("Options/ShowNotifications", true) && !m_pDisableMessages->isChecked()) m_pPopUpWindow->AddLogMessage(Message, MsgCode, MsgData, ProcessId); } @@ -1433,7 +1438,7 @@ void CSandMan::OnQueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 Req void CSandMan::OnFileToRecover(const QString& BoxName, const QString& FilePath, const QString& BoxPath, quint32 ProcessId) { CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); - if (!pBox.isNull() && pBox.objectCast()->IsRecoverySuspended()) + if ((!pBox.isNull() && pBox.objectCast()->IsRecoverySuspended()) || m_pDisableRecovery->isChecked()) return; if (theConf->GetBool("Options/InstantRecovery", true)) @@ -1477,16 +1482,16 @@ CRecoveryWindow* CSandMan::ShowRecovery(const CSandBoxPtr& pBox, bool bFind) auto pBoxEx = pBox.objectCast(); if (!pBoxEx) return false; if (pBoxEx->m_pRecoveryWnd == NULL) { - pBoxEx->m_pRecoveryWnd = new CRecoveryWindow(pBox); + pBoxEx->m_pRecoveryWnd = new CRecoveryWindow(pBox, bFind == false); connect(pBoxEx->m_pRecoveryWnd, &CRecoveryWindow::Closed, [pBoxEx]() { pBoxEx->m_pRecoveryWnd = NULL; }); pBoxEx->m_pRecoveryWnd->show(); } - else { + /*else { pBoxEx->m_pRecoveryWnd->setWindowState((pBoxEx->m_pRecoveryWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); //SetForegroundWindow((HWND)pBoxEx->m_pRecoveryWnd->winId()); - } + }*/ if(bFind) pBoxEx->m_pRecoveryWnd->FindFiles(); return pBoxEx->m_pRecoveryWnd; @@ -1580,6 +1585,10 @@ void CSandMan::OnFileRecovered(const QString& BoxName, const QString& FilePath, m_pRecoveryLog->GetTree()->addTopLevelItem(pItem); m_pRecoveryLog->GetView()->verticalScrollBar()->setValue(m_pRecoveryLog->GetView()->verticalScrollBar()->maximum()); + + CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName); + if (pBox) + pBox.objectCast()->UpdateSize(); } int CSandMan::ShowQuestion(const QString& question, const QString& checkBoxText, bool* checkBoxSetting, int buttons, int defaultButton) diff --git a/SandboxiePlus/SandMan/SandMan.h b/SandboxiePlus/SandMan/SandMan.h index 3930a4e3..99acb08c 100644 --- a/SandboxiePlus/SandMan/SandMan.h +++ b/SandboxiePlus/SandMan/SandMan.h @@ -154,7 +154,7 @@ public slots: void OnAsyncProgress(int Progress); void OnCancelAsync(); - void OnBoxClosed(const QString& BoxName); + void OnBoxClosed(const CSandBoxPtr& pBox); void CheckForUpdates(bool bManual = true); void DownloadUpdates(const QString& DownloadUrl, bool bManual); @@ -247,6 +247,8 @@ private: QAction* m_pWndFinder; QAction* m_pDisableForce; QAction* m_pDisableForce2; + QAction* m_pDisableRecovery; + QAction* m_pDisableMessages; QMenu* m_pMaintenance; QAction* m_pConnect; QAction* m_pDisconnect; diff --git a/SandboxiePlus/SandMan/SbiePlusAPI.cpp b/SandboxiePlus/SandMan/SbiePlusAPI.cpp index c8311cbc..490e8bca 100644 --- a/SandboxiePlus/SandMan/SbiePlusAPI.cpp +++ b/SandboxiePlus/SandMan/SbiePlusAPI.cpp @@ -81,6 +81,11 @@ bool CSbiePlusAPI::IsRunningAsAdmin() return true; } +void CSbiePlusAPI::StopMonitor() +{ + m_BoxMonitor->Stop(); +} + /////////////////////////////////////////////////////////////////////////////// // CSandBoxPlus // @@ -163,18 +168,32 @@ void CSandBoxPlus::UpdateDetails() void CSandBoxPlus::SetBoxPaths(const QString& FilePath, const QString& RegPath, const QString& IpcPath) { + bool bPathChanged = (FilePath != m_FilePath); + + if (bPathChanged && !m_FilePath.isEmpty()) + ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->RemoveBox(this); + CSandBox::SetBoxPaths(FilePath, RegPath, IpcPath); + + if (m_FilePath.isEmpty()) { + m_IsEmpty = true; + return; + } + m_IsEmpty = IsEmpty(); - if (theConf->GetBool("Options/WatchBoxSize", false) && m_TotalSize == -1) - ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->AddBox(this); + if (bPathChanged && theConf->GetBool("Options/WatchBoxSize", false) && m_TotalSize == -1) + ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->ScanBox(this); + + if (theConf->GetBool("Options/ScanStartMenu", true)) + ScanStartMenu(); } void CSandBoxPlus::UpdateSize() { m_TotalSize = -1; if(theConf->GetBool("Options/WatchBoxSize", false)) - ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->AddBox(this); + ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->ScanBox(this); m_IsEmpty = IsEmpty(); } @@ -185,6 +204,11 @@ void CSandBoxPlus::SetSize(quint64 Size) theConf->SetValue("SizeCache/" + m_Name, Size); } +bool CSandBoxPlus::IsSizePending() const +{ + return ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->IsScanPending(this); +} + void CSandBoxPlus::OpenBox() { CSandBox::OpenBox(); @@ -192,7 +216,7 @@ void CSandBoxPlus::OpenBox() m_IsEmpty = false; if (theConf->GetBool("Options/WatchBoxSize", false)) - ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->AddBox(this, true); + ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->WatchBox(this); } void CSandBoxPlus::CloseBox() @@ -202,11 +226,14 @@ void CSandBoxPlus::CloseBox() m_SuspendRecovery = false; ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->CloseBox(this); + + if (theConf->GetBool("Options/ScanStartMenu", true)) + ScanStartMenu(); } SB_PROGRESS CSandBoxPlus::CleanBox() { - ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->CloseBox(this, true); + ((CSbiePlusAPI*)theAPI)->m_BoxMonitor->RemoveBox(this); SB_PROGRESS Status = CSandBox::CleanBox(); @@ -242,8 +269,8 @@ QString CSandBoxPlus::GetStatusStr() const QStringList Status; - if (m_IsEmpty) - Status.append(tr("Empty")); + //if (m_IsEmpty) + // Status.append(tr("Empty")); if (m_bApplicationCompartment) Status.append(tr("Application Compartment")); diff --git a/SandboxiePlus/SandMan/SbiePlusAPI.h b/SandboxiePlus/SandMan/SbiePlusAPI.h index f0d7dd2e..67ff611e 100644 --- a/SandboxiePlus/SandMan/SbiePlusAPI.h +++ b/SandboxiePlus/SandMan/SbiePlusAPI.h @@ -19,6 +19,8 @@ public: virtual bool IsBusy() const { return m_JobCount > 0; } + virtual void StopMonitor(); + protected: friend class CSandBoxPlus; @@ -80,9 +82,12 @@ public: virtual void SetLeaderProgram(const QString& ProgName, bool bSet); virtual int IsLeaderProgram(const QString& ProgName); + virtual bool IsEmptyCached() const { return m_IsEmpty; } + virtual void UpdateSize(); virtual quint64 GetSize() const { if(m_TotalSize == -1) return 0; return m_TotalSize; } virtual void SetSize(quint64 Size); //{ m_TotalSize = Size; } + virtual bool IsSizePending() const; virtual bool IsRecoverySuspended() const { return m_SuspendRecovery; } virtual void SetSuspendRecovery(bool bSet = true) { m_SuspendRecovery = bSet; } @@ -107,7 +112,7 @@ public: class COptionsWindow* m_pOptionsWnd; class CRecoveryWindow* m_pRecoveryWnd; - bool IsBusy() const { return !m_JobQueue.isEmpty(); } + bool IsBusy() const { return IsSizePending() || !m_JobQueue.isEmpty(); } SB_STATUS DeleteContentAsync(bool DeleteShapshots = true, bool bOnAutoDelete = false); public slots: @@ -118,6 +123,7 @@ public slots: protected: friend class CSbiePlusAPI; + virtual bool CheckUnsecureConfig() const; virtual bool TestProgramGroup(const QString& Group, const QString& ProgName); diff --git a/SandboxiePlus/SandMan/Views/SbieView.cpp b/SandboxiePlus/SandMan/Views/SbieView.cpp index daab1716..a06b4c58 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.cpp +++ b/SandboxiePlus/SandMan/Views/SbieView.cpp @@ -111,6 +111,7 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) m_pMenuContent->addSeparator(); m_pMenuExplore = m_pMenuContent->addAction(CSandMan::GetIcon("Explore"), tr("Explore Content"), this, SLOT(OnSandBoxAction())); m_pMenuRegEdit = m_pMenuContent->addAction(CSandMan::GetIcon("RegEdit"), tr("Open Registry"), this, SLOT(OnSandBoxAction())); + m_pMenuRefresh = m_pMenu->addAction(CSandMan::GetIcon("Refresh"), tr("Refresh Info"), this, SLOT(OnSandBoxAction())); m_pMenuSnapshots = m_pMenu->addAction(CSandMan::GetIcon("Snapshots"), tr("Snapshots Manager"), this, SLOT(OnSandBoxAction())); m_pMenuRecover = m_pMenu->addAction(CSandMan::GetIcon("Recover"), tr("Recover Files"), this, SLOT(OnSandBoxAction())); m_pMenuCleanUp = m_pMenu->addAction(CSandMan::GetIcon("Erase"), tr("Delete Content"), this, SLOT(OnSandBoxAction())); @@ -133,6 +134,10 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) m_pMenuPresetsINet->setCheckable(true); m_pMenuPresetsShares = m_pMenuPresets->addAction(tr("Allow Network Shares"), this, SLOT(OnSandBoxAction())); m_pMenuPresetsShares->setCheckable(true); + + m_pMenuPresets->addSeparator(); + m_pMenuPresetsRecovery = m_pMenuPresets->addAction(tr("Imminent Recovery"), this, SLOT(OnSandBoxAction())); + m_pMenuPresetsRecovery->setCheckable(true); m_pMenuDuplicate = m_pMenu->addAction(CSandMan::GetIcon("Duplicate"), tr("Duplicate Sandbox"), this, SLOT(OnSandBoxAction())); m_pMenuRename = m_pMenu->addAction(CSandMan::GetIcon("Rename"), tr("Rename Sandbox"), this, SLOT(OnSandBoxAction())); @@ -197,6 +202,7 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent) m_pMenu2->addAction(m_pMenuCleanUp); m_pMenu2->addSeparator(); m_pMenu2->addAction(m_pMenuOptions); + m_pMenu2->addMenu(m_pMenuPresets); QByteArray Columns = theConf->GetBlob("MainWindow/BoxTree_Columns"); if (Columns.isEmpty()) @@ -454,6 +460,7 @@ bool CSbieView::UpdateMenu() m_pMenuPresetsFakeAdmin->setChecked(pBox && pBox->GetBool("DropAdminRights", false) && pBox->GetBool("FakeAdminRights", false)); m_pMenuPresetsINet->setChecked(pBox && pBox.objectCast()->IsINetBlocked()); m_pMenuPresetsShares->setChecked(pBox && pBox.objectCast()->HasSharesAccess()); + m_pMenuPresetsRecovery->setChecked(pBox && pBox->GetBool("AutoRecover", false)); m_pMenuBrowse->setEnabled(iSandBoxeCount == 1); m_pMenuExplore->setEnabled(iSandBoxeCount == 1); @@ -886,6 +893,8 @@ void CSbieView::OnSandBoxAction(QAction* Action) SandBoxes.first().objectCast()->SetINetBlock(m_pMenuPresetsINet->isChecked()); else if (Action == m_pMenuPresetsShares) SandBoxes.first().objectCast()->SetAllowShares(m_pMenuPresetsShares->isChecked()); + else if (Action == m_pMenuPresetsRecovery) + m_pMenuPresetsRecovery->setChecked(SandBoxes.first()->SetBool("AutoRecover", m_pMenuPresetsRecovery->isChecked())); else if (Action == m_pMenuOptions) { OnDoubleClicked(m_pSbieTree->selectedRows().first()); @@ -914,6 +923,15 @@ void CSbieView::OnSandBoxAction(QAction* Action) SetForegroundWindow((HWND)pFileBrowserWindow->winId()); } } + else if (Action == m_pMenuRefresh) + { + foreach(const CSandBoxPtr& pBox, SandBoxes) + { + pBox.objectCast()->UpdateSize(); + if (theConf->GetBool("Options/ScanStartMenu", true)) + pBox.objectCast()->ScanStartMenu(); + } + } else if (Action == m_pMenuExplore) { if (SandBoxes.first()->IsEmpty()) { @@ -1286,11 +1304,14 @@ void CSbieView::OnDoubleClicked(const QModelIndex& index) if (pBox.isNull()) return; - if (index.column() == CSbieModel::ePath) - OnSandBoxAction(m_pMenuExplore); + if ((QGuiApplication::queryKeyboardModifiers() & Qt::ControlModifier) == 0) { - if (index.column() != CSbieModel::eName) - return; + if (index.column() == CSbieModel::ePath) + OnSandBoxAction(m_pMenuExplore); + } + + //if (index.column() != CSbieModel::eName) + // return; if (!pBox->IsEnabled()) { diff --git a/SandboxiePlus/SandMan/Views/SbieView.h b/SandboxiePlus/SandMan/Views/SbieView.h index b85344da..f39eb4ac 100644 --- a/SandboxiePlus/SandMan/Views/SbieView.h +++ b/SandboxiePlus/SandMan/Views/SbieView.h @@ -119,12 +119,14 @@ private: QAction* m_pMenuPresetsFakeAdmin; QAction* m_pMenuPresetsINet; QAction* m_pMenuPresetsShares; + QAction* m_pMenuPresetsRecovery; QAction* m_pMenuOptions; QAction* m_pMenuSnapshots; QAction* m_pMenuEmptyBox; QMenu* m_pMenuContent; QAction* m_pMenuExplore; QAction* m_pMenuBrowse; + QAction* m_pMenuRefresh; QAction* m_pMenuRegEdit; QAction* m_pMenuRecover; QAction* m_pMenuCleanUp; diff --git a/SandboxiePlus/SandMan/Windows/RecoveryWindow.cpp b/SandboxiePlus/SandMan/Windows/RecoveryWindow.cpp index 4c730cbf..8e3de40d 100644 --- a/SandboxiePlus/SandMan/Windows/RecoveryWindow.cpp +++ b/SandboxiePlus/SandMan/Windows/RecoveryWindow.cpp @@ -13,9 +13,11 @@ #endif -CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent) +CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, bool bImminent, QWidget *parent) : QDialog(parent) { + m_bImminent = bImminent; + Qt::WindowFlags flags = windowFlags(); flags |= Qt::CustomizeWindowHint; //flags &= ~Qt::WindowContextHelpButtonHint; @@ -28,7 +30,7 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent) //setWindowState(Qt::WindowActive); SetForegroundWindow((HWND)QWidget::winId()); - bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false); + bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false) || (bImminent && theConf->GetBool("Options/RecoveryOnTop", true)); this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop); if (!bAlwaysOnTop) { @@ -302,6 +304,9 @@ int CRecoveryWindow::FindFiles() Count += FindFiles(Folder); } + if (m_bImminent && m_FileMap.isEmpty()) + this->close(); + m_pFileModel->Sync(m_FileMap); ui.treeFiles->expandAll(); return Count; @@ -504,6 +509,7 @@ void CRecoveryWindow::OnCloseUntil() void CRecoveryWindow::OnAutoDisable() { + m_pBox.objectCast()->SetSuspendRecovery(); m_pBox->SetBool("AutoRecover", false); close(); } diff --git a/SandboxiePlus/SandMan/Windows/RecoveryWindow.h b/SandboxiePlus/SandMan/Windows/RecoveryWindow.h index 355da118..7d9a8c84 100644 --- a/SandboxiePlus/SandMan/Windows/RecoveryWindow.h +++ b/SandboxiePlus/SandMan/Windows/RecoveryWindow.h @@ -36,7 +36,7 @@ class CRecoveryWindow : public QDialog Q_OBJECT public: - CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent = Q_NULLPTR); + CRecoveryWindow(const CSandBoxPtr& pBox, bool bImminent = false, QWidget *parent = Q_NULLPTR); ~CRecoveryWindow(); bool IsDeleteShapshots() { return m_DeleteShapshots; } @@ -85,6 +85,7 @@ protected: bool m_bTargetsChanged; bool m_bReloadPending; bool m_DeleteShapshots; + bool m_bImminent; private: Ui::RecoveryWindow ui;