2020-11-28 16:20:56 +00:00
# include "stdafx.h"
# include "RecoveryWindow.h"
# include "SandMan.h"
# include "../MiscHelpers/Common/Settings.h"
# include "../MiscHelpers/Common/TreeItemModel.h"
# include "../MiscHelpers/Common/Common.h"
# include <QFileIconProvider>
CRecoveryWindow : : CRecoveryWindow ( const CSandBoxPtr & pBox , QWidget * parent )
: QDialog ( parent )
{
ui . setupUi ( this ) ;
this - > setWindowTitle ( tr ( " %1 - File Recovery " ) . arg ( pBox - > GetName ( ) ) ) ;
m_pBox = pBox ;
2021-01-18 12:04:14 +00:00
m_pCounter = NULL ;
2020-11-28 16:20:56 +00:00
# ifdef WIN32
QStyle * pStyle = QStyleFactory : : create ( " windows " ) ;
ui . treeFiles - > setStyle ( pStyle ) ;
# endif
2021-01-18 12:04:14 +00:00
ui . treeFiles - > setExpandsOnDoubleClick ( false ) ;
2020-11-28 16:20:56 +00:00
ui . btnDeleteAll - > setVisible ( false ) ;
m_pFileModel = new CSimpleTreeModel ( ) ;
m_pFileModel - > SetUseIcons ( true ) ;
m_pFileModel - > AddColumn ( tr ( " File Name " ) , " FileName " ) ;
m_pFileModel - > AddColumn ( tr ( " File Size " ) , " FileSize " ) ;
m_pFileModel - > AddColumn ( tr ( " Full Path " ) , " DiskPath " ) ;
/*m_pSortProxy = new CSortFilterProxyModel(false, this);
m_pSortProxy - > setSortRole ( Qt : : EditRole ) ;
m_pSortProxy - > setSourceModel ( m_pSnapshotModel ) ;
m_pSortProxy - > setDynamicSortFilter ( true ) ; */
//ui.treeSnapshots->setItemDelegate(theGUI->GetItemDelegate());
//ui.treeSnapshots->setModel(m_pSortProxy);
ui . treeFiles - > setModel ( m_pFileModel ) ;
ui . treeFiles - > setSelectionMode ( QAbstractItemView : : ExtendedSelection ) ;
//connect(ui.treeFiles, SIGNAL(clicked(const QModelIndex&)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
//connect(ui.treeFiles->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
//connect(ui.treeFiles, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnSelectSnapshot()));
connect ( ui . btnAddFolder , SIGNAL ( pressed ( ) ) , this , SLOT ( OnAddFolder ( ) ) ) ;
2021-01-18 12:04:14 +00:00
connect ( ui . chkShowAll , SIGNAL ( clicked ( bool ) ) , this , SLOT ( FindFiles ( ) ) ) ;
2020-12-22 14:50:58 +00:00
connect ( ui . btnRefresh , SIGNAL ( pressed ( ) ) , this , SLOT ( FindFiles ( ) ) ) ;
2020-11-28 16:20:56 +00:00
connect ( ui . btnRecover , SIGNAL ( pressed ( ) ) , this , SLOT ( OnRecover ( ) ) ) ;
connect ( ui . btnRecoverTo , SIGNAL ( pressed ( ) ) , this , SLOT ( OnRecoverTo ( ) ) ) ;
connect ( ui . btnDeleteAll , SIGNAL ( pressed ( ) ) , this , SLOT ( OnDeleteAll ( ) ) ) ;
connect ( ui . btnClose , SIGNAL ( pressed ( ) ) , this , SLOT ( close ( ) ) ) ;
restoreGeometry ( theConf - > GetBlob ( " RecoveryWindow/Window_Geometry " ) ) ;
QByteArray Columns = theConf - > GetBlob ( " RecoveryWindow/FileTree_Columns " ) ;
if ( ! Columns . isEmpty ( ) )
ui . treeFiles - > header ( ) - > restoreState ( Columns ) ;
for ( int i = 0 ; i < m_pFileModel - > columnCount ( ) ; i + + )
m_pFileModel - > SetColumnEnabled ( i , true ) ;
foreach ( const QString & NtFolder , m_pBox - > GetTextList ( " RecoverFolder " , true , true ) )
{
QString Folder = theAPI - > Nt2DosPath ( NtFolder ) ;
2021-01-18 12:04:14 +00:00
m_RecoveryFolders . append ( Folder ) ;
2020-11-28 16:20:56 +00:00
}
}
CRecoveryWindow : : ~ CRecoveryWindow ( )
{
theConf - > SetBlob ( " RecoveryWindow/Window_Geometry " , saveGeometry ( ) ) ;
theConf - > SetBlob ( " RecoveryWindow/FileTree_Columns " , ui . treeFiles - > header ( ) - > saveState ( ) ) ;
}
int CRecoveryWindow : : exec ( )
{
ui . btnDeleteAll - > setVisible ( true ) ;
return QDialog : : exec ( ) ;
}
void CRecoveryWindow : : closeEvent ( QCloseEvent * e )
{
this - > deleteLater ( ) ;
}
void CRecoveryWindow : : OnAddFolder ( )
{
2020-12-22 14:50:58 +00:00
QString Folder = QFileDialog : : getExistingDirectory ( this , tr ( " Select Directory " ) ) . replace ( " / " , " \\ " ) ; ;
2020-11-28 16:20:56 +00:00
if ( Folder . isEmpty ( ) )
return ;
if ( m_RecoveryFolders . contains ( Folder ) )
return ;
2021-01-18 12:04:14 +00:00
m_RecoveryFolders . append ( Folder ) ;
2020-11-28 16:20:56 +00:00
m_pBox - > AppendText ( " RecoverFolder " , Folder ) ;
2021-01-18 12:04:14 +00:00
FindFiles ( Folder ) ;
2020-11-28 16:20:56 +00:00
m_pFileModel - > Sync ( m_FileMap ) ;
ui . treeFiles - > expandAll ( ) ;
}
void CRecoveryWindow : : OnDeleteAll ( )
{
this - > setResult ( 1 ) ;
this - > close ( ) ;
}
int CRecoveryWindow : : FindFiles ( )
{
2021-01-18 12:04:14 +00:00
if ( m_pCounter = = NULL ) {
m_pCounter = new CRecoveryCounter ( m_pBox - > GetFileRoot ( ) , this ) ;
connect ( m_pCounter , SIGNAL ( Count ( quint32 , quint32 , quint64 ) ) , this , SLOT ( OnCount ( quint32 , quint32 , quint64 ) ) ) ;
}
2020-11-28 16:20:56 +00:00
m_FileMap . clear ( ) ;
int Count = 0 ;
2021-01-18 12:04:14 +00:00
if ( ui . chkShowAll - > isChecked ( ) )
{
for ( char drive = ' A ' ; drive < = ' Z ' ; drive + + )
Count + = FindBoxFiles ( " \\ drive \\ " + QString ( drive ) ) ;
if ( m_pBox - > GetBool ( " SeparateUserFolders " , true ) ) {
Count + = FindBoxFiles ( " \\ user \\ current " ) ;
Count + = FindBoxFiles ( " \\ user \\ all " ) ;
Count + = FindBoxFiles ( " \\ user \\ public " ) ;
}
Count + = FindBoxFiles ( " \\ share " ) ;
}
else
{
foreach ( const QString & Folder , m_RecoveryFolders )
Count + = FindFiles ( Folder ) ;
}
2020-11-28 16:20:56 +00:00
m_pFileModel - > Sync ( m_FileMap ) ;
ui . treeFiles - > expandAll ( ) ;
return Count ;
}
int CRecoveryWindow : : FindFiles ( const QString & Folder )
2021-01-18 12:04:14 +00:00
{
return FindFiles ( Folder , theAPI - > GetBoxedPath ( m_pBox , Folder ) , Folder ) ;
}
int CRecoveryWindow : : FindBoxFiles ( const QString & Folder )
{
return FindFiles ( Folder , m_pBox - > GetFileRoot ( ) + Folder , theAPI - > GetRealPath ( m_pBox , m_pBox - > GetFileRoot ( ) + Folder ) ) ;
}
int CRecoveryWindow : : FindFiles ( const QString & RecParent , const QString & BoxedFolder , const QString & RealFolder )
2020-11-28 16:20:56 +00:00
{
QFileIconProvider IconProvider ;
int Count = 0 ;
quint64 TotalSize = 0 ;
QStringList Folders ;
2021-01-18 12:04:14 +00:00
Folders . append ( BoxedFolder ) ;
2020-11-28 16:20:56 +00:00
do {
QDir Dir ( Folders . takeFirst ( ) ) ;
foreach ( const QFileInfo & Info , Dir . entryInfoList ( QDir : : AllEntries ) )
{
QString Name = Info . fileName ( ) ;
if ( Name = = " . " | | Name = = " .. " )
continue ;
QString Path = Info . filePath ( ) . replace ( " / " , " \\ " ) ;
if ( Info . isFile ( ) )
{
Count + + ;
TotalSize + = Info . size ( ) ;
2021-01-18 12:04:14 +00:00
QString RealPath = RealFolder + Path . mid ( BoxedFolder . length ( ) ) ;
2020-11-28 16:20:56 +00:00
QVariantMap RecFile ;
RecFile [ " ID " ] = RealPath ;
RecFile [ " ParentID " ] = RecParent ;
RecFile [ " FileName " ] = Name ;
RecFile [ " FileSize " ] = FormatSize ( Info . size ( ) ) ;
RecFile [ " DiskPath " ] = RealPath ;
RecFile [ " BoxPath " ] = Path ;
RecFile [ " Icon " ] = IconProvider . icon ( Info ) ;
m_FileMap . insert ( RealPath , RecFile ) ;
}
else
Folders . append ( Path ) ;
}
} while ( ! Folders . isEmpty ( ) ) ;
if ( Count > 0 )
{
QVariantMap RecFolder ;
RecFolder [ " ID " ] = RecParent ;
RecFolder [ " ParentID " ] = QVariant ( ) ;
RecFolder [ " FileName " ] = RecParent ;
RecFolder [ " FileSize " ] = FormatSize ( TotalSize ) ;
//RecFolder["DiskPath"];
//RecFolder["BoxPath"];
RecFolder [ " Icon " ] = IconProvider . icon ( QFileIconProvider : : Folder ) ;
m_FileMap . insert ( RecParent , RecFolder ) ;
}
return Count ;
}
void CRecoveryWindow : : RecoverFiles ( bool bBrowse )
{
2021-01-18 12:04:14 +00:00
bool HasShare = false ;
2020-11-28 16:20:56 +00:00
QMap < QString , QString > FileMap ;
foreach ( const QModelIndex & Index , ui . treeFiles - > selectionModel ( ) - > selectedIndexes ( ) )
{
//QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index);
//QVariant ID = m_pFileModel->GetItemID(ModelIndex);
QVariant ID = m_pFileModel - > GetItemID ( Index ) ;
QVariantMap File = m_FileMap . value ( ID ) ;
if ( File . isEmpty ( ) )
continue ;
if ( ! File [ " ParentID " ] . isNull ( ) )
2021-01-18 12:04:14 +00:00
{
if ( File [ " DiskPath " ] . toString ( ) . indexOf ( " \\ device \\ mup " ) = = 0 )
HasShare = true ;
2020-11-28 16:20:56 +00:00
FileMap [ File [ " BoxPath " ] . toString ( ) ] = File [ " DiskPath " ] . toString ( ) ;
2021-01-18 12:04:14 +00:00
}
2020-11-28 16:20:56 +00:00
else
{
for ( int i = 0 ; i < m_pFileModel - > rowCount ( Index ) ; i + + )
{
QModelIndex ChildIndex = m_pFileModel - > index ( i , 0 , Index ) ;
QVariant ChildID = m_pFileModel - > GetItemID ( ChildIndex ) ;
QVariantMap File = m_FileMap . value ( ChildID ) ;
if ( File . isEmpty ( ) )
continue ;
2021-01-18 12:04:14 +00:00
if ( File [ " DiskPath " ] . toString ( ) . indexOf ( " \\ device \\ mup " ) = = 0 )
HasShare = true ;
2020-11-28 16:20:56 +00:00
FileMap [ File [ " BoxPath " ] . toString ( ) ] = File [ " DiskPath " ] . toString ( ) ;
}
}
}
2021-01-18 12:04:14 +00:00
QString RecoveryFolder ;
if ( HasShare & & ! bBrowse )
{
if ( ! bBrowse )
QMessageBox : : warning ( this , " Sandboxie-Plus " , tr ( " One or more selected files are located on a network share, and must be recovered to a local drive, please select a folder to recover all selected files to. " ) ) ;
RecoveryFolder = QFileDialog : : getExistingDirectory ( this , tr ( " Select Directory " ) ) . replace ( " / " , " \\ " ) ;
if ( RecoveryFolder . isEmpty ( ) )
return ;
}
2020-11-28 16:20:56 +00:00
QList < QPair < QString , QString > > FileList ;
for ( QMap < QString , QString > : : const_iterator I = FileMap . begin ( ) ; I ! = FileMap . end ( ) ; + + I )
{
QString BoxedFilePath = I . key ( ) ;
QString RecoveryPath = I . value ( ) ;
if ( ! RecoveryFolder . isEmpty ( ) )
{
QString FileName = RecoveryPath . mid ( RecoveryPath . lastIndexOf ( " \\ " ) + 1 ) ;
RecoveryPath = RecoveryFolder + " \\ " + FileName ;
}
FileList . append ( qMakePair ( BoxedFilePath , RecoveryPath ) ) ;
}
SB_PROGRESS Status = theGUI - > RecoverFiles ( FileList ) ;
if ( Status . GetStatus ( ) = = OP_ASYNC )
{
connect ( Status . GetValue ( ) . data ( ) , SIGNAL ( Finished ( ) ) , this , SLOT ( FindFiles ( ) ) ) ;
theGUI - > AddAsyncOp ( Status . GetValue ( ) ) ;
}
}
2021-01-18 12:04:14 +00:00
void CRecoveryWindow : : OnCount ( quint32 fileCount , quint32 folderCount , quint64 totalSize )
{
ui . lblInfo - > setText ( tr ( " There are %1 files and %2 folders in the sandbox, occupying %3 bytes of disk space. " ) . arg ( fileCount ) . arg ( folderCount ) . arg ( FormatSize ( totalSize ) ) ) ;
}
void CRecoveryCounter : : run ( )
{
quint32 fileCount = 0 ;
quint32 folderCount = 0 ;
quint64 totalSize = 0 ;
QStringList Folders ;
Folders . append ( m_BoxPath ) ;
do {
if ( ! m_run ) break ;
QDir Dir ( Folders . takeFirst ( ) ) ;
foreach ( const QFileInfo & Info , Dir . entryInfoList ( QDir : : AllEntries ) )
{
if ( ! m_run ) break ;
QString Name = Info . fileName ( ) ;
if ( Name = = " . " | | Name = = " .. " )
continue ;
QString Path = Info . filePath ( ) . replace ( " / " , " \\ " ) ;
if ( Info . isFile ( ) )
{
fileCount + + ;
totalSize + = Info . size ( ) ;
}
else
{
Folders . append ( Path ) ;
folderCount + + ;
}
}
emit Count ( fileCount , folderCount , totalSize ) ;
} while ( ! Folders . isEmpty ( ) ) ;
}