2021-10-15 16:04:52 +01:00
# include "stdafx.h"
# include "SelectBoxWindow.h"
# include "SandMan.h"
# include "../MiscHelpers/Common/Settings.h"
# include "../SbiePlusAPI.h"
# include "../Views/SbieView.h"
2023-01-29 12:09:10 +00:00
# include "../MiscHelpers/Common/Finder.h"
2021-10-15 16:04:52 +01:00
# if defined(Q_OS_WIN)
# include <wtypes.h>
# include <QAbstractNativeEventFilter>
# include <dbt.h>
# endif
2023-07-01 17:54:53 +01:00
//////////////////////////////////////////////////////////////////////////////////////
// CBoxPicker
//
CBoxPicker : : CBoxPicker ( QString DefaultBox , QWidget * parent )
: QWidget ( parent )
{
m_pTreeBoxes = new QTreeWidget ( ) ;
m_pTreeBoxes - > setHeaderLabels ( tr ( " Sandbox " ) . split ( " | " ) ) ;
connect ( m_pTreeBoxes , SIGNAL ( itemDoubleClicked ( QTreeWidgetItem * , int ) ) , this , SIGNAL ( BoxDblClick ( ) ) ) ;
m_pTreeBoxes - > setAlternatingRowColors ( theConf - > GetBool ( " Options/AltRowColors " , false ) ) ;
QVBoxLayout * pLayout = new QVBoxLayout ( this ) ;
pLayout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
pLayout - > addWidget ( new CFinder ( this , this , 0 ) ) ;
pLayout - > insertWidget ( 0 , m_pTreeBoxes ) ;
if ( DefaultBox . isEmpty ( ) & & theAPI - > IsConnected ( ) )
DefaultBox = theAPI - > GetGlobalSettings ( ) - > GetText ( " DefaultBox " , " DefaultBox " ) ;
LoadBoxed ( " " , DefaultBox ) ;
}
void CBoxPicker : : SetFilter ( const QString & Exp , int iOptions , int Column )
{
LoadBoxed ( Exp ) ;
}
void CBoxPicker : : LoadBoxed ( const QString & Filter , const QString & SelectBox )
{
m_pTreeBoxes - > clear ( ) ;
QList < CSandBoxPtr > Boxes = theAPI - > GetAllBoxes ( ) . values ( ) ; // map is sorted by key (box name)
QMap < QString , QStringList > Groups = theGUI - > GetBoxView ( ) - > GetGroups ( ) ;
if ( theConf - > GetBool ( " MainWindow/BoxTree_UseOrder " , false ) ) {
QMultiMap < double , CSandBoxPtr > Boxes2 ;
foreach ( const CSandBoxPtr & pBox , Boxes ) {
Boxes2 . insertMulti ( GetBoxOrder ( Groups , pBox - > GetName ( ) ) , pBox ) ;
}
Boxes = Boxes2 . values ( ) ;
}
QFileIconProvider IconProvider ;
bool ColorIcons = theConf - > GetBool ( " Options/ColorBoxIcons " , false ) ;
QMap < QString , QTreeWidgetItem * > GroupItems ;
foreach ( const CSandBoxPtr & pBox , Boxes )
{
if ( ! pBox - > IsEnabled ( ) | | ! pBox - > GetBool ( " ShowForRunIn " , true ) )
continue ;
if ( ! Filter . isEmpty ( ) & & ! pBox - > GetName ( ) . contains ( Filter , Qt : : CaseInsensitive ) )
continue ;
CSandBoxPlus * pBoxEx = qobject_cast < CSandBoxPlus * > ( pBox . data ( ) ) ;
QTreeWidgetItem * pParent = GetBoxParent ( Groups , GroupItems , m_pTreeBoxes , pBox - > GetName ( ) ) ;
QTreeWidgetItem * pItem = new QTreeWidgetItem ( ) ;
pItem - > setText ( 0 , pBox - > GetName ( ) . replace ( " _ " , " " ) ) ;
pItem - > setData ( 0 , Qt : : UserRole , pBox - > GetName ( ) ) ;
QIcon Icon ;
QString Action = pBox - > GetText ( " DblClickAction " ) ;
if ( ! Action . isEmpty ( ) & & Action . left ( 1 ) ! = " ! " )
Icon = IconProvider . icon ( QFileInfo ( pBoxEx - > GetCommandFile ( Action ) ) ) ;
else if ( ColorIcons )
Icon = theGUI - > GetColorIcon ( pBoxEx - > GetColor ( ) , pBox - > GetActiveProcessCount ( ) ) ;
else
Icon = theGUI - > GetBoxIcon ( pBoxEx - > GetType ( ) , pBox - > GetActiveProcessCount ( ) ! = 0 ) ;
pItem - > setData ( 0 , Qt : : DecorationRole , Icon ) ;
if ( pParent )
pParent - > addChild ( pItem ) ;
else
m_pTreeBoxes - > addTopLevelItem ( pItem ) ;
if ( pBox - > GetName ( ) . compare ( SelectBox , Qt : : CaseInsensitive ) = = 0 )
m_pTreeBoxes - > setCurrentItem ( pItem ) ;
}
m_pTreeBoxes - > expandAll ( ) ;
}
QString CBoxPicker : : GetBoxName ( ) const
{
auto pItem = m_pTreeBoxes - > currentItem ( ) ;
if ( ! pItem ) return QString ( ) ;
return pItem - > data ( 0 , Qt : : UserRole ) . toString ( ) ;
}
QTreeWidgetItem * CBoxPicker : : GetBoxParent ( const QMap < QString , QStringList > & Groups , QMap < QString , QTreeWidgetItem * > & GroupItems , QTreeWidget * treeBoxes , const QString & Name , int Depth )
2021-10-15 16:04:52 +01:00
{
if ( Depth > 100 )
return NULL ;
for ( auto I = Groups . constBegin ( ) ; I ! = Groups . constEnd ( ) ; + + I ) {
if ( I - > contains ( Name ) ) {
if ( I . key ( ) . isEmpty ( ) )
return NULL ; // global group
QTreeWidgetItem * & pParent = GroupItems [ I . key ( ) ] ;
if ( ! pParent ) {
pParent = new QTreeWidgetItem ( ) ;
pParent - > setText ( 0 , I . key ( ) ) ;
QFont fnt = pParent - > font ( 0 ) ;
fnt . setBold ( true ) ;
pParent - > setFont ( 0 , fnt ) ;
2023-07-01 17:54:53 +01:00
if ( QTreeWidgetItem * pParent2 = GetBoxParent ( Groups , GroupItems , treeBoxes , I . key ( ) , + + Depth ) )
2021-10-15 16:04:52 +01:00
pParent2 - > addChild ( pParent ) ;
else
treeBoxes - > addTopLevelItem ( pParent ) ;
}
return pParent ;
}
}
return NULL ;
}
2023-07-01 17:54:53 +01:00
double CBoxPicker : : GetBoxOrder ( const QMap < QString , QStringList > & Groups , const QString & Name , double value , int Depth )
2021-10-15 16:04:52 +01:00
{
if ( Depth > 100 )
return 1000000000 ;
for ( auto I = Groups . constBegin ( ) ; I ! = Groups . constEnd ( ) ; + + I ) {
int Pos = I - > indexOf ( Name ) ;
if ( Pos ! = - 1 ) {
value = double ( Pos ) + value / 10.0 ;
if ( I . key ( ) . isEmpty ( ) )
return value ;
2023-07-01 17:54:53 +01:00
return GetBoxOrder ( Groups , I . key ( ) , value , + + Depth ) ;
2021-10-15 16:04:52 +01:00
}
}
return 1000000000 ;
}
2023-07-01 17:54:53 +01:00
//////////////////////////////////////////////////////////////////////////////////////
// CSelectBoxWindow
//
2021-12-20 11:55:02 +00:00
CSelectBoxWindow : : CSelectBoxWindow ( const QStringList & Commands , const QString & BoxName , const QString & WrkDir , QWidget * parent )
2021-10-15 16:04:52 +01:00
: QDialog ( parent )
{
m_Commands = Commands ;
2021-12-20 11:55:02 +00:00
m_WrkDir = WrkDir ;
2021-10-15 16:04:52 +01:00
Qt : : WindowFlags flags = windowFlags ( ) ;
flags | = Qt : : CustomizeWindowHint ;
//flags &= ~Qt::WindowContextHelpButtonHint;
//flags &= ~Qt::WindowSystemMenuHint;
//flags &= ~Qt::WindowMinMaxButtonsHint;
//flags |= Qt::WindowMinimizeButtonHint;
//flags &= ~Qt::WindowCloseButtonHint;
flags & = ~ Qt : : WindowContextHelpButtonHint ;
//flags &= ~Qt::WindowSystemMenuHint;
setWindowFlags ( flags ) ;
//setWindowState(Qt::WindowActive);
SetForegroundWindow ( ( HWND ) QWidget : : winId ( ) ) ;
2023-10-21 21:15:07 +01:00
bool bAlwaysOnTop = theGUI - > IsAlwaysOnTop ( ) ;
2021-10-15 16:04:52 +01:00
this - > setWindowFlag ( Qt : : WindowStaysOnTopHint , bAlwaysOnTop ) ;
if ( ! bAlwaysOnTop ) {
HWND hWnd = ( HWND ) this - > winId ( ) ;
SetWindowPos ( hWnd , HWND_TOPMOST , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ) ;
QTimer : : singleShot ( 100 , this , [ hWnd ] ( ) {
SetWindowPos ( hWnd , HWND_NOTOPMOST , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ) ;
} ) ;
}
ui . setupUi ( this ) ;
this - > setWindowTitle ( tr ( " Sandboxie-Plus - Run Sandboxed " ) ) ;
connect ( ui . radBoxed , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnBoxType ( ) ) ) ;
2023-01-28 13:05:37 +00:00
connect ( ui . radBoxedNew , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnBoxType ( ) ) ) ;
2021-10-15 16:04:52 +01:00
connect ( ui . radUnBoxed , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnBoxType ( ) ) ) ;
2024-05-18 09:49:20 +01:00
connect ( ui . chkFCP , SIGNAL ( clicked ( bool ) ) , this , SLOT ( OnBoxType ( ) ) ) ;
ui . chkFCP - > setEnabled ( false ) ;
ui . chkFCP - > setVisible ( false ) ;
2021-10-15 16:04:52 +01:00
connect ( ui . buttonBox , SIGNAL ( accepted ( ) ) , SLOT ( OnRun ( ) ) ) ;
connect ( ui . buttonBox , SIGNAL ( rejected ( ) ) , SLOT ( reject ( ) ) ) ;
2023-07-01 17:54:53 +01:00
m_pBoxPicker = new CBoxPicker ( BoxName ) ;
connect ( m_pBoxPicker , SIGNAL ( BoxDblClick ( ) ) , this , SLOT ( OnRun ( ) ) ) ;
ui . treeBoxes - > parentWidget ( ) - > layout ( ) - > replaceWidget ( ui . treeBoxes , m_pBoxPicker ) ;
delete ui . treeBoxes ;
2023-01-29 12:09:10 +00:00
2023-07-01 17:54:53 +01:00
m_pBoxPicker - > setFocus ( ) ;
2023-01-29 12:09:10 +00:00
2024-04-20 14:09:52 +01:00
restoreGeometry ( theConf - > GetBlob ( " SelectBoxWindow/Window_Geometry " ) ) ;
2023-01-29 12:09:10 +00:00
}
CSelectBoxWindow : : ~ CSelectBoxWindow ( )
{
2024-04-20 14:09:52 +01:00
theConf - > SetBlob ( " SelectBoxWindow/Window_Geometry " , saveGeometry ( ) ) ;
2023-01-29 12:09:10 +00:00
}
2024-05-18 09:49:20 +01:00
void CSelectBoxWindow : : ShowFCP ( )
{
ui . chkFCP - > setVisible ( true ) ;
}
2023-01-29 12:09:10 +00:00
void CSelectBoxWindow : : closeEvent ( QCloseEvent * e )
{
//emit Closed();
this - > deleteLater ( ) ;
}
2021-10-15 16:04:52 +01:00
void CSelectBoxWindow : : OnBoxType ( )
{
2024-05-18 09:49:20 +01:00
ui . chkFCP - > setEnabled ( ui . radUnBoxed - > isChecked ( ) ) ;
m_pBoxPicker - > setEnabled ( ui . radBoxed - > isChecked ( ) | | ( ui . chkFCP - > isEnabled ( ) & & ui . chkFCP - > isChecked ( ) ) ) ;
2021-10-15 16:04:52 +01:00
}
void CSelectBoxWindow : : OnRun ( )
{
QString BoxName ;
2024-05-18 09:49:20 +01:00
int Flags = CSbieAPI : : eStartDefault ;
if ( ui . chkAdmin - > isChecked ( ) )
Flags | = CSbieAPI : : eStartElevated ;
2021-10-15 16:04:52 +01:00
if ( ui . radUnBoxed - > isChecked ( ) )
{
if ( QMessageBox ( " Sandboxie-Plus " , tr ( " Are you sure you want to run the program outside the sandbox? " ) , QMessageBox : : Question , QMessageBox : : Yes , QMessageBox : : No | QMessageBox : : Default | QMessageBox : : Escape , QMessageBox : : NoButton , this ) . exec ( ) ! = QMessageBox : : Yes )
return ;
}
2024-05-18 09:49:20 +01:00
if ( ui . radBoxedNew - > isChecked ( ) )
2023-01-28 13:05:37 +00:00
{
2023-01-29 10:48:28 +00:00
BoxName = theGUI - > GetBoxView ( ) - > AddNewBox ( true ) ;
2023-01-28 13:05:37 +00:00
if ( BoxName . isEmpty ( ) ) {
close ( ) ;
return ;
}
}
2024-05-18 09:49:20 +01:00
else if ( ! ui . radUnBoxed - > isChecked ( ) | | ui . chkFCP - > isChecked ( ) )
2023-07-01 17:54:53 +01:00
{
2024-05-18 09:49:20 +01:00
if ( ui . chkFCP - > isChecked ( ) )
Flags | = CSbieAPI : : eStartFCP ;
2023-07-01 17:54:53 +01:00
BoxName = m_pBoxPicker - > GetBoxName ( ) ;
if ( BoxName . isEmpty ( ) ) {
QMessageBox ( " Sandboxie-Plus " , tr ( " Please select a sandbox. " ) , QMessageBox : : Information , QMessageBox : : Ok , QMessageBox : : NoButton , QMessageBox : : NoButton , this ) . exec ( ) ;
return ;
}
2021-10-15 16:04:52 +01:00
}
2024-05-18 09:49:20 +01:00
foreach ( const QString & Command , m_Commands )
theGUI - > RunStart ( BoxName , Command , ( CSbieAPI : : EStartFlags ) Flags , m_WrkDir ) ;
2021-10-15 16:04:52 +01:00
2022-02-02 18:31:03 +00:00
setResult ( 1 ) ;
2021-10-15 16:04:52 +01:00
close ( ) ;
2024-05-18 09:49:20 +01:00
}