Build 0.9.4

This commit is contained in:
DavidXanatos 2021-08-22 21:20:22 +02:00
parent 4ba9b95b10
commit 9ee6b24eb3
36 changed files with 1165 additions and 251 deletions

View File

@ -4,6 +4,26 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [0.9.4 / 5.51.4] - 2021-08-22
### added
- added clear commands to log sub menus [#391](https://github.com/sandboxie-plus/Sandboxie/issues/391)
- added option to disable prompt to confirm process termination [#514](https://github.com/sandboxie-plus/Sandboxie/issues/514)
- added settings to sandboxie-plus.ini "Options/InstantRecovery" to use the recovery window instad of the notification popUp [#988](https://github.com/sandboxie-plus/Sandboxie/issues/988)
- added ability to rename a non empty sandbox [#1100](https://github.com/sandboxie-plus/Sandboxie/issues/1100)
- added ability to remove a non empty sandbox
- added file browser window to sandman ui to cover the files view functionality of sbie ctrl [#578](https://github.com/sandboxie-plus/Sandboxie/issues/578)
### Changed
- generic error in sbie ui now show the status code as hex and provide a string description when available
### fixed
- "del" shortcut to terminate a process did not always work
- fixed group display issue [#1094](https://github.com/sandboxie-plus/Sandboxie/issues/1094)
- fixed issue when using run sandboxed on a file located already in a sandbox [#1099](https://github.com/sandboxie-plus/Sandboxie/issues/1099)
## [0.9.3 / 5.51.3] - 2021-08-08
### added

View File

@ -21,8 +21,8 @@
#ifndef _MY_VERSION_H
#define _MY_VERSION_H
#define MY_VERSION_BINARY 5,51,3
#define MY_VERSION_STRING "5.51.3"
#define MY_VERSION_BINARY 5,51,4
#define MY_VERSION_STRING "5.51.4"
#define MY_VERSION_COMPAT "5.51.0" // this refers to the driver ABI compatibility
// These #defines are used by either Resource Compiler, or by NSIC installer

View File

@ -538,9 +538,6 @@ _FX BOOL Proc_SetProcessMitigationPolicy(
if (MitigationPolicy == ProcessDynamicCodePolicy)
return TRUE;
//if (MitigationPolicy == ProcessUserShadowStackPolicy)
// return TRUE;
return __sys_SetProcessMitigationPolicy(MitigationPolicy, lpBuffer, dwLength);
}

View File

@ -112,7 +112,7 @@ static P_NtTraceEvent __sys_NtTraceEvent = NULL;
static ULONG_PTR *SysInfo_JobCallbackData = NULL;
BOOLEAN SysInfo_UseSbieJob = TRUE;
BOOLEAN SysInfo_UseSbieJob = FALSE;
BOOLEAN SysInfo_CanUseJobs = FALSE;
//---------------------------------------------------------------------------

View File

@ -27,7 +27,7 @@
#include "core/dll/sbiedll.h"
#include "common/defines.h"
#include "common/my_version.h"
#include <psapi.h> // For access to GetModuleFileNameEx
#include "sbieiniserver.h"
//---------------------------------------------------------------------------
// Defines
@ -1131,6 +1131,34 @@ MSG_HEADER *PipeServer::Call(MSG_HEADER *msg)
}
//---------------------------------------------------------------------------
// IsCallerAdmin
//---------------------------------------------------------------------------
bool PipeServer::IsCallerAdmin()
{
CLIENT_TLS_DATA *TlsData =
(CLIENT_TLS_DATA *)TlsGetValue(m_instance->m_TlsIndex);
bool IsAdmin = false;
ULONG processId = (ULONG)(ULONG_PTR)TlsData->PortMessage->ClientId.UniqueProcess;
HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
if (processHandle != NULL) {
HANDLE hToken;
if (OpenProcessToken(processHandle, TOKEN_QUERY, &hToken)) {
IsAdmin = SbieIniServer::TokenIsAdmin(hToken, true);
CloseHandle(hToken);
}
CloseHandle(processHandle);
}
return IsAdmin;
}
//---------------------------------------------------------------------------
// IsCallerSigned
//---------------------------------------------------------------------------

View File

@ -130,6 +130,12 @@ public:
MSG_HEADER *Call(MSG_HEADER *msg);
/*
* Checks if the calling process has administrative privileges
*/
static bool IsCallerAdmin();
/*
* Checks if the calling process has a valid signature
*/

View File

@ -174,7 +174,7 @@ MSG_HEADER *ProcessServer::KillOneHandler(
// match session id and box name
//
if (CallerSessionId != TargetSessionId)
if (CallerSessionId != TargetSessionId && !PipeServer::IsCallerAdmin())
return SHORT_REPLY(STATUS_ACCESS_DENIED);
if (CallerBoxName[0] && _wcsicmp(CallerBoxName, TargetBoxName) != 0)
@ -248,7 +248,7 @@ MSG_HEADER *ProcessServer::KillAllHandler(
if (TargetSessionId == -1)
TargetSessionId = CallerSessionId;
else if (CallerSessionId != TargetSessionId)
else if (CallerSessionId != TargetSessionId && !PipeServer::IsCallerAdmin())
return SHORT_REPLY(STATUS_ACCESS_DENIED);
if (CallerBoxName[0] && _wcsicmp(CallerBoxName, TargetBoxName) != 0)

View File

@ -498,7 +498,7 @@ bool SbieIniServer::SetUserSettingsSectionName(HANDLE hToken)
//---------------------------------------------------------------------------
bool SbieIniServer::TokenIsAdmin(HANDLE hToken)
bool SbieIniServer::TokenIsAdmin(HANDLE hToken, bool OnlyFull)
{
//
// check if token is member of the Administrators group
@ -522,7 +522,7 @@ bool SbieIniServer::TokenIsAdmin(HANDLE hToken)
// on Windows Vista, check for UAC split token
//
if (! b) {
if (! b || OnlyFull) {
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi) && osvi.dwMajorVersion >= 6) {
@ -531,7 +531,7 @@ bool SbieIniServer::TokenIsAdmin(HANDLE hToken)
hToken, (TOKEN_INFORMATION_CLASS)TokenElevationType,
&elevationType, sizeof(elevationType), &len);
if (b && (elevationType != TokenElevationTypeFull &&
elevationType != TokenElevationTypeLimited))
(OnlyFull || elevationType != TokenElevationTypeLimited)))
b = FALSE;
}
}

View File

@ -37,6 +37,8 @@ public:
~SbieIniServer();
static bool TokenIsAdmin(HANDLE hToken, bool OnlyFull = false);
protected:
static MSG_HEADER *Handler(void *_this, MSG_HEADER *msg);
@ -78,8 +80,6 @@ protected:
bool GetIniPath(WCHAR **IniPath, WCHAR **TmpPath,
BOOLEAN *IsHomePath = NULL, BOOLEAN* IsUTF8 = NULL);
bool TokenIsAdmin(HANDLE hToken);
ULONG IsCallerAuthorized(HANDLE hToken, const WCHAR *Password);
void LockConf(WCHAR *IniPath);

View File

@ -0,0 +1,193 @@
#include "stdafx.h"
#include "OtherFunctions.h"
//////////////////////////////////////////////////////////////////////////////////////////
// File system functions
//
QString ReadFileAsString(const QString& filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream stream(&file);
QString content = stream.readAll();
file.close();
content.remove("\r").replace("\n","\r\n");
return content;
}
return "";
}
bool WriteStringToFile(const QString& filename, const QString& content)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return false;
QTextStream out(&file);
out << QString(content).remove("\r");
file.close();
return true;
}
bool CreateDir(const QString& path)
{
QDir dir(path);
if (dir.exists())
return true;
return dir.mkpath(path);
}
bool DeleteDir(const QString& path, bool bEmpty)
{
bool error = false;
QDir delDir(path);
QStringList fileNames = delDir.entryList();
foreach (const QString& name, fileNames)
{
if (name.compare(".") == 0 || name.compare("..") == 0)
continue;
QString src = path;
src = src.append("/%1").arg(name);
QFileInfo srcInfo(src);
if (srcInfo.isDir())
{
if(!DeleteDir(src, bEmpty))
error = true;
}
else if(bEmpty)
error = true;
else
{
if(!QFile::remove(src))
error = true;
}
}
if (!error)
{
if(!QDir().rmdir(path))
error = true;
}
return !error;
}
bool CopyDir(const QString& srcDirPath, const QString& destDirPath, bool bMove)
{
QDir srcDir(srcDirPath);
if (!srcDir.exists())
return false;
QDir destDir(destDirPath);
if (!destDir.exists() && !destDir.mkdir(destDirPath))
return false;
QStringList fileNames = srcDir.entryList();
foreach (const QString& name, fileNames)
{
if (name.compare(".") == 0 || name.compare("..") == 0)
continue;
QString src = srcDirPath;
src = src + "/" + name;
QString dst = destDirPath;
QFileInfo srcInfo(src);
if (srcInfo.isDir())
{
dst = dst.append("/" + srcInfo.baseName());
CopyDir(src, dst, bMove);
}
else
{
dst = dst.append("/%1").arg(name);
if(bMove)
QFile::rename(src, dst);
else
QFile::copy(src, dst);
}
}
if(bMove)
QDir().rmdir(srcDirPath);
return true;
}
QStringList ListDir(const QString& srcDirPath)
{
QStringList FileList;
QDir srcDir(srcDirPath);
if (!srcDir.exists())
return FileList;
QStringList Files = srcDir.entryList(QDir::Files);
foreach (const QString& FileName, Files)
FileList.append(FileName);
QStringList Dirs = srcDir.entryList(QDir::Dirs);
foreach (const QString& DirName, Dirs)
{
if (DirName.compare(".") == 0 || DirName.compare("..") == 0)
continue;
QStringList SubFiles = ListDir(srcDirPath + DirName + "/");
foreach (const QString& FileName, SubFiles)
FileList.append(DirName + "/" + FileName);
}
return FileList;
}
bool SafeRemove(const QString& FilePath)
{
bool bRemoved = false;
for(int i=0; i < 100; i++) // try for 10 sec
{
bRemoved = QFile::remove(FilePath);
if(bRemoved)
break;
QThread::currentThread()->msleep(100);
}
return bRemoved;
}
QString GetRelativeSharedPath(const QString& fullPath, const QStringList& shared, QString& rootPath)
{
QString relativePath = fullPath;
bool bFound = false;
foreach (QString curShared, shared)
{
curShared = curShared.replace("\\", "/");
int length = curShared.length();
if (length == 0)
continue;
QFileInfo fileInfo = QFileInfo(fullPath);
if (!fileInfo.isDir())
{
QString curDir = curShared.left(curShared.lastIndexOf('/'));
length = curDir.length();
if (fullPath.left(length).compare(curDir) == 0) {
rootPath = relativePath.left(length+1);
relativePath.remove(0, length+1);
return relativePath;
}
}
else
{
if (fullPath.left(length).compare(curShared) == 0) {
rootPath = relativePath.left(length);
relativePath.remove(0, length);
return relativePath;
}
}
}
int length = relativePath.lastIndexOf("/");
rootPath = relativePath.left(length+1);
relativePath.remove(0, length+1);
return relativePath;
}
QString NameOfFile(const QString& FileName)
{
int Begin = FileName.lastIndexOf("/") + 1;
int End = FileName.lastIndexOf(".");
if(End!= -1)
return FileName.mid(Begin, End - Begin);
return FileName.mid(Begin);
}

View File

@ -0,0 +1,129 @@
#pragma once
#include "../mischelpers_global.h"
/////////////////////////
// HeapSort
template <class T>
void HeapSortAux(T &refArray, quint32 first, quint32 last, void (*HeapMov)(T &, quint32, quint32), bool (*HeapCmp)(T &, quint32, quint32))
{
quint32 r;
for (r = first; !(r & 0x80000000) && (r<<1) < last;)
{
quint32 r2 = (r<<1)+1;
if (r2 != last)
{
if(HeapCmp(refArray, r2, r2+1))
r2++;
}
if(HeapCmp(refArray, r, r2))
{
HeapMov(refArray, r2, r);
r = r2;
}
else
break;
}
}
template <class T>
void HeapSort(T &refArray, void (*HeapMov)(T &, quint32, quint32), bool (*HeapCmp)(T &, quint32, quint32))
{
int n = refArray.size();
if (n > 0)
{
int r;
for (r = n/2; r--;)
HeapSortAux(refArray, r, n-1, HeapMov, HeapCmp);
for (r = n; --r;)
{
HeapMov(refArray, r, 0);
HeapSortAux(refArray, 0, r-1, HeapMov, HeapCmp);
}
}
}
/////////////////////////
// MergeSort
template<typename I> void MergeSortAux(I& lst, I& res, quint32 begin, quint32 middle, quint32 end, void (*Cpy)(I& T, I& S, quint32 t, quint32 s), bool (*Cmp)(I& A, quint32 l, quint32 r))
{
quint32 a = begin;
quint32 b = middle;
quint32 r = 0;
while (a < middle && b < end)
{
if (Cmp(lst, a, b))
Cpy(res, lst, r++, a++);
else
Cpy(res, lst, r++, b++);
}
while (a < middle)
Cpy(res, lst, r++, a++);
while (b < end)
Cpy(res, lst, r++, b++);
a = begin;
r = 0;
while (a < end)
Cpy(lst, res, a++, r++);
}
template<typename I> void MergeSort(I& lst, I& res, int begin, int end, void (*Cpy)(I& T, I& S, quint32 t, quint32 s), bool (*Cmp)(I& A, quint32 l, quint32 r))
{
quint32 s = end-begin;
if (s > 1)
{
quint32 middle = begin+s/2;
MergeSort(lst, res, begin, middle, Cpy, Cmp);
MergeSort(lst, res, middle, end, Cpy, Cmp);
MergeSortAux(lst, res, begin, middle, end, Cpy, Cmp);
}
}
template<typename I> void MergeSort(I& lst, void (*Cpy)(I& T, I& S, quint32 t, quint32 s), bool (*Cmp)(I& A, quint32 l, quint32 r))
{
I res = lst; // temporary space
MergeSort(lst, res, 0, lst.size(), Cpy, Cmp);
}
/////////////////////////
// Reverse
template <class T>
void Reverse(T* Data, size_t Size)
{
for(size_t i=0; i < Size/2; i++)
{
T Temp = Data[i];
Data[i] = Data[Size - 1 - i];
Data[Size - 1 - i] = Temp;
}
}
//inline QString tr(const char* s) {return QObject::tr(s);}
//////////////////////////////////////////////////////////////////////////////////////////
// File system functions
//
MISCHELPERS_EXPORT QString ReadFileAsString(const QString& filename);
MISCHELPERS_EXPORT bool WriteStringToFile(const QString& filename, const QString& content);
MISCHELPERS_EXPORT bool CreateDir(const QString& path);
MISCHELPERS_EXPORT bool DeleteDir(const QString& path, bool bEmpty = false);
MISCHELPERS_EXPORT bool CopyDir(const QString& srcDirPath, const QString& destDirPath, bool bMove = false);
MISCHELPERS_EXPORT QStringList ListDir(const QString& srcDirPath);
MISCHELPERS_EXPORT bool SafeRemove(const QString& path);
MISCHELPERS_EXPORT QString GetRelativeSharedPath(const QString& fullPath, const QStringList& shared, QString& rootPath);
MISCHELPERS_EXPORT QString NameOfFile(const QString& FileName);
#ifdef _DEBUG
MISCHELPERS_EXPORT void GlobalTest();
#endif

View File

@ -2,20 +2,21 @@
#include "../mischelpers_global.h"
class MISCHELPERS_EXPORT CProgressDialog : public QMainWindow
class MISCHELPERS_EXPORT CProgressDialog : public QDialog
{
Q_OBJECT
public:
CProgressDialog(const QString& Prompt, QWidget* parent = 0)
: QMainWindow(parent)
: QDialog(parent)
{
setWindowFlags(Qt::Tool);
m_pMainWidget = new QWidget();
//m_pMainWidget = new QWidget();
m_pMainLayout = new QGridLayout(this);
m_pMainWidget->setLayout(m_pMainLayout);
this->setCentralWidget(m_pMainWidget);
this->setLayout(m_pMainLayout);
//m_pMainWidget->setLayout(m_pMainLayout);
//this->setCentralWidget(m_pMainWidget);
m_pMessageLabel = new QLabel(Prompt);
m_pMessageLabel->setMinimumWidth(300);
@ -87,7 +88,7 @@ protected:
{
if (e->timerId() != m_TimerId)
{
QMainWindow::timerEvent(e);
QDialog::timerEvent(e);
return;
}

View File

@ -6,6 +6,7 @@ HEADERS += ./MiscHelpers.h \
./mischelpers_global.h \
./stdafx.h \
./Common/Common.h \
./Common/OtherFunctions.h \
./Common/DebugHelpers.h \
./Common/ExitDialog.h \
./Common/FlexError.h \
@ -39,6 +40,7 @@ SOURCES += ./MiscHelpers.cpp \
./Common/CheckableMessageBox.cpp \
./Common/ComboInputDialog.cpp \
./Common/Common.cpp \
./Common/OtherFunctions.cpp \
./Common/DebugHelpers.cpp \
./Common/Finder.cpp \
./Common/FlowLayout.cpp \

View File

@ -192,6 +192,7 @@
<ClCompile Include="Common\KeyValueInputDialog.cpp" />
<ClCompile Include="Common\ListItemModel.cpp" />
<ClCompile Include="Common\MultiLineInputDialog.cpp" />
<ClCompile Include="Common\OtherFunctions.cpp" />
<ClCompile Include="Common\PanelView.cpp" />
<ClCompile Include="Common\qRC4.cpp" />
<ClCompile Include="Common\NetworkAccessManager.cpp" />
@ -236,6 +237,7 @@
<QtMoc Include="Common\TreeViewEx.h" />
<QtMoc Include="Common\TreeWidgetEx.h" />
<ClInclude Include="Common\IconExtreactor.h" />
<ClInclude Include="Common\OtherFunctions.h" />
<ClInclude Include="Common\qRC4.h" />
<QtMoc Include="Common\NetworkAccessManager.h" />
<ClInclude Include="Common\Xml.h" />

View File

@ -93,6 +93,9 @@
<ClCompile Include="Common\NetworkAccessManager.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="Common\OtherFunctions.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="MiscHelpers.h">
@ -128,6 +131,9 @@
<ClInclude Include="Common\qRC4.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="Common\OtherFunctions.h">
<Filter>Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mischelpers_global.h">

View File

@ -196,22 +196,34 @@ void CSandBox::CleanBoxAsync(const CSbieProgressPtr& pProgress, const QStringLis
pProgress->Finish(Status);
}
SB_STATUS CSandBox__MoveFolder(const QString& SourcePath, const QString& ParentFolder, const QString& TargetName);
SB_STATUS CSandBox::RenameBox(const QString& NewName)
{
if (!IsEmpty())
return SB_ERR(SB_RemNotEmpty);
SB_STATUS Status = CSbieAPI::ValidateName(NewName);
if (Status.IsError())
return Status;
if (QDir(m_FilePath).exists())
{
QStringList FilePath = m_FilePath.split("\\");
if (FilePath.last().isEmpty()) FilePath.removeLast();
QString Name = FilePath.takeLast();
if (Name.compare(m_Name, Qt::CaseInsensitive) == 0)
{
Status = CSandBox__MoveFolder(m_FilePath, FilePath.join("\\"), NewName);
if (Status.IsError())
return Status;
}
}
return RenameSection(NewName);
}
SB_STATUS CSandBox::RemoveBox()
{
if (!IsEmpty())
return SB_ERR(SB_DelNotEmpty);
//if (!IsEmpty())
// return SB_ERR(SB_DelNotEmpty);
return RemoveSection();
}

View File

@ -1028,6 +1028,11 @@ QString CSbieAPI::GetStartPath() const
return m_SbiePath + "\\" + QString::fromWCharArray(SBIESTART_EXE);
}
quint32 CSbieAPI::GetSessionID() const
{
return m->sessionId;
}
SB_STATUS CSbieAPI::ReloadBoxes(bool bFullUpdate)
{
QMap<QString, CSandBoxPtr> OldSandBoxes = m_SandBoxes;
@ -1063,20 +1068,20 @@ SB_STATUS CSbieAPI::ReloadBoxes(bool bFullUpdate)
return SB_OK;
}
QString CSbieAPI__FormatNtStatus(NTSTATUS nsCode)
QString CSbieAPI__FormatNtStatus(long nsCode)
{
static HMODULE hNtDll = NULL;
if(!hNtDll)
hNtDll = GetModuleHandle(L"ntdll.dll");
if (hNtDll == NULL)
return "???";
return QString();
WCHAR* ret_str = NULL;
DWORD dwRes = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
hNtDll, RtlNtStatusToDosError(nsCode), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&ret_str, 0, NULL);
QString qStr = QString::fromWCharArray(ret_str);
QString qStr = dwRes > 0 ? QString::fromWCharArray(ret_str) : QString();
LocalFree(ret_str);
return qStr;
}
@ -1225,13 +1230,13 @@ SB_STATUS CSbieAPI::CreateBox(const QString& BoxName, bool bReLoad)
return Status;
}
SB_STATUS CSbieAPI__GetProcessPIDs(SSbieAPI* m, const QString& BoxName, ULONG* pids, ULONG* count)
SB_STATUS CSbieAPI__GetProcessPIDs(SSbieAPI* m, const QString& BoxName, bool bAllSessions, ULONG* pids, ULONG* count)
{
WCHAR box_name[34];
BoxName.toWCharArray(box_name); // fix-me: potential overflow
box_name[BoxName.size()] = L'\0';
BOOLEAN all_sessions = TRUE;
ULONG which_session = 0; // -1 for current session
BOOLEAN all_sessions = bAllSessions ? TRUE : false;
ULONG which_session = -1; // -1 means current session, ignoreewd when all_sessions == true
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
@ -1249,16 +1254,16 @@ SB_STATUS CSbieAPI__GetProcessPIDs(SSbieAPI* m, const QString& BoxName, ULONG* p
return SB_OK;
}
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep)
SB_STATUS CSbieAPI::UpdateProcesses(bool bKeep, bool bAllSessions)
{
ULONG count = 0;
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, "", NULL, &count); // query the count
SB_STATUS Status = CSbieAPI__GetProcessPIDs(m, "", bAllSessions, NULL, &count); // query the count
if (Status.IsError())
count += 128; // add some extra space
ULONG* boxed_pids = new ULONG[count];
Status = CSbieAPI__GetProcessPIDs(m, "", boxed_pids, &count); // query the count
Status = CSbieAPI__GetProcessPIDs(m, "", bAllSessions, boxed_pids, &count); // query the count
if (Status.IsError()) {
delete[] boxed_pids;
return Status;
@ -1382,7 +1387,7 @@ finish:
bool CSbieAPI::HasProcesses(const QString& BoxName)
{
ULONG count;
return CSbieAPI__GetProcessPIDs(m, BoxName, NULL, &count) && (count > 0);
return CSbieAPI__GetProcessPIDs(m, BoxName, false, NULL, &count) && (count > 0);
}
SB_STATUS CSbieAPI__QueryBoxPath(SSbieAPI* m, const WCHAR *box_name, WCHAR *out_file_path, WCHAR *out_key_path, WCHAR *out_ipc_path,

View File

@ -59,7 +59,7 @@ public:
static SB_STATUS ValidateName(const QString& BoxName);
virtual SB_STATUS CreateBox(const QString& BoxName, bool bReLoad = true);
virtual SB_STATUS UpdateProcesses(bool bKeep);
virtual SB_STATUS UpdateProcesses(bool bKeep, bool bAllSessions);
//virtual SB_STATUS UpdateProcesses(bool bKeep, const CSandBoxPtr& pBox);
virtual QMap<QString, CSandBoxPtr> GetAllBoxes() { return m_SandBoxes; }
@ -123,6 +123,9 @@ public:
virtual SB_STATUS RunStart(const QString& BoxName, const QString& Command, QProcess* pProcess = NULL, bool Elevated = false);
virtual QString GetStartPath() const;
virtual quint32 GetSessionID() const;
enum ESbieQueuedRequests
{
ePrintSpooler = -1,

View File

@ -5,6 +5,10 @@
#define OP_CONFIRM (3)
#define OP_CANCELED (4)
#include "qsbieapi_global.h"
QString QSBIEAPI_EXPORT CSbieAPI__FormatNtStatus(long nsCode);
enum ESbieMsgCodes
{
SB_Generic = 0,
@ -24,8 +28,8 @@ enum ESbieMsgCodes
SB_FailedKillAll,
SB_DeleteProtect,
SB_DeleteError,
SB_RemNotEmpty,
SB_DelNotEmpty,
//SB_RemNotEmpty,
//SB_DelNotEmpty,
SB_FailedMoveDir,
SB_SnapMkDirFail,
SB_SnapCopyRegFail,
@ -60,7 +64,7 @@ public:
CSbieStatus(ESbieMsgCodes MsgCode, long Status) : CSbieStatus(MsgCode, QVariantList(), Status)
{
}
CSbieStatus(long Status) : CSbieStatus(SB_Generic, QVariantList(), Status)
CSbieStatus(long Status) : CSbieStatus(SB_Generic, QVariantList() << CSbieAPI__FormatNtStatus(Status), Status)
{
}
CSbieStatus(const CSbieStatus& other) : CSbieStatus()

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FileBrowserWindow</class>
<widget class="QWidget" name="FileBrowserWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>573</width>
<height>451</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>SandboxiePlus - Snapshots</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTreeView" name="treeFiles"/>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -54,37 +54,6 @@
<layout class="QGridLayout" name="gridLayout_9">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_8">
<item row="5" column="1" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="chkPanic">
<property name="text">
<string>Hotkey for terminating all boxed processes:</string>
</property>
</widget>
</item>
<item>
<widget class="QKeySequenceEdit" name="keyPanic"/>
</item>
</layout>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkShowRecovery">
<property name="text">
<string>Show first recovery window when emptying sandboxes</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Restart required (!)</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QCheckBox" name="chkSandboxUrls">
<property name="text">
@ -95,9 +64,6 @@
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="onClose"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="uiLang"/>
</item>
@ -111,7 +77,10 @@
</property>
</widget>
</item>
<item row="10" column="2">
<item row="10" column="1">
<widget class="QComboBox" name="onClose"/>
</item>
<item row="11" column="2">
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -134,7 +103,21 @@
</property>
</widget>
</item>
<item row="7" column="0">
<item row="6" column="1" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="chkPanic">
<property name="text">
<string>Hotkey for terminating all boxed processes:</string>
</property>
</widget>
</item>
<item>
<widget class="QKeySequenceEdit" name="keyPanic"/>
</item>
</layout>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="font">
<font>
@ -148,7 +131,7 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>On main window close:</string>
@ -158,14 +141,41 @@
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QCheckBox" name="chkShowTray">
<property name="text">
<string>Show Sys-Tray</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="0" column="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Restart required (!)</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QCheckBox" name="chkShowRecovery">
<property name="text">
<string>Show first recovery window when emptying sandboxes</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>UI Language:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="11" column="1">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -178,20 +188,17 @@
</property>
</spacer>
</item>
<item row="6" column="1" colspan="2">
<item row="7" column="1" colspan="2">
<widget class="QCheckBox" name="chkWatchConfig">
<property name="text">
<string>Watch Sandboxie.ini for changes</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_19">
<item row="5" column="1" colspan="2">
<widget class="QCheckBox" name="chkInstantRecovery">
<property name="text">
<string>UI Language:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<string>Show the recovery window outright instead of only notifying about recoverable files</string>
</property>
</widget>
</item>
@ -299,19 +306,6 @@
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="2" colspan="4">
<widget class="QLineEdit" name="fileRoot"/>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="chkSeparateUserFolders">
<property name="text">
<string>Separate user folders</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="4">
<widget class="QLineEdit" name="regRoot"/>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_16">
<property name="text">
@ -325,6 +319,81 @@
</property>
</widget>
</item>
<item row="6" column="1" colspan="5">
<widget class="QCheckBox" name="chkWFP">
<property name="text">
<string>Use Windows Filtering Platform to restrict network access (experimental)</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="4">
<widget class="QLineEdit" name="fileRoot"/>
</item>
<item row="4" column="2" colspan="4">
<widget class="QLineEdit" name="ipcRoot"/>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/ipcrootpath&quot;&gt;ipc root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QCheckBox" name="chkAutoRoot">
<property name="text">
<string>Portable root folder</string>
</property>
</widget>
</item>
<item row="7" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/filerootpath&quot;&gt;file system root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2" colspan="4">
<widget class="QLineEdit" name="regRoot"/>
</item>
<item row="7" column="4">
<spacer name="horizontalSpacer_5">
<property name="orientation">
@ -338,6 +407,19 @@
</property>
</spacer>
</item>
<item row="7" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_43">
<property name="font">
@ -352,13 +434,6 @@
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QCheckBox" name="chkAutoRoot">
<property name="text">
<string>Portable root folder</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="label_45">
<property name="font">
@ -373,55 +448,6 @@
</property>
</widget>
</item>
<item row="6" column="1" colspan="5">
<widget class="QCheckBox" name="chkWFP">
<property name="text">
<string>Use Windows Filtering Platform to restrict network access (experimental)</string>
</property>
</widget>
</item>
<item row="7" column="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/ipcrootpath&quot;&gt;ipc root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Sandbox &lt;a href=&quot;sbie://docs/filerootpath&quot;&gt;file system root&lt;/a&gt;: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="2" colspan="4">
<widget class="QLineEdit" name="ipcRoot"/>
</item>
<item row="1" column="6">
<widget class="QPushButton" name="btnBrowse">
<property name="maximumSize">
@ -435,31 +461,12 @@
</property>
</widget>
</item>
<item row="7" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="2" column="2">
<widget class="QCheckBox" name="chkSeparateUserFolders">
<property name="text">
<string>Separate user folders</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
</layout>
</item>
@ -784,13 +791,27 @@
<item row="3" column="2" colspan="2">
<widget class="QLabel" name="lblSupportCert">
<property name="text">
<string>Supporters of the Sandboxie-Plus project receive a &lt;a href=&quot;https://sandboxie-plus.com/go.php?to=certificate&quot;&gt;supporter certificate&lt;/a&gt;. It's like a license key but for awesome people using free software. :-)</string>
<string>Supporters of the Sandboxie-Plus project receive a &lt;a href=&quot;https://sandboxie-plus.com/go.php?to=certificate&quot;&gt;supporter certificate&lt;/a&gt;. It's like a license key but for awesome people using open source software. :-)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QLabel" name="lblCertExp">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
<kerning>true</kerning>
</font>
</property>
<property name="text">
<string>This supporter certificate has expired, please get an updated certificate.</string>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="5" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">

View File

@ -43,7 +43,7 @@ public:
if (msg->message == WM_NOTIFY)
{
return true;
//return true;
}
else if (msg->message == WM_DEVICECHANGE)
{
@ -152,7 +152,6 @@ CSandMan::CSandMan(QWidget *parent)
m_pPanelSplitter->addWidget(m_pBoxView);
connect(m_pBoxView->GetTree()->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(OnSelectionChanged()));
connect(m_pBoxView, SIGNAL(RecoveryRequested(const QString&)), this, SLOT(OpenRecovery(const QString&)));
//m_pPanelSplitter->addWidget();
@ -165,14 +164,20 @@ CSandMan::CSandMan(QWidget *parent)
//m_pMessageLog->GetView()->setItemDelegate(theGUI->GetItemDelegate());
((QTreeWidgetEx*)m_pMessageLog->GetView())->setHeaderLabels(tr("Time|Message").split("|"));
m_pMessageLog->GetMenu()->insertAction(m_pMessageLog->GetMenu()->actions()[0], m_pCleanUpMsgLog);
m_pMessageLog->GetMenu()->insertSeparator(m_pMessageLog->GetMenu()->actions()[0]);
m_pMessageLog->GetView()->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_pMessageLog->GetView()->setSortingEnabled(false);
m_pLogTabs->addTab(m_pMessageLog, tr("Sbie Messages"));
//
m_pTraceView = new CTraceView(this);
m_pTraceView->GetMenu()->insertAction(m_pTraceView->GetMenu()->actions()[0], m_pCleanUpTrace);
m_pTraceView->GetMenu()->insertSeparator(m_pTraceView->GetMenu()->actions()[0]);
m_pLogTabs->addTab(m_pTraceView, tr("Trace Log"));
m_pHotkeyManager = new UGlobalHotkeys(this);
@ -210,6 +215,7 @@ CSandMan::CSandMan(QWidget *parent)
//m_pTrayBoxes->setHeaderLabels(tr(" Sandbox").split("|"));
m_pTrayBoxes->setHeaderHidden(true);
m_pTrayBoxes->setSelectionMode(QAbstractItemView::NoSelection);
//m_pTrayBoxes->setSelectionMode(QAbstractItemView::ExtendedSelection);
pLayout->insertSpacing(0, 1);// 32);
@ -271,13 +277,14 @@ CSandMan::CSandMan(QWidget *parent)
m_pKeepTerminated->setChecked(theConf->GetBool("Options/KeepTerminated"));
m_pShowAllSessions->setChecked(theConf->GetBool("Options/ShowAllSessions"));
m_pProgressDialog = new CProgressDialog("", this);
m_pProgressDialog->setWindowModality(Qt::ApplicationModal);
connect(m_pProgressDialog, SIGNAL(Cancel()), this, SLOT(OnCancelAsync()));
m_pProgressModal = false;
m_pPopUpWindow = new CPopUpWindow();
connect(m_pPopUpWindow, SIGNAL(RecoveryRequested(const QString&)), this, SLOT(OpenRecovery(const QString&)));
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
m_pWndTopMost->setChecked(bAlwaysOnTop);
@ -400,6 +407,10 @@ void CSandMan::CreateMenus()
m_pShowHidden = m_pMenuView->addAction(tr("Show Hidden Boxes"));
m_pShowHidden->setCheckable(true);
m_pShowAllSessions = m_pMenuView->addAction(tr("Show All Sessions"), this, SLOT(OnProcView()));
m_pShowAllSessions->setCheckable(true);
m_pMenuView->addSeparator();
m_pCleanUpMenu = m_pMenuView->addMenu(CSandMan::GetIcon("Clean"), tr("Clean Up"));
m_pCleanUpProcesses = m_pCleanUpMenu->addAction(tr("Cleanup Processes"), this, SLOT(OnCleanUp()));
@ -407,9 +418,10 @@ void CSandMan::CreateMenus()
m_pCleanUpMsgLog = m_pCleanUpMenu->addAction(tr("Cleanup Message Log"), this, SLOT(OnCleanUp()));
m_pCleanUpTrace = m_pCleanUpMenu->addAction(tr("Cleanup Trace Log"), this, SLOT(OnCleanUp()));
m_pKeepTerminated = m_pMenuView->addAction(CSandMan::GetIcon("Keep"), tr("Keep terminated"), this, SLOT(OnSetKeep()));
m_pKeepTerminated = m_pMenuView->addAction(CSandMan::GetIcon("Keep"), tr("Keep terminated"), this, SLOT(OnProcView()));
m_pKeepTerminated->setCheckable(true);
m_pMenuOptions = menuBar()->addMenu(tr("&Options"));
m_pMenuSettings = m_pMenuOptions->addAction(CSandMan::GetIcon("Settings"), tr("Global Settings"), this, SLOT(OnSettings()));
m_pMenuResetMsgs = m_pMenuOptions->addAction(tr("Reset all hidden messages"), this, SLOT(OnResetMsgs()));
@ -634,6 +646,7 @@ void CSandMan::OnMessage(const QString& Message)
}
}
m_pProgressDialog->hide();
//statusBar()->showMessage(tr("Maintenance operation completed"), 3000);
m_bConnectPending = false;
m_bStopPending = false;
}
@ -675,7 +688,7 @@ void CSandMan::timerEvent(QTimerEvent* pEvent)
{
SB_STATUS Status = theAPI->ReloadBoxes();
theAPI->UpdateProcesses(m_pKeepTerminated->isChecked());
theAPI->UpdateProcesses(m_pKeepTerminated->isChecked(), m_pShowAllSessions->isChecked());
bForceProcessDisabled = theAPI->AreForceProcessDisabled();
m_pDisableForce->setChecked(bForceProcessDisabled);
@ -798,10 +811,8 @@ void CSandMan::OnBoxClosed(const QString& BoxName)
if (!pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false) && !pBox->IsEmpty())
{
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox, this);
if (pRecoveryWindow->FindFiles() == 0)
delete pRecoveryWindow;
else if (pRecoveryWindow->exec() != 1)
// 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
return;
SB_PROGRESS Status = pBox->CleanBox();
@ -1048,18 +1059,48 @@ void CSandMan::OnQueuedRequest(quint32 ClientPid, quint32 ClientTid, quint32 Req
void CSandMan::OnFileToRecover(const QString& BoxName, const QString& FilePath, const QString& BoxPath, quint32 ProcessId)
{
if (theConf->GetBool("Options/InstantRecovery", false))
{
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
if (pBox)
ShowRecovery(pBox);
}
else
m_pPopUpWindow->AddFileToRecover(FilePath, BoxPath, BoxName, ProcessId);
}
void CSandMan::OpenRecovery(const QString& BoxName)
bool CSandMan::OpenRecovery(const CSandBoxPtr& pBox, bool bCloseEmpty)
{
CSandBoxPtr pBox = theAPI->GetBoxByName(BoxName);
if (!pBox)
return;
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
if (pBoxEx->m_pRecoveryWnd != NULL) {
pBoxEx->m_pRecoveryWnd->close();
// todo: resuse window?
}
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox);
pRecoveryWindow->FindFiles();
pRecoveryWindow->show();
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox, this);
if (pRecoveryWindow->FindFiles() == 0 && bCloseEmpty) {
delete pRecoveryWindow;
}
else if (pRecoveryWindow->exec() != 1)
return false;
return true;
}
void CSandMan::ShowRecovery(const CSandBoxPtr& pBox)
{
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
if (pBoxEx->m_pRecoveryWnd == NULL) {
pBoxEx->m_pRecoveryWnd = new CRecoveryWindow(pBox);
connect(pBoxEx->m_pRecoveryWnd, &CRecoveryWindow::Closed, [pBoxEx]() {
pBoxEx->m_pRecoveryWnd = NULL;
});
pBoxEx->m_pRecoveryWnd->show();
}
else {
pBoxEx->m_pRecoveryWnd->setWindowState((pBoxEx->m_pRecoveryWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
SetForegroundWindow((HWND)pBoxEx->m_pRecoveryWnd->winId());
}
pBoxEx->m_pRecoveryWnd->FindFiles();
}
SB_PROGRESS CSandMan::RecoverFiles(const QList<QPair<QString, QString>>& FileList, int Action)
@ -1189,7 +1230,7 @@ void CSandMan::OnNewBox()
void CSandMan::OnEmptyAll()
{
if (theConf->GetInt("Options/TerminateAll", -1) == -1)
if (theConf->GetInt("Options/WarnTerminateAll", -1) == -1)
{
bool State = false;
if(CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Do you want to terminate all processes in all sandboxes?")
@ -1197,7 +1238,7 @@ void CSandMan::OnEmptyAll()
return;
if (State)
theConf->SetValue("Options/TerminateAll", 1);
theConf->SetValue("Options/WarnTerminateAll", 1);
}
theAPI->TerminateAll();
@ -1336,7 +1377,8 @@ void CSandMan::OnMaintenance()
Status = CSbieUtils::Uninstall(CSbieUtils::eService);
if (Status.GetStatus() == OP_ASYNC) {
statusBar()->showMessage(tr("Executing maintenance operation, please wait..."));
//statusBar()->showMessage(tr("Executing maintenance operation, please wait..."));
m_pProgressDialog->OnStatusMessage(tr("Executing maintenance operation, please wait..."));
m_pProgressDialog->show();
return;
}
@ -1405,15 +1447,13 @@ void CSandMan::OnCleanUp()
m_pTraceView->Clear();
if (sender() == m_pCleanUpProcesses || sender() == m_pCleanUpButton)
theAPI->UpdateProcesses(false);
theAPI->UpdateProcesses(false, m_pShowAllSessions->isChecked());
}
void CSandMan::OnSetKeep()
void CSandMan::OnProcView()
{
theConf->SetValue("Options/KeepTerminated", m_pKeepTerminated->isChecked());
if(!m_pKeepTerminated->isChecked()) // clear on disable
theAPI->UpdateProcesses(false);
theConf->SetValue("Options/ShowAllSessions", m_pShowAllSessions->isChecked());
}
void CSandMan::OnSettings()
@ -1467,7 +1507,8 @@ void CSandMan::OnResetMsgs()
theConf->SetValue("Options/OpenUrlsSandboxed", 2);
theConf->SetValue("Options/AutoCleanupTemplates", -1);
theConf->SetValue("Options/TerminateAll", -1);
theConf->SetValue("Options/WarnTerminateAll", -1);
theConf->SetValue("Options/WarnTerminate", -1);
}
theAPI->GetUserSettings()->UpdateTextList("SbieCtrl_HideMessage", QStringList(), true);
@ -1539,7 +1580,7 @@ void CSandMan::OnSetMonitoring()
//m_pTraceView->setEnabled(m_pEnableMonitoring->isChecked());
}
void CSandMan::AddAsyncOp(const CSbieProgressPtr& pProgress)
bool CSandMan::AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait)
{
m_pAsyncProgress.insert(pProgress.data(), pProgress);
connect(pProgress.data(), SIGNAL(Message(const QString&)), this, SLOT(OnAsyncMessage(const QString&)));
@ -1547,10 +1588,18 @@ void CSandMan::AddAsyncOp(const CSbieProgressPtr& pProgress)
connect(pProgress.data(), SIGNAL(Finished()), this, SLOT(OnAsyncFinished()));
m_pProgressDialog->OnStatusMessage("");
if (bWait) {
m_pProgressModal = true;
m_pProgressDialog->exec();
m_pProgressModal = false;
}
else
m_pProgressDialog->show();
if (pProgress->IsFinished()) // Note: since the operation runs asynchronously, it may have already finished, so we need to test for that
OnAsyncFinished(pProgress.data());
return !pProgress->IsCanceled();
}
void CSandMan::OnAsyncFinished()
@ -1569,8 +1618,12 @@ void CSandMan::OnAsyncFinished(CSbieProgress* pSender)
if(Status.IsError())
CSandMan::CheckResults(QList<SB_STATUS>() << Status);
if(m_pAsyncProgress.isEmpty())
if (m_pAsyncProgress.isEmpty()) {
if(m_pProgressModal)
m_pProgressDialog->close();
else
m_pProgressDialog->hide();
}
}
void CSandMan::OnAsyncMessage(const QString& Text)
@ -1598,7 +1651,8 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
QString Message;
switch (Error.GetMsgCode())
{
case SB_Generic: return tr("Error Status: %1").arg(Error.GetStatus());
case SB_Generic: return tr("Error Status: 0x%1 (%2)").arg((quint32)Error.GetStatus(), 8, 16, QChar('0')).arg(
(Error.GetArgs().isEmpty() || Error.GetArgs().first().toString().isEmpty()) ? tr("Unknown") : Error.GetArgs().first().toString().trimmed());
case SB_Message: Message = "%1"; break;
case SB_NeedAdmin: Message = tr("Administrator rights are required for this operation."); break;
case SB_ExecFail: Message = tr("Failed to execute: %1"); break;
@ -1615,8 +1669,8 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
case SB_FailedKillAll: Message = tr("Failed to terminate all processes"); break;
case SB_DeleteProtect: Message = tr("Delete protection is enabled for the sandbox"); break;
case SB_DeleteError: Message = tr("Error deleting sandbox folder: %1"); break;
case SB_RemNotEmpty: Message = tr("A sandbox must be emptied before it can be renamed."); break;
case SB_DelNotEmpty: Message = tr("A sandbox must be emptied before it can be deleted."); break;
//case SB_RemNotEmpty: Message = tr("A sandbox must be emptied before it can be renamed."); break;
//case SB_DelNotEmpty: Message = tr("A sandbox must be emptied before it can be deleted."); break;
case SB_FailedMoveDir: Message = tr("Failed to move directory '%1' to '%2'"); break;
case SB_SnapIsRunning: Message = tr("This Snapshot operation can not be performed while processes are still running in the box."); break;
case SB_SnapMkDirFail: Message = tr("Failed to create directory for new snapshot"); break;
@ -1631,7 +1685,7 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
case SB_SnapIsEmpty: Message = tr("Can not create snapshot of an empty sandbox"); break;
case SB_NameExists: Message = tr("A sandbox with that name already exists"); break;
case SB_PasswordBad: Message = tr("The config password must not be longer than 64 characters"); break;
default: return tr("Unknown Error Status: %1").arg(Error.GetStatus());
default: return tr("Unknown Error Status: 0x%1").arg((quint32)Error.GetStatus(), 8, 16, QChar('0'));
}
foreach(const QVariant& Arg, Error.GetArgs())

View File

@ -38,7 +38,7 @@ public:
SB_PROGRESS RecoverFiles(const QList<QPair<QString, QString>>& FileList, int Action = 0);
void AddAsyncOp(const CSbieProgressPtr& pProgress);
bool AddAsyncOp(const CSbieProgressPtr& pProgress, bool bWait = false);
static QString FormatError(const SB_STATUS& Error);
static void CheckResults(QList<SB_STATUS> Results);
@ -109,7 +109,8 @@ 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);
void OpenRecovery(const QString& BoxName);
bool OpenRecovery(const CSandBoxPtr& pBox, bool bCloseEmpty = false);
void ShowRecovery(const CSandBoxPtr& pBox);
void UpdateSettings();
void OnIniReloaded();
@ -149,7 +150,7 @@ private slots:
void OnViewMode(QAction* action);
void OnAlwaysTop();
void OnCleanUp();
void OnSetKeep();
void OnProcView();
void OnSettings();
void OnResetMsgs();
@ -227,6 +228,7 @@ private:
QAction* m_pCleanUpTrace;
QToolButton* m_pCleanUpButton;
QAction* m_pKeepTerminated;
QAction* m_pShowAllSessions;
QMenu* m_pMenuOptions;
QAction* m_pMenuSettings;
@ -253,6 +255,7 @@ private:
bool m_bExit;
CProgressDialog* m_pProgressDialog;
bool m_pProgressModal;
CPopUpWindow* m_pPopUpWindow;
void SetUITheme();

View File

@ -212,6 +212,7 @@
</ClCompile>
<ClCompile Include="Views\SbieView.cpp" />
<ClCompile Include="Views\TraceView.cpp" />
<ClCompile Include="Windows\FileBrowserWindow.cpp" />
<ClCompile Include="Windows\NewBoxWindow.cpp" />
<ClCompile Include="Windows\OptionsAccess.cpp" />
<ClCompile Include="Windows\OptionsAdvanced.cpp" />
@ -231,6 +232,7 @@
<ClCompile Include="Windows\SnapshotsWindow.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="Windows\FileBrowserWindow.h" />
<QtMoc Include="Windows\SelectBoxWindow.h" />
<QtMoc Include="Views\TraceView.h" />
<QtMoc Include="Windows\NewBoxWindow.h" />
@ -259,6 +261,7 @@
<Image Include="Resources\SandMan.ico" />
</ItemGroup>
<ItemGroup>
<QtUic Include="Forms\FileBrowserWindow.ui" />
<QtUic Include="Forms\NewBoxWindow.ui" />
<QtUic Include="Forms\OptionsWindow.ui" />
<QtUic Include="Forms\PopUpWindow.ui" />

View File

@ -135,6 +135,9 @@
<ClCompile Include="Windows\OptionsTemplates.cpp">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="Windows\FileBrowserWindow.cpp">
<Filter>Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -193,6 +196,9 @@
<QtMoc Include="Windows\SelectBoxWindow.h">
<Filter>Windows</Filter>
</QtMoc>
<QtMoc Include="Windows\FileBrowserWindow.h">
<Filter>Windows</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<QtRcc Include="Resources\SandMan.qrc">
@ -232,6 +238,9 @@
<QtUic Include="Forms\SelectBoxWindow.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="Forms\FileBrowserWindow.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>
<None Include="sandman_de.ts">

View File

@ -90,6 +90,9 @@ CSandBoxPlus::CSandBoxPlus(const QString& BoxName, class CSbieAPI* pAPI) : CSand
m_iUnsecureDebugging = 0;
m_SuspendRecovery = false;
m_pOptionsWnd = NULL;
m_pRecoveryWnd = NULL;
}
CSandBoxPlus::~CSandBoxPlus()
@ -476,6 +479,9 @@ QString CSbieProcess::GetStatusStr() const
else
Status = tr("Running");
if(m_SessionId != theAPI->GetSessionID())
Status += tr(" in session %1").arg(m_SessionId);
if (m_bIsWoW64)
Status += " *32";

View File

@ -84,6 +84,8 @@ public:
EBoxTypes GetType() const;
class COptionsWindow* m_pOptionsWnd;
class CRecoveryWindow* m_pRecoveryWnd;
protected:
friend class CSbiePlusAPI;

View File

@ -12,6 +12,7 @@
#include "../../MiscHelpers/Common/CheckableMessageBox.h"
#include "../Windows/RecoveryWindow.h"
#include "../Windows/NewBoxWindow.h"
#include "../Windows/FileBrowserWindow.h"
#include "qt_windows.h"
#include "qwindowdefs_win.h"
@ -86,6 +87,7 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
m_pMenuMkLink = m_pMenu->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnSandBoxAction()));
m_pMenu->addSeparator();
m_pMenuExplore = m_pMenu->addAction(CSandMan::GetIcon("Explore"), tr("Explore Content"), this, SLOT(OnSandBoxAction()));
m_pMenuBrowse = m_pMenu->addAction(CSandMan::GetIcon("Tree"), tr("Browse Content"), 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()));
@ -118,9 +120,9 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
m_pMenuTerminate = m_pMenu->addAction(CSandMan::GetIcon("Remove"), tr("Terminate"), this, SLOT(OnProcessAction()));
m_pMenuTerminate->setShortcut(QKeySequence::Delete);
m_pMenuLinkTo = m_pMenu->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnProcessAction()));
this->addAction(m_pMenuTerminate);
m_pMenuTerminate->setShortcutContext(Qt::WidgetWithChildrenShortcut);
this->addAction(m_pMenuTerminate);
m_pMenuLinkTo = m_pMenu->addAction(CSandMan::GetIcon("MkLink"), tr("Create Shortcut"), this, SLOT(OnProcessAction()));
m_pMenuPreset = m_pMenu->addMenu(CSandMan::GetIcon("Presets"), tr("Preset"));
m_pMenuPinToRun = m_pMenuPreset->addAction(tr("Pin to Run Menu"), this, SLOT(OnProcessAction()));
m_pMenuPinToRun->setCheckable(true);
@ -147,6 +149,7 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
m_pMenu2->addAction(m_pMenuEmptyBox);
m_pMenu2->addSeparator();
m_pMenu2->addAction(m_pMenuExplore);
m_pMenu2->addAction(m_pMenuBrowse);
m_pMenu2->addAction(m_pMenuSnapshots);
m_pMenu2->addAction(m_pMenuRecover);
m_pMenu2->addAction(m_pMenuCleanUp);
@ -285,6 +288,7 @@ void CSbieView::UpdateMenu()
m_pMenuPresetsINet->setChecked(pBox && pBox.objectCast<CSandBoxPlus>()->IsINetBlocked());
m_pMenuPresetsShares->setChecked(pBox && pBox.objectCast<CSandBoxPlus>()->HasSharesAccess());
m_pMenuBrowse->setEnabled(iSandBoxeCount == 1);
m_pMenuExplore->setEnabled(iSandBoxeCount == 1);
m_pMenuOptions->setEnabled(iSandBoxeCount == 1);
m_pMenuSnapshots->setEnabled(iSandBoxeCount == 1);
@ -340,8 +344,6 @@ void CSbieView::UpdateMenu()
void CSbieView::OnMenu(const QPoint& Point)
{
UpdateMenu();
CPanelView::OnMenu(Point);
}
@ -638,6 +640,21 @@ void CSbieView::OnSandBoxAction(QAction* Action)
::ShellExecute(NULL, NULL, SandBoxes.first()->GetFileRoot().toStdWString().c_str(), NULL, NULL, SW_SHOWNORMAL);
}
else if (Action == m_pMenuBrowse)
{
CSandBoxPtr pBox = SandBoxes.first();
static QMap<void*, CFileBrowserWindow*> FileBrowserWindows;
if (!FileBrowserWindows.contains(pBox.data()))
{
CFileBrowserWindow* pFileBrowserWindow = new CFileBrowserWindow(SandBoxes.first());
FileBrowserWindows.insert(pBox.data(), pFileBrowserWindow);
connect(pFileBrowserWindow, &CFileBrowserWindow::Closed, [this, pBox]() {
FileBrowserWindows.remove(pBox.data());
});
pFileBrowserWindow->show();
}
}
else if (Action == m_pMenuSnapshots)
{
CSandBoxPtr pBox = SandBoxes.first();
@ -661,17 +678,26 @@ void CSbieView::OnSandBoxAction(QAction* Action)
return;
Results.append((SandBoxes.first()->RenameBox(Value.replace(" ", "_"))));
}
else if (Action == m_pMenuRecover)
{
theGUI->ShowRecovery(SandBoxes.first());
}
else if (Action == m_pMenuRemove)
{
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to remove the selected sandbox(es)?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
return;
foreach(const CSandBoxPtr& pBox, SandBoxes)
foreach(const CSandBoxPtr & pBox, SandBoxes)
{
SB_PROGRESS Status = pBox->CleanBox();
if (Status.GetStatus() == OP_ASYNC)
theGUI->AddAsyncOp(Status.GetValue(), true);
else if (Status.IsError()) {
Results.append(Status);
continue;
}
Results.append(pBox->RemoveBox());
}
else if (Action == m_pMenuRecover)
{
emit RecoveryRequested(SandBoxes.first()->GetName());
}
else if (Action == m_pMenuCleanUp)
{
@ -684,9 +710,8 @@ void CSbieView::OnSandBoxAction(QAction* Action)
if (theConf->GetBool("Options/ShowRecovery", false))
{
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(SandBoxes.first(), this);
pRecoveryWindow->FindFiles();
if (pRecoveryWindow->exec() != 1)
// Use recovery dialog in place of the confirmation messagebox for box clean up
if(!theGUI->OpenRecovery(SandBoxes.first()))
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)
@ -706,9 +731,17 @@ void CSbieView::OnSandBoxAction(QAction* Action)
}
else if (Action == m_pMenuEmptyBox)
{
if (QMessageBox("Sandboxie-Plus", tr("Do you want to terminate all processes in the selected sandbox(es)?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
if (theConf->GetInt("Options/WarnTerminate", -1) == -1)
{
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)
return;
if (State)
theConf->SetValue("Options/WarnTerminate", 1);
}
foreach(const CSandBoxPtr& pBox, SandBoxes)
Results.append(pBox->TerminateAll());
}
@ -766,15 +799,27 @@ void CSbieView::OnProcessAction()
{
QList<SB_STATUS> Results;
QList<CBoxedProcessPtr> Processes = CSbieView::GetSelectedProcesses();
QAction* Action = qobject_cast<QAction*>(sender());
if (Action == m_pMenuTerminate || Action == m_pMenuBlackList)
{
if (QMessageBox("Sandboxie-Plus", tr("Do you want to %1 the selected process(es)?").arg(((QAction*)sender())->text().toLower())
, QMessageBox::Question, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton, this).exec() != QMessageBox::Yes)
if (theConf->GetInt("Options/WarnTerminate", -1) == -1)
{
if (Processes.isEmpty())
return;
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)
return;
if (State)
theConf->SetValue("Options/WarnTerminate", 1);
}
}
foreach(const CBoxedProcessPtr& pProcess, CSbieView::GetSelectedProcesses())
foreach(const CBoxedProcessPtr& pProcess, Processes)
{
if (Action == m_pMenuTerminate)
Results.append(pProcess->Terminate());
@ -861,15 +906,17 @@ void CSbieView::OnDoubleClicked(const QModelIndex& index)
pBox->SetText("Enabled", "y");
}
static QMap<void*, COptionsWindow*> OptionsWindows;
if (!OptionsWindows.contains(pBox.data()))
{
COptionsWindow* pOptionsWindow = new COptionsWindow(pBox, pBox->GetName());
OptionsWindows.insert(pBox.data(), pOptionsWindow);
connect(pOptionsWindow, &COptionsWindow::Closed, [this, pBox]() {
OptionsWindows.remove(pBox.data());
auto pBoxEx = pBox.objectCast<CSandBoxPlus>();
if (pBoxEx->m_pOptionsWnd == NULL) {
pBoxEx->m_pOptionsWnd = new COptionsWindow(pBox, pBox->GetName());
connect(pBoxEx->m_pOptionsWnd, &COptionsWindow::Closed, [pBoxEx]() {
pBoxEx->m_pOptionsWnd = NULL;
});
pOptionsWindow->show();
pBoxEx->m_pOptionsWnd->show();
}
else {
pBoxEx->m_pOptionsWnd->setWindowState((pBoxEx->m_pOptionsWnd->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
SetForegroundWindow((HWND)pBoxEx->m_pOptionsWnd->winId());
}
}
@ -906,6 +953,8 @@ void CSbieView::ProcessSelection(const QItemSelection& selected, const QItemSele
}
selectionModel->select(invalid, QItemSelectionModel::Deselect);
UpdateMenu();
}
QList<CSandBoxPtr> CSbieView::GetSelectedBoxes()
@ -1005,7 +1054,6 @@ void CSbieView::SelectBox(const QString& Name)
void CSbieView::PopUpMenu(const QString& Name)
{
SelectBox(Name);
UpdateMenu();
m_pMenu2->popup(QCursor::pos());
//OnMenu(QCursor::pos());
}

View File

@ -24,9 +24,6 @@ public:
virtual void PopUpMenu(const QString& Name);
virtual void ShowOptions(const QString& Name);
signals:
void RecoveryRequested(const QString& BoxName);
public slots:
void Clear();
void Refresh();
@ -95,6 +92,7 @@ private:
QAction* m_pMenuSnapshots;
QAction* m_pMenuEmptyBox;
QAction* m_pMenuExplore;
QAction* m_pMenuBrowse;
QAction* m_pMenuRecover;
QAction* m_pMenuCleanUp;
QAction* m_pMenuRemove;

View File

@ -0,0 +1,261 @@
#include "stdafx.h"
#include "FileBrowserWindow.h"
#include "SandMan.h"
#include "../MiscHelpers/Common/Settings.h"
#include "../MiscHelpers/Common/TreeItemModel.h"
#include "../MiscHelpers/Common/OtherFunctions.h"
#include "../QSbieAPI/SbieUtils.h"
CFileBrowserWindow::CFileBrowserWindow(const CSandBoxPtr& pBox, QWidget *parent)
: QDialog(parent)
{
Qt::WindowFlags flags = windowFlags();
flags |= Qt::CustomizeWindowHint;
//flags &= ~Qt::WindowContextHelpButtonHint;
//flags &= ~Qt::WindowSystemMenuHint;
//flags &= ~Qt::WindowMinMaxButtonsHint;
flags |= Qt::WindowMinimizeButtonHint;
//flags &= ~Qt::WindowCloseButtonHint;
setWindowFlags(flags);
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
ui.setupUi(this);
this->setWindowTitle(tr("%1 - Files").arg(pBox->GetName()));
m_pBox = pBox;
m_pFileModel = new QFileSystemModel(this);
m_pFileModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files | QDir::Hidden | QDir::System);
m_pFileModel->setRootPath(pBox->GetFileRoot());
ui.treeFiles->setModel(m_pFileModel);
ui.treeFiles->setRootIndex(m_pFileModel->setRootPath(pBox->GetFileRoot()));
ui.treeFiles->setSelectionMode(QAbstractItemView::ExtendedSelection);
#ifdef WIN32
QStyle* pStyle = QStyleFactory::create("windows");
ui.treeFiles->setStyle(pStyle);
#endif
ui.treeFiles->setExpandsOnDoubleClick(false);
ui.treeFiles->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui.treeFiles, SIGNAL(customContextMenuRequested( const QPoint& )), this, SLOT(OnFileMenu(const QPoint &)));
connect(ui.treeFiles, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(OnFileDblClick(const QModelIndex &)));
//statusBar();
restoreGeometry(theConf->GetBlob("FileBrowserWindow/Window_Geometry"));
QByteArray Columns = theConf->GetBlob("FileBrowserWindow/FileTree_Columns");
if (!Columns.isEmpty())
ui.treeFiles->header()->restoreState(Columns);
}
CFileBrowserWindow::~CFileBrowserWindow()
{
theConf->SetBlob("FileBrowserWindow/Window_Geometry",saveGeometry());
theConf->SetBlob("FileBrowserWindow/FileTree_Columns", ui.treeFiles->header()->saveState());
}
void CFileBrowserWindow::closeEvent(QCloseEvent *e)
{
emit Closed();
this->deleteLater();
}
#include <windows.h>
#include <Shlobj.h>
#include <atlbase.h>
#define MENU_RECOVER 1
#define MENU_RECOVER_TO_ANY 2
#define MENU_CREATE_SHORTCUT 3
void addSeparatorToShellContextMenu(HMENU hMenu)
{
MENUITEMINFO menu_item_info;
memset(&menu_item_info, 0, sizeof(MENUITEMINFO));
menu_item_info.cbSize = sizeof(MENUITEMINFO);
menu_item_info.fType = MFT_SEPARATOR;
menu_item_info.wID = 0;
InsertMenuItem(hMenu, 0, TRUE, &menu_item_info);
}
void addItemToShellContextMenu(HMENU hMenu, const wchar_t *name, int ID)
{
MENUITEMINFO menu_item_info;
memset(&menu_item_info, 0, sizeof(MENUITEMINFO));
menu_item_info.cbSize = sizeof(MENUITEMINFO);
menu_item_info.fMask = MIIM_ID | MIIM_STRING | MIIM_DATA;
menu_item_info.wID = 0xF000 + ID;
menu_item_info.dwTypeData = (wchar_t*)name;
InsertMenuItem(hMenu, 0, TRUE, &menu_item_info);
}
int openShellContextMenu(const QStringList& Files, void * parentWindow)
{
std::list<CComHeapPtr<ITEMIDLIST_ABSOLUTE>> items;
items.resize(Files.count());
auto IT = items.begin();
foreach(QString File, Files) {
CComPtr<IShellItem> item;
SHCreateItemFromParsingName(File.toStdWString().c_str(), NULL, IID_PPV_ARGS(&item));
CComQIPtr<IPersistIDList> idl(item);
idl->GetIDList(&*IT++);
}
std::vector<LPCITEMIDLIST> list;
list.resize(items.size());
LPCITEMIDLIST* listPtr = &list.front();
for (auto I = items.begin(); I != items.end(); I++)
*listPtr++ = *I;
CComPtr<IShellItemArray> array;
SHCreateShellItemArrayFromIDLists(list.size(), &list.front(), &array);
CComPtr<IContextMenu> menu;
array->BindToHandler(NULL, BHID_SFUIObject, IID_PPV_ARGS(&menu));
if (!menu)
return 0;
HMENU hMenu = CreatePopupMenu();
if (!hMenu)
return 0;
if (SUCCEEDED(menu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_NORMAL)))
{
addSeparatorToShellContextMenu(hMenu);
std::wstring Str1 = CFileBrowserWindow::tr("Create Shortcut").toStdWString();
if (Files.count() == 1) {
addItemToShellContextMenu(hMenu, Str1.c_str(), MENU_CREATE_SHORTCUT);
addSeparatorToShellContextMenu(hMenu);
}
std::wstring Str2 = CFileBrowserWindow::tr("Recover to Any Folder").toStdWString();
addItemToShellContextMenu(hMenu, Str2.c_str(), MENU_RECOVER_TO_ANY);
std::wstring Str3 = CFileBrowserWindow::tr("Recover to Same Folder").toStdWString();
addItemToShellContextMenu(hMenu, Str3.c_str(), MENU_RECOVER);
POINT point;
GetCursorPos(&point);
int iCmd = TrackPopupMenuEx(hMenu, TPM_RETURNCMD, point.x, point.y, (HWND)parentWindow, NULL);
if (iCmd > 0)
{
if ((iCmd & 0xF000) == 0xF000) {
DestroyMenu(hMenu);
return iCmd & 0x0FFF;
}
CMINVOKECOMMANDINFOEX info = { 0 };
info.cbSize = sizeof(info);
info.fMask = CMIC_MASK_UNICODE;
info.hwnd = (HWND)parentWindow;
info.lpVerb = MAKEINTRESOURCEA(iCmd - 1);
info.lpVerbW = MAKEINTRESOURCEW(iCmd - 1);
info.nShow = SW_SHOWNORMAL;
menu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
}
}
DestroyMenu(hMenu);
return 0;
}
void CFileBrowserWindow::OnFileMenu(const QPoint&)
{
QStringList Files;
foreach(const QModelIndex & Index, ui.treeFiles->selectionModel()->selectedIndexes()) {
QString BoxedPath = m_pFileModel->fileInfo(Index).absoluteFilePath().replace("/", "\\");
if (m_pFileModel->fileInfo(Index).isDir())
BoxedPath += "\\";
bool bFound = false;
foreach(const QString & File, Files) {
if (BoxedPath.contains(File))
bFound = true;
else if (File.contains(BoxedPath))
Files.removeOne(File);
}
if(!bFound)
Files.append(BoxedPath);
}
int iCmd = openShellContextMenu(Files, (void*)this->winId());
if (iCmd == 0)
return;
QString RecoveryFolder;
switch (iCmd)
{
case MENU_RECOVER_TO_ANY:
RecoveryFolder = QFileDialog::getExistingDirectory(this, CFileBrowserWindow::tr("Select Directory")).replace("/", "\\");
if (RecoveryFolder.isEmpty())
break;
case MENU_RECOVER:
{
QStringList AllFiles;
foreach(const QString& File, Files)
{
if (File.right(1) == "\\") {
foreach(QString SubFile, ListDir(File))
AllFiles.append(File + SubFile.replace("/", "\\"));
}
else
AllFiles.append(File);
}
QList<QPair<QString, QString>> FileList;
foreach(QString BoxedPath, AllFiles)
{
if (!RecoveryFolder.isEmpty()) {
QString FileName = BoxedPath.mid(BoxedPath.lastIndexOf("\\") + 1);
FileList.append(qMakePair(BoxedPath, RecoveryFolder + "\\" + FileName));
}
else {
QString RealPath = theAPI->GetRealPath(m_pBox, BoxedPath);
FileList.append(qMakePair(BoxedPath, RealPath));
}
}
SB_PROGRESS Status = theGUI->RecoverFiles(FileList, 0);
if (Status.GetStatus() == OP_ASYNC)
theGUI->AddAsyncOp(Status.GetValue());
break;
}
case MENU_CREATE_SHORTCUT:
{
QString BoxName = m_pBox->GetName();
QString LinkPath = Files.first();
QString LinkName = LinkPath.mid(LinkPath.lastIndexOf("\\") + 1);
QString Path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation).replace("/", "\\");
//Path = QFileDialog::getExistingDirectory(this, tr("Select Directory to create Shorcut in"), Path).replace("/", "\\");
//if (Path.isEmpty())
// return;
if (Path.right(1) != "\\")
Path.append("\\");
Path += "[" + BoxName + "] " + LinkName;
Path = QFileDialog::getSaveFileName(this, tr("Create Shortcut to sandbox %1").arg(BoxName), Path, QString("Shortcut files (*.lnk)")).replace("/", "\\");
if (Path.isEmpty())
return;
CSbieUtils::CreateShortcut(theAPI, Path, LinkName, BoxName, LinkPath, LinkPath);
break;
}
}
}
void CFileBrowserWindow::OnFileDblClick(const QModelIndex &)
{
QString BoxedPath = m_pFileModel->fileInfo(ui.treeFiles->currentIndex()).absoluteFilePath();
ShellExecute(NULL, NULL, BoxedPath.toStdWString().c_str(), NULL, m_pBox->GetFileRoot().toStdWString().c_str(), SW_SHOWNORMAL);
}

View File

@ -0,0 +1,35 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_FileBrowserWindow.h"
#include "SbiePlusAPI.h"
#include <QFileSystemModel>
class CFileBrowserWindow : public QDialog
{
Q_OBJECT
public:
CFileBrowserWindow(const CSandBoxPtr& pBox, QWidget *parent = Q_NULLPTR);
~CFileBrowserWindow();
virtual void accept() {}
virtual void reject() { this->close(); }
signals:
void Closed();
private slots:
void OnFileMenu(const QPoint &);
void OnFileDblClick(const QModelIndex &);
protected:
void closeEvent(QCloseEvent *e);
CSandBoxPtr m_pBox;
private:
Ui::FileBrowserWindow ui;
QFileSystemModel* m_pFileModel;
};

View File

@ -101,6 +101,7 @@ int CRecoveryWindow::exec()
void CRecoveryWindow::closeEvent(QCloseEvent *e)
{
emit Closed();
this->deleteLater();
}

View File

@ -41,6 +41,9 @@ public:
virtual void accept() {}
virtual void reject() { this->close(); }
signals:
void Closed();
public slots:
int exec();

View File

@ -109,6 +109,7 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
m_FeaturesChanged = false;
connect(ui.chkWFP, SIGNAL(stateChanged(int)), this, SLOT(OnFeaturesChanged()));
connect(ui.chkObjCb, SIGNAL(stateChanged(int)), this, SLOT(OnFeaturesChanged()));
m_WarnProgsChanged = false;
@ -207,6 +208,7 @@ void CSettingsWindow::LoadSettings()
ui.chkSandboxUrls->setCheckState(CSettingsWindow__Int2Chk(theConf->GetInt("Options/OpenUrlsSandboxed", 2)));
ui.chkShowRecovery->setChecked(theConf->GetBool("Options/ShowRecovery", false));
ui.chkInstantRecovery->setChecked(theConf->GetBool("Options/InstantRecovery", false));
ui.chkPanic->setChecked(theConf->GetBool("Options/EnablePanicKey", false));
ui.keyPanic->setKeySequence(QKeySequence(theConf->GetString("Options/PanicKeySequence", "Ctrl+Alt+Cancel")));
@ -324,6 +326,7 @@ void CSettingsWindow::SaveSettings()
theConf->SetValue("Options/OpenUrlsSandboxed", CSettingsWindow__Chk2Int(ui.chkSandboxUrls->checkState()));
theConf->SetValue("Options/ShowRecovery", ui.chkShowRecovery->isChecked());
theConf->SetValue("Options/InstantRecovery", ui.chkInstantRecovery->isChecked());
theConf->SetValue("Options/EnablePanicKey", ui.chkPanic->isChecked());
theConf->SetValue("Options/PanicKeySequence", ui.keyPanic->keySequence().toString());

View File

@ -24,6 +24,8 @@ int main(int argc, char *argv[])
//InitConsole(false);
bool IsBoxed = GetModuleHandle(L"SbieDll.dll") != NULL;
SB_STATUS Status = CSbieUtils::DoAssist();
if (Status.GetStatus()) {
if(Status.GetStatus() == ERROR_OK) app.sendMessage("Status:OK");
@ -50,9 +52,20 @@ int main(int argc, char *argv[])
// CommandLine += "\"" + Args[i] + "\" ";
//PendingMessage = "Run:" + CommandLine.trimmed();
LPWSTR ChildCmdLine = wcsstr(GetCommandLineW(), L"/box:__ask__") + 13;
if (IsBoxed) {
ShellExecute(NULL, L"open", ChildCmdLine, NULL, NULL, SW_SHOWNORMAL);
return 0;
}
PendingMessage = "Run:" + QString::fromWCharArray(ChildCmdLine);
}
if (IsBoxed) {
QMessageBox::critical(NULL, "Sandboxie-Plus", CSandMan::tr("Sandboxie Manager can not be run sandboxed!"));
return -1;
}
if (!PendingMessage.isEmpty()) {
if(app.sendMessage(PendingMessage))
return 0;

View File

@ -2,7 +2,7 @@
#define VERSION_MJR 0
#define VERSION_MIN 9
#define VERSION_REV 3
#define VERSION_REV 4
#define VERSION_UPD 0
#ifndef STR