389 lines
9.5 KiB
C++
389 lines
9.5 KiB
C++
/*
|
|
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Boxes
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "Boxes.h"
|
|
|
|
#include "SbieIni.h"
|
|
#include "UserSettings.h"
|
|
#include "WindowTitleMap.h"
|
|
#include "common/win32_ntddk.h"
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Variables
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBoxes *CBoxes::m_instance = NULL;
|
|
|
|
CString CBoxes::m_DefaultBox(L"DefaultBox");
|
|
|
|
static const CString _BoxExpandedView(L"BoxExpandedView");
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Constructor
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBoxes::CBoxes()
|
|
{
|
|
// _nullBox = new CBox(L"");
|
|
ReloadBoxes();
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Destructor
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBoxes::~CBoxes()
|
|
{
|
|
Clear();
|
|
// delete _nullBox;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// GetInstance
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBoxes &CBoxes::GetInstance()
|
|
{
|
|
if (! m_instance)
|
|
m_instance = new CBoxes();
|
|
return *m_instance;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// ReloadBoxes
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void CBoxes::ReloadBoxes()
|
|
{
|
|
Clear();
|
|
|
|
WCHAR name[64];
|
|
int index = -1;
|
|
while (1) {
|
|
|
|
if (GetSize() == 0)
|
|
name[0] = L'\0';
|
|
else {
|
|
index = SbieApi_EnumBoxesEx(
|
|
index, name, TRUE);
|
|
if (index == -1)
|
|
break;
|
|
LONG rc = SbieApi_IsBoxEnabled(name);
|
|
if (rc == STATUS_ACCOUNT_RESTRICTION)
|
|
m_AnyHiddenBoxes = true;
|
|
if (rc != STATUS_SUCCESS)
|
|
continue;
|
|
}
|
|
|
|
CBox *box = new CBox(name);
|
|
|
|
int index2;
|
|
for (index2 = 1; index2 < GetSize(); ++index2) {
|
|
const CBox &oldBox = GetBox(index2);
|
|
if (oldBox.GetName().CompareNoCase(name) > 0)
|
|
break;
|
|
}
|
|
|
|
if (index2 > GetSize())
|
|
Add((CObject *)box);
|
|
else
|
|
InsertAt(index2, (CObject *)box);
|
|
}
|
|
|
|
//
|
|
// if DefaultBox is missing, add it
|
|
//
|
|
|
|
bool doWriteExpandedView = false;
|
|
|
|
if (GetSize() == 1 &&
|
|
SbieApi_IsBoxEnabled(m_DefaultBox) ==
|
|
STATUS_OBJECT_NAME_NOT_FOUND) {
|
|
|
|
CBox *box = new CBox(m_DefaultBox);
|
|
Add((CObject *)box);
|
|
CBox::SetEnabled(box->GetName());
|
|
box->SetExpandedView(TRUE);
|
|
doWriteExpandedView = true;
|
|
}
|
|
|
|
ReadExpandedView();
|
|
if (doWriteExpandedView)
|
|
WriteExpandedView();
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// RefreshProcesses
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void CBoxes::RefreshProcesses()
|
|
{
|
|
CWindowTitleMap::GetInstance().Refresh();
|
|
for (int i = 0; i < GetSize(); ++i)
|
|
GetBox(i).GetBoxProc().RefreshProcesses();
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Clear
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void CBoxes::Clear()
|
|
{
|
|
while (GetSize()) {
|
|
CBox *box = (CBox *)GetAt(0);
|
|
RemoveAt(0);
|
|
delete box;
|
|
}
|
|
m_AnyHiddenBoxes = false;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// GetBox
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBox &CBoxes::GetBox(int index) const
|
|
{
|
|
if (index < 0 || index > GetSize())
|
|
index = 0;
|
|
return *(CBox *)GetAt(index);
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// GetBox
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBox &CBoxes::GetBox(const CString &name) const
|
|
{
|
|
for (int i = 0; i < GetSize(); ++i) {
|
|
CBox &box = GetBox(i);
|
|
if (box.GetName().CompareNoCase(name) == 0)
|
|
return box;
|
|
}
|
|
return GetBox(0);
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// GetBoxByProcessId
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
CBox &CBoxes::GetBoxByProcessId(ULONG pid) const
|
|
{
|
|
for (int i = 0; i < GetSize(); ++i) {
|
|
CBox &box = GetBox(i);
|
|
if (box.GetBoxProc().GetIndexForProcessId(pid) != -1)
|
|
return box;
|
|
}
|
|
return GetBox(0);
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// GetBoxIndex
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
int CBoxes::GetBoxIndex(const CString &name) const
|
|
{
|
|
for (int i = 0; i < GetSize(); ++i) {
|
|
CBox &box = GetBox(i);
|
|
if (box.GetName().CompareNoCase(name) == 0)
|
|
return i;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// AnyActivity
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
BOOL CBoxes::AnyActivity() const
|
|
{
|
|
for (int i = 1; i < GetSize(); ++i) {
|
|
if (GetBox(i).GetBoxProc().GetProcessCount())
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// KillAll
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void CBoxes::KillAll() const
|
|
{
|
|
for (int i = 1; i < GetSize(); ++i)
|
|
SbieDll_KillAll(-1, GetBox(i).GetName());
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// AnyHiddenBoxes
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
bool CBoxes::AnyHiddenBoxes() const
|
|
{
|
|
return m_AnyHiddenBoxes;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// GetHiddenBoxes
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void CBoxes::GetHiddenBoxes(CStringList &list) const
|
|
{
|
|
while (! list.IsEmpty())
|
|
list.RemoveHead();
|
|
|
|
WCHAR name[64];
|
|
int index = -1;
|
|
while (1) {
|
|
index = SbieApi_EnumBoxesEx(index, name, TRUE);
|
|
if (index == -1)
|
|
break;
|
|
LONG rc = SbieApi_IsBoxEnabled(name);
|
|
if (rc == STATUS_ACCOUNT_RESTRICTION)
|
|
list.AddTail(name);
|
|
}
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// ReadExpandedView
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
void CBoxes::ReadExpandedView()
|
|
{
|
|
CUserSettings &ini = CUserSettings::GetInstance();
|
|
|
|
//
|
|
// read old BoxExpandedView_boxname settings
|
|
//
|
|
|
|
for (int i = 0; i < GetSize(); ++i) {
|
|
CBox &box = GetBox(i);
|
|
CString boxname = box.GetName();
|
|
if (! boxname.IsEmpty()) {
|
|
CString setting(_BoxExpandedView);
|
|
setting += L"_";
|
|
setting += boxname;
|
|
BOOL value;
|
|
ini.GetBool(setting, value, FALSE);
|
|
if (value)
|
|
box.SetExpandedView(TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// read new setting BoxExpandedView=boxname1,boxname2
|
|
//
|
|
|
|
CStringList list;
|
|
ini.GetTextCsv(_BoxExpandedView, list);
|
|
while (! list.IsEmpty()) {
|
|
CString boxname = list.RemoveHead();
|
|
if (! boxname.IsEmpty()) {
|
|
CBox &box = GetBox(boxname);
|
|
if (! box.GetName().IsEmpty())
|
|
box.SetExpandedView(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// WriteExpandedView
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
BOOL CBoxes::WriteExpandedView()
|
|
{
|
|
CUserSettings &ini = CUserSettings::GetInstance();
|
|
|
|
//
|
|
// write new setting BoxExpandedView=boxname1,boxname2
|
|
//
|
|
|
|
CStringList list;
|
|
for (int i = 0; i < GetSize(); ++i) {
|
|
CBox &box = GetBox(i);
|
|
CString boxname = box.GetName();
|
|
if (! boxname.IsEmpty()) {
|
|
if (box.IsExpandedView())
|
|
list.AddTail(boxname);
|
|
}
|
|
}
|
|
|
|
BOOL ok = ini.SetTextCsv(_BoxExpandedView, list);
|
|
|
|
//
|
|
// delete old BoxExpandedView_boxname settings
|
|
//
|
|
|
|
if (ok) {
|
|
|
|
CString setting(_BoxExpandedView);
|
|
setting += L"_";
|
|
int len = setting.GetLength();
|
|
|
|
CStringList names;
|
|
ini.GetSettingsNames(names);
|
|
while (! names.IsEmpty()) {
|
|
CString name = names.RemoveHead();
|
|
if (name.GetLength() >= len &&
|
|
name.Left(len).CompareNoCase(setting) == 0) {
|
|
ini.SetText(name, CString());
|
|
}
|
|
}
|
|
}
|
|
|
|
return ok;
|
|
}
|