1.0.9
This commit is contained in:
parent
45152ce01d
commit
d34731c1ab
|
@ -3,16 +3,19 @@ All notable changes to this project will be documented in this file.
|
|||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [1.0.9 / 5.55.9] - 2022-01-??
|
||||
## [1.0.9 / 5.55.9] - 2022-01-31
|
||||
|
||||
### Added
|
||||
- sandman now causes all boxed processes to update thair path settings in real time when access options were modified
|
||||
- added new maintenance meu option Uninstal All to quickly remove all components when runnign in portable mode
|
||||
- added option to return not to a snapshot but to an empty box state while keeping all snapshots
|
||||
- Sandboxie-Plus.ini can now be placed in C:\ProgramData\Sandboxie-Plus\ folder and takes precedence (for business use)
|
||||
|
||||
### Changed
|
||||
- reworked breakout mechanism to be service based and not alow the parent process to access the broken out child process
|
||||
- enabled creatin of directory junctions for sandboxed processes [#1375](https://github.com/sandboxie-plus/Sandboxie/issues/1375)
|
||||
- changed back to set AutoRecover=y on box creation [#1554](https://github.com/sandboxie-plus/Sandboxie/discussions/1554)
|
||||
- improved snapshot support [#1220](https://github.com/sandboxie-plus/Sandboxie/issues/1220)
|
||||
|
||||
### Fixed
|
||||
- fixed BreakoutProcess not working with EnableObjectFiltering=y
|
||||
|
@ -23,6 +26,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- fixed border issues on maximized windows introduced in the last build [#1561](https://github.com/sandboxie-plus/Sandboxie/issues/1561)
|
||||
- fixed a couple if index overruns (thanks 7eRoM)
|
||||
- fixed issues with sysnative directroy [#1403](https://github.com/sandboxie-plus/Sandboxie/issues/1403)
|
||||
- fixed issue with starting sandman when running sandboxed from context menu [#1579](https://github.com/sandboxie-plus/Sandboxie/issues/1579)
|
||||
- fixed dark mode flash issue with main window creation
|
||||
- fixed issues with snapshot error handling
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ bool TestWriteRight(const QString& Path)
|
|||
return TestFile.remove();
|
||||
}
|
||||
|
||||
CSettings::CSettings(const QString& AppName, QMap<QString, SSetting> DefaultValues, QObject* qObject) : QObject(qObject)
|
||||
CSettings::CSettings(const QString& AppName, bool bShared, QMap<QString, SSetting> DefaultValues, QObject* qObject) : QObject(qObject)
|
||||
{
|
||||
m_ConfigDir = QCoreApplication::applicationDirPath();
|
||||
if (!(m_bPortable = QFile::exists(m_ConfigDir + "/" + AppName + ".ini")))
|
||||
|
@ -20,8 +20,17 @@ CSettings::CSettings(const QString& AppName, QMap<QString, SSetting> DefaultValu
|
|||
QStringList dirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
|
||||
if (dirs.isEmpty())
|
||||
m_ConfigDir = QDir::homePath() + "/." + AppName;
|
||||
//
|
||||
// if shared is set a new ini is created in the shared location
|
||||
// and if present take precedence over an ini in a user location
|
||||
// howeever if the only existing ini is in a user location it will be used
|
||||
//
|
||||
else if(bShared && dirs.count() > 2 && (
|
||||
QFile::exists(dirs[1] + "/" + AppName + "/" + AppName + ".ini") ||
|
||||
!QFile::exists(dirs[0] + "/" + AppName + "/" + AppName + ".ini") ))
|
||||
m_ConfigDir = dirs[1] + "/" + AppName;
|
||||
else
|
||||
m_ConfigDir = dirs.first() + "/" + AppName;
|
||||
m_ConfigDir = dirs[0] + "/" + AppName;
|
||||
QDir().mkpath(m_ConfigDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
virtual bool IsBlob() const {return true;}
|
||||
};
|
||||
|
||||
CSettings(const QString& AppName, QMap<QString, SSetting> DefaultValues = QMap<QString, SSetting>(), QObject* qObject = NULL);
|
||||
CSettings(const QString& AppName, bool bShared = false, QMap<QString, SSetting> DefaultValues = QMap<QString, SSetting>(), QObject* qObject = NULL);
|
||||
virtual ~CSettings();
|
||||
|
||||
bool SetValue(const QString& key, const QVariant& value);
|
||||
|
|
|
@ -51,7 +51,7 @@ CSandBox::CSandBox(const QString& BoxName, class CSbieAPI* pAPI) : CSbieIni(BoxN
|
|||
|
||||
if (cfglvl == 0)
|
||||
{
|
||||
SetBool("AutoRecover", false);
|
||||
SetBool("AutoRecover", true);
|
||||
SetBool("BlockNetworkFiles", true);
|
||||
|
||||
// recovery
|
||||
|
@ -235,7 +235,7 @@ SB_STATUS CSandBox::RemoveBox()
|
|||
return RemoveSection();
|
||||
}
|
||||
|
||||
QList<SBoxSnapshot> CSandBox::GetSnapshots(QString* pCurrent) const
|
||||
QList<SBoxSnapshot> CSandBox::GetSnapshots(QString* pCurrent, QString* pDefault) const
|
||||
{
|
||||
QSettings ini(m_FilePath + "\\Snapshots.ini", QSettings::IniFormat);
|
||||
|
||||
|
@ -259,12 +259,65 @@ QList<SBoxSnapshot> CSandBox::GetSnapshots(QString* pCurrent) const
|
|||
|
||||
if(pCurrent)
|
||||
*pCurrent = ini.value("Current/Snapshot").toString();
|
||||
if(pDefault)
|
||||
*pDefault = ini.value("Current/Default").toString();
|
||||
|
||||
return Snapshots;
|
||||
}
|
||||
|
||||
void CSandBox::SetDefaultSnapshot(QString Default)
|
||||
{
|
||||
QSettings ini(m_FilePath + "\\Snapshots.ini", QSettings::IniFormat);
|
||||
|
||||
ini.setValue("Current/Default", Default);
|
||||
ini.sync();
|
||||
}
|
||||
|
||||
QString CSandBox::GetDefaultSnapshot(QString* pCurrent) const
|
||||
{
|
||||
QSettings ini(m_FilePath + "\\Snapshots.ini", QSettings::IniFormat);
|
||||
|
||||
if(pCurrent)
|
||||
*pCurrent = ini.value("Current/Snapshot").toString();
|
||||
|
||||
return ini.value("Current/Default").toString();
|
||||
}
|
||||
|
||||
QStringList CSandBox__BoxSubFolders = QStringList() << "drive" << "user" << "share";
|
||||
|
||||
struct SBoxDataFile
|
||||
{
|
||||
SBoxDataFile(QString name, bool required, bool recursive) : Name(name), Required(required), Recursive(recursive) {}
|
||||
QString Name;
|
||||
bool Required; // fail on fail
|
||||
bool Recursive;
|
||||
};
|
||||
|
||||
QList<SBoxDataFile> CSandBox__BoxDataFiles = QList<SBoxDataFile>()
|
||||
<< SBoxDataFile("RegHive", true, false)
|
||||
;
|
||||
|
||||
bool CSandBox::IsInitialized() const
|
||||
{
|
||||
if (IsEmpty())
|
||||
return false;
|
||||
|
||||
foreach(const QString & BoxSubFolder, CSandBox__BoxSubFolders) {
|
||||
if (QDir(m_FilePath + "\\" + BoxSubFolder).exists())
|
||||
return true;
|
||||
}
|
||||
foreach(const SBoxDataFile& BoxDataFile, CSandBox__BoxDataFiles) {
|
||||
if (BoxDataFile.Required && QFile::exists(m_FilePath + "\\" + BoxDataFile.Name))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSandBox::HasSnapshots() const
|
||||
{
|
||||
return QFile::exists(m_FilePath + "\\Snapshots.ini");
|
||||
}
|
||||
|
||||
SB_STATUS CSandBox__MoveFolder(const QString& SourcePath, const QString& ParentFolder, const QString& TargetName)
|
||||
{
|
||||
SNtObject src_dir(L"\\??\\" + SourcePath.toStdWString());
|
||||
|
@ -282,7 +335,7 @@ SB_PROGRESS CSandBox::TakeSnapshot(const QString& Name)
|
|||
if (m_pAPI->HasProcesses(m_Name))
|
||||
return SB_ERR(SB_SnapIsRunning, OP_CONFIRM);
|
||||
|
||||
if (IsEmpty())
|
||||
if (!IsInitialized())
|
||||
return SB_ERR(SB_SnapIsEmpty);
|
||||
|
||||
QStringList Snapshots = ini.childGroups();
|
||||
|
@ -295,10 +348,18 @@ SB_PROGRESS CSandBox::TakeSnapshot(const QString& Name)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!QDir().mkdir(m_FilePath + "\\snapshot-" + ID))
|
||||
if (!QDir().mkpath(m_FilePath + "\\snapshot-" + ID))
|
||||
return SB_ERR(SB_SnapMkDirFail);
|
||||
if (!QFile::copy(m_FilePath + "\\RegHive", m_FilePath + "\\snapshot-" + ID + "\\RegHive"))
|
||||
return SB_ERR(SB_SnapCopyDatFail);
|
||||
|
||||
foreach(const SBoxDataFile& BoxDataFile, CSandBox__BoxDataFiles)
|
||||
{
|
||||
if (!QFile::copy(m_FilePath + "\\" + BoxDataFile.Name, m_FilePath + "\\snapshot-" + ID + "\\" + BoxDataFile.Name)) {
|
||||
if (BoxDataFile.Required)
|
||||
return SB_ERR(SB_SnapCopyDatFail);
|
||||
}
|
||||
else if (BoxDataFile.Required) // this one is incremental, hence delete it from the copy root, after it was copied to the snapshot
|
||||
QFile::remove(m_FilePath + "\\" + BoxDataFile.Name);
|
||||
}
|
||||
|
||||
ini.setValue("Snapshot_" + ID + "/Name", Name);
|
||||
ini.setValue("Snapshot_" + ID + "/SnapshotDate", QDateTime::currentDateTime().toTime_t());
|
||||
|
@ -400,14 +461,18 @@ SB_STATUS CSandBox__MergeFolders(const CSbieProgressPtr& pProgress, const QStrin
|
|||
|
||||
SB_STATUS CSandBox__CleanupSnapshot(const QString& Folder)
|
||||
{
|
||||
SNtObject ntHiveFile(L"\\??\\" + (Folder + "\\RegHive").toStdWString());
|
||||
SB_STATUS status = NtDeleteFile(&ntHiveFile.attr);
|
||||
if (NT_SUCCESS(status)) {
|
||||
SNtObject ntSnapshotFile(L"\\??\\" + Folder.toStdWString());
|
||||
status = NtDeleteFile(&ntSnapshotFile.attr);
|
||||
foreach(const SBoxDataFile& BoxDataFile, CSandBox__BoxDataFiles)
|
||||
{
|
||||
SNtObject ntHiveFile(L"\\??\\" + (Folder + "\\" + BoxDataFile.Name).toStdWString());
|
||||
SB_STATUS status = NtDeleteFile(&ntHiveFile.attr);
|
||||
if (NT_SUCCESS(status)) {
|
||||
SNtObject ntSnapshotFile(L"\\??\\" + Folder.toStdWString());
|
||||
status = NtDeleteFile(&ntSnapshotFile.attr);
|
||||
}
|
||||
if(BoxDataFile.Required)
|
||||
if (!NT_SUCCESS(status))
|
||||
return SB_ERR(SB_SnapRmDirFail, QVariantList() << Folder, status);
|
||||
}
|
||||
if (!NT_SUCCESS(status))
|
||||
return SB_ERR(SB_SnapRmDirFail, QVariantList() << Folder, status);
|
||||
return SB_OK;
|
||||
}
|
||||
|
||||
|
@ -485,16 +550,30 @@ SB_PROGRESS CSandBox::SelectSnapshot(const QString& ID)
|
|||
{
|
||||
QSettings ini(m_FilePath + "\\Snapshots.ini", QSettings::IniFormat);
|
||||
|
||||
if (!ini.childGroups().contains("Snapshot_" + ID))
|
||||
if (!ID.isEmpty() && !ini.childGroups().contains("Snapshot_" + ID))
|
||||
return SB_ERR(SB_SnapNotFound);
|
||||
|
||||
if (m_pAPI->HasProcesses(m_Name))
|
||||
return SB_ERR(SB_SnapIsRunning, OP_CONFIRM);
|
||||
|
||||
if (!QFile::remove(m_FilePath + "\\RegHive"))
|
||||
return SB_ERR(SB_SnapDelDatFail);
|
||||
if (!QFile::copy(m_FilePath + "\\snapshot-" + ID + "\\RegHive", m_FilePath + "\\RegHive"))
|
||||
return SB_ERR(SB_SnapCopyDatFail);
|
||||
foreach(const SBoxDataFile& BoxDataFile, CSandBox__BoxDataFiles)
|
||||
{
|
||||
if (!QFile::exists(m_FilePath + "\\" + BoxDataFile.Name))
|
||||
continue;
|
||||
|
||||
if (!QFile::remove(m_FilePath + "\\" + BoxDataFile.Name)) {
|
||||
if (BoxDataFile.Required)
|
||||
return SB_ERR(SB_SnapDelDatFail);
|
||||
}
|
||||
|
||||
if (ID.isEmpty() || BoxDataFile.Recursive)
|
||||
continue; // this one is incremental, don't restore it
|
||||
|
||||
if (!QFile::copy(m_FilePath + "\\snapshot-" + ID + "\\" + BoxDataFile.Name, m_FilePath + "\\" + BoxDataFile.Name)) {
|
||||
if (BoxDataFile.Required)
|
||||
return SB_ERR(SB_SnapCopyDatFail);
|
||||
}
|
||||
}
|
||||
|
||||
ini.setValue("Current/Snapshot", ID);
|
||||
ini.sync();
|
||||
|
|
|
@ -59,11 +59,15 @@ public:
|
|||
virtual bool IsEnabled() const { return m_IsEnabled; }
|
||||
|
||||
virtual bool IsEmpty() const;
|
||||
virtual bool IsInitialized() const;
|
||||
virtual bool HasSnapshots() const;
|
||||
virtual SB_PROGRESS CleanBox();
|
||||
virtual SB_STATUS RenameBox(const QString& NewName);
|
||||
virtual SB_STATUS RemoveBox();
|
||||
|
||||
virtual QList<SBoxSnapshot> GetSnapshots(QString* pCurrent = NULL) const;
|
||||
virtual QList<SBoxSnapshot> GetSnapshots(QString* pCurrent = NULL, QString* pDefault = NULL) const;
|
||||
virtual void SetDefaultSnapshot(QString Default);
|
||||
virtual QString GetDefaultSnapshot(QString* pCurrent = NULL) const;
|
||||
virtual SB_PROGRESS TakeSnapshot(const QString& Name);
|
||||
virtual SB_PROGRESS RemoveSnapshot(const QString& ID);
|
||||
virtual SB_PROGRESS SelectSnapshot(const QString& ID);
|
||||
|
|
|
@ -91,19 +91,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QPushButton" name="btnDeleteAll">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="chkShowAll">
|
||||
<property name="text">
|
||||
|
@ -154,6 +141,25 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QToolButton" name="btnDeleteAll">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete Content</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -163,7 +169,6 @@
|
|||
<tabstops>
|
||||
<tabstop>treeFiles</tabstop>
|
||||
<tabstop>chkShowAll</tabstop>
|
||||
<tabstop>btnDeleteAll</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -60,12 +60,8 @@
|
|||
<string>Selected Snapshot Details</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtName"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
|
@ -77,11 +73,25 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2">
|
||||
<widget class="QPlainTextEdit" name="txtInfo"/>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtName"/>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="chkDefault">
|
||||
<property name="toolTip">
|
||||
<string>When deleting a snapshots content, it will be returned to this snapshot instead of to none.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Default shapsnot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" rowspan="2" colspan="2">
|
||||
<widget class="QPlainTextEdit" name="txtInfo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -98,20 +108,6 @@
|
|||
<string>Snapshot Actions</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="btnRemove">
|
||||
<property name="text">
|
||||
<string>Remove Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="btnSelect">
|
||||
<property name="text">
|
||||
<string>Go to Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="btnTake">
|
||||
<property name="text">
|
||||
|
@ -132,6 +128,32 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="btnRemove">
|
||||
<property name="text">
|
||||
<string>Remove Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QToolButton" name="btnSelect">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Go to Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -147,7 +169,6 @@
|
|||
<tabstops>
|
||||
<tabstop>btnTake</tabstop>
|
||||
<tabstop>treeSnapshots</tabstop>
|
||||
<tabstop>btnSelect</tabstop>
|
||||
<tabstop>btnRemove</tabstop>
|
||||
<tabstop>txtName</tabstop>
|
||||
<tabstop>txtInfo</tabstop>
|
||||
|
|
|
@ -116,10 +116,6 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
|
||||
QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion());
|
||||
|
||||
if (QFile::exists(QCoreApplication::applicationDirPath() + "\\Certificate.dat")) {
|
||||
CSettingsWindow::LoadCertificate();
|
||||
}
|
||||
|
||||
this->setWindowTitle(appTitle);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
@ -303,9 +299,6 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
m_pProgressDialog->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
|
||||
|
||||
|
||||
if (!bAutoRun && g_PendingMessage.isEmpty())
|
||||
show();
|
||||
|
||||
//connect(theAPI, SIGNAL(LogMessage(const QString&, bool)), this, SLOT(OnLogMessage(const QString&, bool)));
|
||||
connect(theAPI, SIGNAL(LogSbieMessage(quint32, const QStringList&, quint32)), this, SLOT(OnLogSbieMessage(quint32, const QStringList&, quint32)));
|
||||
connect(theAPI, SIGNAL(NotAuthorized(bool, bool&)), this, SLOT(OnNotAuthorized(bool, bool&)), Qt::DirectConnection);
|
||||
|
@ -315,6 +308,9 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
|
||||
m_uTimerID = startTimer(1000);
|
||||
|
||||
if (!bAutoRun && g_PendingMessage.isEmpty())
|
||||
SafeShow(this);
|
||||
|
||||
OnStatusChanged();
|
||||
if (CSbieUtils::IsRunning(CSbieUtils::eAll) || theConf->GetBool("Options/StartIfStopped", true))
|
||||
{
|
||||
|
@ -899,11 +895,20 @@ void CSandMan::OnBoxClosed(const QString& BoxName)
|
|||
|
||||
if (!pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false) && !pBox->IsEmpty())
|
||||
{
|
||||
bool DeleteShapshots = false;
|
||||
// if this box auto deletes first show the recovry dialog with the option to abort deletion
|
||||
if(!theGUI->OpenRecovery(pBox, true)) // unless no files are found than continue silently
|
||||
if(!theGUI->OpenRecovery(pBox, DeleteShapshots, true)) // unless no files are found than continue silently
|
||||
return;
|
||||
|
||||
SB_PROGRESS Status = pBox->CleanBox();
|
||||
SB_PROGRESS Status;
|
||||
if (!DeleteShapshots && pBox->HasSnapshots()) { // in auto delete mdoe always return to last snapshot
|
||||
QString Current;
|
||||
pBox->GetDefaultSnapshot(&Current);
|
||||
Status = pBox->SelectSnapshot(Current);
|
||||
}
|
||||
else // if there are no snapshots jut use the normal cleaning procedure
|
||||
Status = pBox->CleanBox();
|
||||
|
||||
if (Status.GetStatus() == OP_ASYNC)
|
||||
AddAsyncOp(Status.GetValue());
|
||||
}
|
||||
|
@ -932,9 +937,10 @@ void CSandMan::OnStatusChanged()
|
|||
if (isConnected)
|
||||
{
|
||||
QString SbiePath = theAPI->GetSbiePath();
|
||||
OnLogMessage(tr("Sbie Directory: %1").arg(SbiePath));
|
||||
OnLogMessage(tr("Sbie+ Version: %1 (%2)").arg(GetVersion()).arg(theAPI->GetVersion()));
|
||||
OnLogMessage(tr("Installation Directory: %1").arg(SbiePath));
|
||||
OnLogMessage(tr("Sandboxie-Plus Version: %1 (%2)").arg(GetVersion()).arg(theAPI->GetVersion()));
|
||||
OnLogMessage(tr("Loaded Config: %1").arg(theAPI->GetIniPath()));
|
||||
OnLogMessage(tr("Data Directory: %1").arg(QString(theConf->GetConfigDir()).replace("/","\\")));
|
||||
|
||||
//statusBar()->showMessage(tr("Driver version: %1").arg(theAPI->GetVersion()));
|
||||
|
||||
|
@ -1006,6 +1012,10 @@ void CSandMan::OnStatusChanged()
|
|||
else {
|
||||
g_Certificate.clear();
|
||||
g_CertInfo.State = 0;
|
||||
|
||||
QString CertPath = QCoreApplication::applicationDirPath() + "\\Certificate.dat";
|
||||
if(QFile::exists(CertPath)) // always delete invalid certificates
|
||||
WindowsMoveFile(CertPath.replace("/", "\\"), "");
|
||||
}
|
||||
|
||||
g_FeatureFlags = theAPI->GetFeatureFlags();
|
||||
|
@ -1237,7 +1247,7 @@ void CSandMan::OnFileToRecover(const QString& BoxName, const QString& FilePath,
|
|||
m_pPopUpWindow->AddFileToRecover(FilePath, BoxPath, pBox, ProcessId);
|
||||
}
|
||||
|
||||
bool CSandMan::OpenRecovery(const CSandBoxPtr& pBox, bool bCloseEmpty)
|
||||
bool CSandMan::OpenRecovery(const CSandBoxPtr& pBox, bool& DeleteShapshots, bool bCloseEmpty)
|
||||
{
|
||||
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
|
||||
if (pBoxEx->m_pRecoveryWnd != NULL) {
|
||||
|
@ -1251,6 +1261,7 @@ bool CSandMan::OpenRecovery(const CSandBoxPtr& pBox, bool bCloseEmpty)
|
|||
}
|
||||
else if (pRecoveryWindow->exec() != 1)
|
||||
return false;
|
||||
DeleteShapshots = pRecoveryWindow->IsDeleteShapshots();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ public slots:
|
|||
void OnQueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 RequestId, const QVariantMap& Data);
|
||||
void OnFileToRecover(const QString& BoxName, const QString& FilePath, const QString& BoxPath, quint32 ProcessId);
|
||||
|
||||
bool OpenRecovery(const CSandBoxPtr& pBox, bool bCloseEmpty = false);
|
||||
bool OpenRecovery(const CSandBoxPtr& pBox, bool& DeleteShapshots, bool bCloseEmpty = false);
|
||||
class CRecoveryWindow* ShowRecovery(const CSandBoxPtr& pBox, bool bFind = true);
|
||||
|
||||
void UpdateSettings();
|
||||
|
|
|
@ -911,6 +911,9 @@ void CSbieView::OnSandBoxAction(QAction* Action)
|
|||
{
|
||||
for (QList<QPair<QString, QString>>::iterator I = Settings.begin(); I != Settings.end(); ++I)
|
||||
{
|
||||
if (I->first == "FileRootPath" && !I->second.toUpper().contains("%SANDBOX%"))
|
||||
continue; // skip the FileRootPath if it does not contain a %SANDBOX%
|
||||
|
||||
Status = theAPI->SbieIniSet(Name, I->first, I->second, CSbieAPI::eIniInsert, false);
|
||||
if (Status.IsError())
|
||||
break;
|
||||
|
@ -957,6 +960,8 @@ void CSbieView::OnSandBoxAction(QAction* Action)
|
|||
}
|
||||
else if (Action == m_pMenuCleanUp)
|
||||
{
|
||||
bool DeleteShapshots = false;
|
||||
|
||||
if (SandBoxes.count() == 1)
|
||||
{
|
||||
if (SandBoxes.first()->IsEmpty()) {
|
||||
|
@ -967,18 +972,27 @@ void CSbieView::OnSandBoxAction(QAction* Action)
|
|||
if (theConf->GetBool("Options/ShowRecovery", false))
|
||||
{
|
||||
// Use recovery dialog in place of the confirmation messagebox for box clean up
|
||||
if(!theGUI->OpenRecovery(SandBoxes.first()))
|
||||
if(!theGUI->OpenRecovery(SandBoxes.first(), DeleteShapshots))
|
||||
return;
|
||||
}
|
||||
else if(QMessageBox("Sandboxie-Plus", tr("Do you want to delete the content of the selected sandbox?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
else if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to delete the content of the selected sandbox?")
|
||||
, tr("Also delete all Snapshots"), &DeleteShapshots, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes)
|
||||
return;
|
||||
}
|
||||
else if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the content of multiple sandboxes?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
else if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you really want to delete the content of all sellected sandboxes?")
|
||||
, tr("Also delete all Snapshots"), &DeleteShapshots, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes)
|
||||
return;
|
||||
|
||||
foreach(const CSandBoxPtr & pBox, SandBoxes)
|
||||
{
|
||||
SB_PROGRESS Status = pBox->CleanBox();
|
||||
SB_PROGRESS Status;
|
||||
if (!DeleteShapshots && pBox->HasSnapshots()) {
|
||||
QString Default = pBox->GetDefaultSnapshot();
|
||||
Status = pBox->SelectSnapshot(Default);
|
||||
}
|
||||
else // if there are no snapshots jut use the normal cleaning procedure
|
||||
Status = pBox->CleanBox();
|
||||
|
||||
if (Status.GetStatus() == OP_ASYNC)
|
||||
theGUI->AddAsyncOp(Status.GetValue());
|
||||
else if (Status.IsError())
|
||||
|
@ -991,7 +1005,7 @@ void CSbieView::OnSandBoxAction(QAction* Action)
|
|||
{
|
||||
bool State = false;
|
||||
if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to terminate all processes in the selected sandbox(es)?")
|
||||
, tr("Terminate without asking"), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes, QMessageBox::Information) != QDialogButtonBox::Yes)
|
||||
, tr("Terminate without asking"), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes)
|
||||
return;
|
||||
|
||||
if (State)
|
||||
|
@ -1067,7 +1081,7 @@ void CSbieView::OnProcessAction()
|
|||
|
||||
bool State = false;
|
||||
if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to %1 %2?").arg(((QAction*)sender())->text().toLower()).arg(Processes.count() == 1 ? Processes[0]->GetProcessName() : tr("the selected processes"))
|
||||
, tr("Terminate without asking"), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes, QMessageBox::Information) != QDialogButtonBox::Yes)
|
||||
, tr("Terminate without asking"), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes) != QDialogButtonBox::Yes)
|
||||
return;
|
||||
|
||||
if (State)
|
||||
|
@ -1243,21 +1257,6 @@ QList<CBoxedProcessPtr> CSbieView::GetSelectedProcesses()
|
|||
return List;
|
||||
}
|
||||
|
||||
/*void CSbieView::UpdateRunMenu()
|
||||
{
|
||||
while (m_iMenuRun < m_pMenuRun->actions().count())
|
||||
m_pMenuRun->removeAction(m_pMenuRun->actions().at(m_iMenuRun));
|
||||
|
||||
QStringList RunOptions = theConf->ListKeys("RunOptions");
|
||||
foreach(const QString& RunOption, RunOptions)
|
||||
{
|
||||
StrPair NameCmd = Split2(theConf->GetString("RunOptions/" + RunOption), "|");
|
||||
|
||||
QAction* pAction = m_pMenuRun->addAction(NameCmd.first, this, SLOT(OnSandBoxAction()));
|
||||
pAction->setData(NameCmd.second);
|
||||
}
|
||||
}*/
|
||||
|
||||
void CSbieView::UpdateRunMenu(const CSandBoxPtr& pBox)
|
||||
{
|
||||
while (m_iMenuRun < m_pMenuRun->actions().count())
|
||||
|
|
|
@ -49,6 +49,7 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
m_LastTargetIndex = 0;
|
||||
m_bTargetsChanged = false;
|
||||
m_bReloadPending = false;
|
||||
m_DeleteShapshots = false;
|
||||
|
||||
#ifdef WIN32
|
||||
QStyle* pStyle = QStyleFactory::create("windows");
|
||||
|
@ -99,6 +100,10 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
ui.btnRecover->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
ui.btnRecover->setMenu(pRecMenu);
|
||||
|
||||
QMenu* pDelMenu = new QMenu(ui.btnDeleteAll);
|
||||
pDelMenu->addAction(tr("Delete evertyhign including all snapshots"), this, SLOT(OnDeleteEverything()));
|
||||
ui.btnDeleteAll->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
ui.btnDeleteAll->setMenu(pDelMenu);
|
||||
|
||||
restoreGeometry(theConf->GetBlob("RecoveryWindow/Window_Geometry"));
|
||||
|
||||
|
@ -145,6 +150,7 @@ int CRecoveryWindow::exec()
|
|||
{
|
||||
//QDialog::setWindowModality(Qt::WindowModal);
|
||||
ui.btnDeleteAll->setVisible(true);
|
||||
SafeShow(this);
|
||||
return QDialog::exec();
|
||||
}
|
||||
|
||||
|
@ -223,6 +229,12 @@ void CRecoveryWindow::OnDeleteAll()
|
|||
this->close();
|
||||
}
|
||||
|
||||
void CRecoveryWindow::OnDeleteEverything()
|
||||
{
|
||||
m_DeleteShapshots = true;
|
||||
OnDeleteAll();
|
||||
}
|
||||
|
||||
void CRecoveryWindow::AddFile(const QString& FilePath, const QString& BoxPath)
|
||||
{
|
||||
ui.chkShowAll->setTristate(true);
|
||||
|
|
|
@ -39,6 +39,8 @@ public:
|
|||
CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent = Q_NULLPTR);
|
||||
~CRecoveryWindow();
|
||||
|
||||
bool IsDeleteShapshots() { return m_DeleteShapshots; }
|
||||
|
||||
virtual void accept() {}
|
||||
virtual void reject() { this->close(); }
|
||||
|
||||
|
@ -56,6 +58,7 @@ private slots:
|
|||
void OnRecover();
|
||||
void OnTargetChanged();
|
||||
void OnDeleteAll();
|
||||
void OnDeleteEverything();
|
||||
void OnCloseUntil();
|
||||
void OnCount(quint32 fileCount, quint32 folderCount, quint64 totalSize);
|
||||
|
||||
|
@ -80,6 +83,7 @@ protected:
|
|||
int m_LastTargetIndex;
|
||||
bool m_bTargetsChanged;
|
||||
bool m_bReloadPending;
|
||||
bool m_DeleteShapshots;
|
||||
|
||||
private:
|
||||
Ui::RecoveryWindow ui;
|
||||
|
|
|
@ -811,7 +811,7 @@ void CSettingsWindow::CertChanged()
|
|||
void CSettingsWindow::LoadCertificate()
|
||||
{
|
||||
QString CertPath;
|
||||
if (theAPI->IsConnected())
|
||||
if (theAPI && theAPI->IsConnected())
|
||||
CertPath = theAPI->GetSbiePath() + "\\Certificate.dat";
|
||||
else
|
||||
CertPath = QCoreApplication::applicationDirPath() + "\\Certificate.dat";
|
||||
|
|
|
@ -96,10 +96,11 @@ union SCertInfo {
|
|||
quint64 State;
|
||||
struct {
|
||||
quint32
|
||||
valid : 1,
|
||||
expired : 1,
|
||||
outdated : 1,
|
||||
reservd_1 : 5,
|
||||
valid : 1, // certificate is active
|
||||
expired : 1, // certificate is expired but may be active
|
||||
outdated : 1, // certificate is expired, not anymore valid for the current build
|
||||
business : 1, // certificate is siutable for business use
|
||||
reservd_1 : 4,
|
||||
reservd_2 : 8,
|
||||
reservd_3 : 8,
|
||||
reservd_4 : 8;
|
||||
|
|
|
@ -49,11 +49,18 @@ CSnapshotsWindow::CSnapshotsWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
connect(ui.treeSnapshots->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(UpdateSnapshot(const QModelIndex&)));
|
||||
connect(ui.treeSnapshots, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnSelectSnapshot()));
|
||||
|
||||
|
||||
QMenu* pSelMenu = new QMenu(ui.btnSelect);
|
||||
pSelMenu->addAction(tr("Revert to empty box"), this, SLOT(OnSelectEmpty()));
|
||||
ui.btnSelect->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
ui.btnSelect->setMenu(pSelMenu);
|
||||
|
||||
connect(ui.btnTake, SIGNAL(clicked(bool)), this, SLOT(OnTakeSnapshot()));
|
||||
connect(ui.btnSelect, SIGNAL(clicked(bool)), this, SLOT(OnSelectSnapshot()));
|
||||
connect(ui.btnRemove, SIGNAL(clicked(bool)), this, SLOT(OnRemoveSnapshot()));
|
||||
|
||||
connect(ui.txtName, SIGNAL(textEdited(const QString&)), this, SLOT(SaveInfo()));
|
||||
connect(ui.chkDefault, SIGNAL(clicked(bool)), this, SLOT(OnChangeDefault()));
|
||||
connect(ui.txtInfo, SIGNAL(textChanged()), this, SLOT(SaveInfo()));
|
||||
|
||||
ui.groupBox->setEnabled(false);
|
||||
|
@ -84,13 +91,16 @@ void CSnapshotsWindow::closeEvent(QCloseEvent *e)
|
|||
void CSnapshotsWindow::UpdateSnapshots(bool AndSelect)
|
||||
{
|
||||
m_SnapshotMap.clear();
|
||||
QList<SBoxSnapshot> SnapshotList = m_pBox->GetSnapshots(&m_CurSnapshot);
|
||||
QList<SBoxSnapshot> SnapshotList = m_pBox->GetSnapshots(&m_CurSnapshot, &m_DefaultSnapshot);
|
||||
foreach(const SBoxSnapshot& Snapshot, SnapshotList)
|
||||
{
|
||||
QVariantMap BoxSnapshot;
|
||||
BoxSnapshot["ID"] = Snapshot.ID;
|
||||
BoxSnapshot["ParentID"] = Snapshot.Parent;
|
||||
BoxSnapshot["Name"] = Snapshot.NameStr;
|
||||
if(m_DefaultSnapshot == Snapshot.ID)
|
||||
BoxSnapshot["Name"] = Snapshot.NameStr + tr(" (default)");
|
||||
else
|
||||
BoxSnapshot["Name"] = Snapshot.NameStr;
|
||||
BoxSnapshot["Info"] = Snapshot.InfoStr;
|
||||
BoxSnapshot["Date"] = Snapshot.SnapDate;
|
||||
if(m_CurSnapshot == Snapshot.ID)
|
||||
|
@ -131,6 +141,7 @@ void CSnapshotsWindow::UpdateSnapshot(const QModelIndex& Index)
|
|||
|
||||
m_SaveInfoPending = -1;
|
||||
ui.txtName->setText(BoxSnapshot["Name"].toString());
|
||||
ui.chkDefault->setChecked(ID == m_DefaultSnapshot);
|
||||
ui.txtInfo->setPlainText(BoxSnapshot["Info"].toString());
|
||||
m_SaveInfoPending = 0;
|
||||
|
||||
|
@ -173,10 +184,37 @@ void CSnapshotsWindow::OnSelectSnapshot()
|
|||
//QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex);
|
||||
QVariant ID = m_pSnapshotModel->GetItemID(Index);
|
||||
|
||||
SelectSnapshot(ID.toString());
|
||||
}
|
||||
|
||||
void CSnapshotsWindow::OnSelectEmpty()
|
||||
{
|
||||
SelectSnapshot(QString());
|
||||
}
|
||||
|
||||
void CSnapshotsWindow::SelectSnapshot(const QString& ID)
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to switch the active snapshot? Doing so will delete the current state!"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
HandleResult(m_pBox->SelectSnapshot(ID.toString()));
|
||||
HandleResult(m_pBox->SelectSnapshot(ID));
|
||||
}
|
||||
|
||||
void CSnapshotsWindow::OnChangeDefault()
|
||||
{
|
||||
QModelIndex Index = ui.treeSnapshots->currentIndex();
|
||||
//QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index);
|
||||
//QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex);
|
||||
QVariant ID = m_pSnapshotModel->GetItemID(Index);
|
||||
|
||||
if (ui.chkDefault->isChecked())
|
||||
m_DefaultSnapshot = ID.toString();
|
||||
else
|
||||
m_DefaultSnapshot.clear();
|
||||
|
||||
m_pBox->SetDefaultSnapshot(m_DefaultSnapshot);
|
||||
|
||||
UpdateSnapshots();
|
||||
}
|
||||
|
||||
void CSnapshotsWindow::OnRemoveSnapshot()
|
||||
|
|
|
@ -27,6 +27,8 @@ private slots:
|
|||
|
||||
void OnTakeSnapshot();
|
||||
void OnSelectSnapshot();
|
||||
void OnSelectEmpty();
|
||||
void OnChangeDefault();
|
||||
void OnRemoveSnapshot();
|
||||
|
||||
void OnSaveInfo();
|
||||
|
@ -34,10 +36,12 @@ private slots:
|
|||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
void SelectSnapshot(const QString& ID);
|
||||
void HandleResult(SB_PROGRESS Status);
|
||||
|
||||
CSandBoxPtr m_pBox;
|
||||
QString m_CurSnapshot;
|
||||
QString m_DefaultSnapshot;
|
||||
QMap<QVariant, QVariantMap> m_SnapshotMap;
|
||||
|
||||
QVariant m_SellectedID;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//#include "../MiscHelpers/Common/qRC4.h"
|
||||
#include "../MiscHelpers/Common/Common.h"
|
||||
#include <windows.h>
|
||||
#include "./Windows/SettingsWindow.h"
|
||||
|
||||
CSettings* theConf = NULL;
|
||||
|
||||
|
@ -85,10 +86,18 @@ int main(int argc, char *argv[])
|
|||
else if (app.sendMessage("ShowWnd"))
|
||||
return 0;
|
||||
|
||||
theConf = new CSettings("Sandboxie-Plus");
|
||||
|
||||
if (QFile::exists(QCoreApplication::applicationDirPath() + "\\Certificate.dat")) {
|
||||
CSettingsWindow::LoadCertificate();
|
||||
g_CertInfo.business = GetArguments(g_Certificate, L'\n', L':').value("TYPE").toUpper().contains("BUSINESS");
|
||||
}
|
||||
|
||||
// use a shared setting location when used in a business environment for easier administration
|
||||
theConf = new CSettings("Sandboxie-Plus", g_CertInfo.business);
|
||||
|
||||
//QThreadPool::globalInstance()->setMaxThreadCount(theConf->GetInt("Options/MaxThreadPool", 10));
|
||||
|
||||
|
||||
CSandMan* pWnd = new CSandMan();
|
||||
|
||||
QObject::connect(&app, SIGNAL(messageReceived(const QString&)), pWnd, SLOT(OnMessage(const QString&)));
|
||||
|
|
Loading…
Reference in New Issue