experimental sbie desktop
This commit is contained in:
parent
2c29585e5c
commit
46929668e2
|
@ -25,7 +25,7 @@
|
|||
#define STR(X) STR2(X)
|
||||
|
||||
#define VERSION_MJR 5
|
||||
#define VERSION_MIN 69
|
||||
#define VERSION_MIN 70
|
||||
#define VERSION_REV 0
|
||||
#define VERSION_UPD 0
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2004-2020 Sandboxie Holdings, LLC
|
||||
* Copyright 2020 David Xanatos, xanasoft.com
|
||||
* Copyright 2020-2023 David Xanatos, xanasoft.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1152,17 +1152,11 @@ _FX NTSTATUS File_NtFsControlFile(
|
|||
handle = File_GetProxyPipe(FileHandle, NULL);
|
||||
if (! handle) {
|
||||
|
||||
status = STATUS_BAD_INITIAL_PC;
|
||||
|
||||
if (IoControlCode == FSCTL_SET_REPARSE_POINT) {
|
||||
|
||||
BOOLEAN BoxReparsTarget = SbieApi_QueryConfBool(NULL, L"BoxReparsTarget", FALSE);
|
||||
if(BoxReparsTarget) {
|
||||
|
||||
status = File_SetReparsePoint(
|
||||
FileHandle, InputBuffer, InputBufferLength);
|
||||
SetLastError(LastError);
|
||||
}
|
||||
status = File_SetReparsePoint(
|
||||
FileHandle, InputBuffer, InputBufferLength);
|
||||
SetLastError(LastError);
|
||||
|
||||
} else if (IoControlCode == FSCTL_PIPE_WAIT) {
|
||||
|
||||
|
@ -1178,7 +1172,8 @@ _FX NTSTATUS File_NtFsControlFile(
|
|||
else
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
||||
}
|
||||
} else
|
||||
status = STATUS_BAD_INITIAL_PC;
|
||||
|
||||
if (status == STATUS_BAD_INITIAL_PC) {
|
||||
|
||||
|
|
|
@ -416,18 +416,7 @@ _FX BOOLEAN Gui_Init(HMODULE module)
|
|||
GUI_IMPORT___(ClipCursor);
|
||||
GUI_IMPORT___(GetClipCursor);
|
||||
GUI_IMPORT___(GetCursorPos);
|
||||
GUI_IMPORT___(SetCursorPos);
|
||||
|
||||
GUI_IMPORT___(SetTimer);
|
||||
HMODULE temp = module;
|
||||
module = Dll_Kernel32;
|
||||
GUI_IMPORT___(Sleep);
|
||||
GUI_IMPORT___(SleepEx);
|
||||
GUI_IMPORT___(GetTickCount);
|
||||
GUI_IMPORT___(GetTickCount64);
|
||||
GUI_IMPORT___(QueryUnbiasedInterruptTime);
|
||||
GUI_IMPORT___(QueryPerformanceCounter);
|
||||
module = temp;
|
||||
GUI_IMPORT___(SetCursorPos);
|
||||
|
||||
GUI_IMPORT___(SetTimer);
|
||||
GUI_IMPORT___(MsgWaitForMultipleObjects);
|
||||
|
|
|
@ -285,7 +285,7 @@ _FX BOOLEAN Gui_InitMisc(HMODULE module)
|
|||
__sys_GetThreadDpiAwarenessContext = (P_GetThreadDpiAwarenessContext)
|
||||
Ldr_GetProcAddrNew(DllName_user32, L"GetThreadDpiAwarenessContext","GetThreadDpiAwarenessContext");
|
||||
|
||||
HMODULE current = module;
|
||||
|
||||
if (SbieApi_QueryConfBool(NULL, L"BlockInterferePower", FALSE)) {
|
||||
|
||||
SBIEDLL_HOOK_GUI(ShutdownBlockReasonCreate);
|
||||
|
@ -1703,45 +1703,3 @@ _FX void Gui_SwitchToThisWindow(HWND hWnd, BOOL fAlt)
|
|||
return;
|
||||
__sys_SwitchToThisWindow(hWnd, fAlt);
|
||||
}
|
||||
|
||||
_FX DWORD Gui_GetTickCount() {
|
||||
return __sys_GetTickCount() * SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL,L"LowTickSpeed", 1);
|
||||
}
|
||||
|
||||
_FX ULONGLONG Gui_GetTickCount64() {
|
||||
return __sys_GetTickCount64() * SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
|
||||
}
|
||||
|
||||
_FX BOOL Gui_QueryUnbiasedInterruptTime(
|
||||
PULONGLONG UnbiasedTime
|
||||
) {
|
||||
BOOL rtn = __sys_QueryUnbiasedInterruptTime(UnbiasedTime);
|
||||
*UnbiasedTime *= SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
_FX void Gui_Sleep(DWORD dwMiSecond) {
|
||||
__sys_Sleep(dwMiSecond * SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1));
|
||||
}
|
||||
|
||||
_FX DWORD Gui_SleepEx(DWORD dwMiSecond, BOOL bAlert) {
|
||||
return __sys_SleepEx(dwMiSecond * SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1),bAlert);
|
||||
}
|
||||
|
||||
_FX BOOL Gui_QueryPerformanceCounter(
|
||||
LARGE_INTEGER* lpPerformanceCount
|
||||
) {
|
||||
BOOL rtn = __sys_QueryPerformanceCounter(lpPerformanceCount);
|
||||
lpPerformanceCount->QuadPart = lpPerformanceCount->QuadPart*SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1)/ SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
_FX UINT_PTR Gui_SetTimer(
|
||||
HWND hWnd,
|
||||
UINT_PTR nIDEvent,
|
||||
UINT uElapse,
|
||||
TIMERPROC lpTimerFunc
|
||||
)
|
||||
{
|
||||
return __sys_SetTimer(hWnd, nIDEvent, uElapse * SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1) / SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1), lpTimerFunc);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#include <aclapi.h>
|
||||
#include <dde.h>
|
||||
#include "misc.h"
|
||||
#include <wtsapi32.h>
|
||||
#include <userenv.h>
|
||||
#include "sbieiniserver.h"
|
||||
|
||||
#define PATTERN XPATTERN
|
||||
extern "C" {
|
||||
|
@ -906,9 +909,17 @@ bool GuiServer::QueueCallbackSlave2(void)
|
|||
args.rpl_len = rpl_len;
|
||||
args.rpl_buf = rpl_buf;
|
||||
|
||||
HDESK prev_desk;
|
||||
HDESK local_desktop = SwitchToCallerDesktop(args.pid, &prev_desk);
|
||||
|
||||
status = (this->*SlaveFuncPtr)(&args);
|
||||
if (status == 0)
|
||||
rpl_len = args.rpl_len;
|
||||
|
||||
if (local_desktop) {
|
||||
SetThreadDesktop(prev_desk);
|
||||
CloseDesktop(local_desktop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1583,19 +1594,12 @@ ULONG GuiServer::GetWindowStationSlave(SlaveArgs *args)
|
|||
local_winsta = GetProcessWindowStation();
|
||||
|
||||
WCHAR deskname[128] = { 0 };
|
||||
/*SbieApi_QueryConfAsIs(boxname, L"SandboxDesktopName", 0, deskname, sizeof(deskname));
|
||||
if(*value)
|
||||
local_desktop = OpenDesktop(value, 0, FALSE, GENERIC_ALL);
|
||||
else*/
|
||||
if (SbieApi_QueryConfBool(boxname, L"UseSandboxDesktop", FALSE)) {
|
||||
|
||||
wsprintf(deskname, L"%s_%s_Session_%d_Desktop", //_%08X",
|
||||
SANDBOXIE, boxname, m_SessionId); //GetTickCount());
|
||||
|
||||
local_desktop = OpenDesktop(deskname, 0, FALSE, GENERIC_ALL);
|
||||
if (!local_desktop)
|
||||
local_desktop = CreateDesktop(deskname, NULL, NULL, 0, GENERIC_ALL, NULL);
|
||||
|
||||
local_desktop = CreateBoxedDesktop(session_id, deskname);
|
||||
close_desktop = TRUE;
|
||||
} else
|
||||
local_desktop = GetThreadDesktop(GetCurrentThreadId());
|
||||
|
@ -1710,6 +1714,166 @@ finish:
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// CreateBoxedDesktop
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
struct SDeskStartParam
|
||||
{
|
||||
ULONG session_id;
|
||||
const wchar_t* desk_name;
|
||||
HDESK local_desktop;
|
||||
};
|
||||
|
||||
ULONG GuiServer__StartupWorker(void* _Param)
|
||||
{
|
||||
SDeskStartParam* pParam = (SDeskStartParam*)_Param;
|
||||
|
||||
ULONG status = 0;
|
||||
const ULONG TOKEN_RIGHTS = TOKEN_QUERY | TOKEN_DUPLICATE
|
||||
| TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID
|
||||
| TOKEN_ADJUST_GROUPS | TOKEN_ASSIGN_PRIMARY;
|
||||
HANDLE hOldToken = NULL;
|
||||
HANDLE hNewToken = NULL;
|
||||
//void *env = NULL;
|
||||
//WCHAR cmdline[MAX_PATH];
|
||||
BOOL ok = TRUE;
|
||||
|
||||
//
|
||||
// set thread desktop and check if explorer is already running
|
||||
//
|
||||
|
||||
SetThreadDesktop(pParam->local_desktop);
|
||||
|
||||
if (FindWindowW(L"Shell_TrayWnd", 0))
|
||||
return 0;
|
||||
|
||||
//
|
||||
// get the user token
|
||||
//
|
||||
|
||||
if (ok) {
|
||||
ok = WTSQueryUserToken(pParam->session_id, &hOldToken);
|
||||
if (! ok)
|
||||
status = 0x72000000 | GetLastError();
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
ok = DuplicateTokenEx(
|
||||
hOldToken, TOKEN_RIGHTS, NULL, SecurityAnonymous,
|
||||
TokenPrimary, &hNewToken);
|
||||
if (! ok)
|
||||
status = 0x73000000 | GetLastError();
|
||||
}
|
||||
|
||||
//
|
||||
// create the new shell process
|
||||
//
|
||||
|
||||
//ok = CreateEnvironmentBlock(&env, hNewToken, FALSE);
|
||||
//if (! ok)
|
||||
// status = 0x75000000 | GetLastError();
|
||||
|
||||
if (ok) {
|
||||
|
||||
//GetSystemWindowsDirectoryW(cmdline, MAX_PATH);
|
||||
//wcscat_s(cmdline, MAX_PATH, L"\\Explorer.exe");
|
||||
|
||||
//STARTUPINFO si;
|
||||
//PROCESS_INFORMATION pi;
|
||||
|
||||
//memzero(&si, sizeof(STARTUPINFO));
|
||||
//si.cb = sizeof(STARTUPINFO);
|
||||
//si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
//si.lpDesktop = (wchar_t*)pParam->desk_name;
|
||||
|
||||
//ok = CreateProcessAsUser(
|
||||
// hNewToken, NULL, cmdline, NULL, NULL, FALSE,
|
||||
// CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi);
|
||||
|
||||
//if (! ok)
|
||||
// status = 0x76000000 | GetLastError();
|
||||
//else {
|
||||
|
||||
// CloseHandle(pi.hThread);
|
||||
// CloseHandle(pi.hProcess);
|
||||
//}
|
||||
|
||||
SbieIniServer::RunSbieCtrl(hOldToken, pParam->desk_name);
|
||||
|
||||
for (int i = 0; i++ < 10 && !FindWindowW(L"Shell_TrayWnd", 0); Sleep(1000)); // wait 10 seconds
|
||||
}
|
||||
|
||||
if (hNewToken)
|
||||
CloseHandle(hNewToken);
|
||||
if (hOldToken)
|
||||
CloseHandle(hOldToken);
|
||||
//if (env)
|
||||
// DestroyEnvironmentBlock(env);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HDESK GuiServer::CreateBoxedDesktop(ULONG session_id, const wchar_t* desk_name)
|
||||
{
|
||||
HDESK local_desktop = OpenDesktop(desk_name, 0, FALSE, GENERIC_ALL);
|
||||
if (!local_desktop)
|
||||
local_desktop = CreateDesktop(desk_name, NULL, NULL, 0, GENERIC_ALL, NULL);
|
||||
if (local_desktop) {
|
||||
|
||||
SDeskStartParam* pParam = (SDeskStartParam*)HeapAlloc(GetProcessHeap(), 0, sizeof(SDeskStartParam));
|
||||
pParam->session_id = session_id;
|
||||
pParam->desk_name = desk_name;
|
||||
pParam->local_desktop = local_desktop;
|
||||
|
||||
HANDLE hThread = CreateThread(NULL, 0, GuiServer__StartupWorker, (void *)pParam, 0, NULL);
|
||||
WaitForSingleObject(hThread, 20 * 1000);
|
||||
CloseHandle(hThread);
|
||||
|
||||
HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, pParam);
|
||||
}
|
||||
return local_desktop;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// SwitchToCallerDesktop
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
HDESK GuiServer::SwitchToCallerDesktop(ULONG pid, HDESK* prev_desk)
|
||||
{
|
||||
ULONG status;
|
||||
WCHAR boxname[BOXNAME_COUNT];
|
||||
ULONG session_id;
|
||||
WCHAR deskname[128] = { 0 };
|
||||
HDESK local_desktop = NULL;
|
||||
|
||||
status = SbieApi_QueryProcess((HANDLE)(ULONG_PTR)pid, boxname, NULL, NULL, &session_id);
|
||||
if (!NT_SUCCESS(status))
|
||||
return NULL;
|
||||
|
||||
if (SbieApi_QueryConfBool(boxname, L"UseSandboxDesktop", FALSE)) {
|
||||
|
||||
wsprintf(deskname, L"%s_%s_Session_%d_Desktop", //_%08X",
|
||||
SANDBOXIE, boxname, m_SessionId); //GetTickCount());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
if (prev_desk) *prev_desk = GetThreadDesktop(GetCurrentThreadId());
|
||||
local_desktop = OpenDesktop(deskname, 0, FALSE, GENERIC_ALL);
|
||||
if (local_desktop) {
|
||||
|
||||
if (!SetThreadDesktop(local_desktop))
|
||||
SbieApi_LogEx(session_id, 2340, L"[%d]", GetLastError());
|
||||
}
|
||||
|
||||
return local_desktop;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// CreateConsoleSlave
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -74,6 +74,10 @@ protected:
|
|||
|
||||
bool QueueCallbackSlave2(void);
|
||||
|
||||
HDESK CreateBoxedDesktop(ULONG session_id, const wchar_t* deskname);
|
||||
|
||||
HDESK SwitchToCallerDesktop(ULONG pid, HDESK* prev_desk);
|
||||
|
||||
HANDLE GetJobObjectForAssign(const WCHAR *boxname);
|
||||
|
||||
HANDLE GetJobObjectForGrant(ULONG pid);
|
||||
|
|
|
@ -486,6 +486,11 @@ ULONG SbieIniServer::CheckRequest(MSG_HEADER *msg)
|
|||
|
||||
|
||||
bool SbieIniServer::SetUserSettingsSectionName(HANDLE hToken)
|
||||
{
|
||||
return SetUserSettingsSectionName(hToken, m_username, m_sectionname);
|
||||
}
|
||||
|
||||
bool SbieIniServer::SetUserSettingsSectionName(HANDLE hToken, WCHAR* m_username, WCHAR* m_sectionname)
|
||||
{
|
||||
union {
|
||||
TOKEN_USER user;
|
||||
|
@ -493,8 +498,6 @@ bool SbieIniServer::SetUserSettingsSectionName(HANDLE hToken)
|
|||
WCHAR value[4];
|
||||
} info;
|
||||
|
||||
m_admin = FALSE;
|
||||
|
||||
//
|
||||
// if the UserSettings_Portable section exists, use that
|
||||
//
|
||||
|
@ -521,7 +524,7 @@ bool SbieIniServer::SetUserSettingsSectionName(HANDLE hToken)
|
|||
if (! ok)
|
||||
return false;
|
||||
|
||||
ULONG username_len = sizeof(m_username) / sizeof(WCHAR) - 4;
|
||||
ULONG username_len = 256 - 4; // ULONG username_len = sizeof(m_username) / sizeof(WCHAR) - 4;
|
||||
WCHAR domain[256];
|
||||
ULONG domain_len = sizeof(domain) / sizeof(WCHAR) - 4;
|
||||
SID_NAME_USE use;
|
||||
|
@ -533,7 +536,7 @@ bool SbieIniServer::SetUserSettingsSectionName(HANDLE hToken)
|
|||
if (! ok || ! m_username[0])
|
||||
return false;
|
||||
|
||||
m_username[sizeof(m_username) / sizeof(WCHAR) - 4] = L'\0';
|
||||
m_username[username_len] = L'\0'; //m_username[sizeof(m_username) / sizeof(WCHAR) - 4] = L'\0';
|
||||
_wcslwr(m_username);
|
||||
|
||||
//
|
||||
|
@ -2245,7 +2248,6 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(MSG_HEADER *msg, HANDLE idProcess, bool i
|
|||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
HANDLE hToken = NULL;
|
||||
BOOL ok = TRUE;
|
||||
WCHAR ctrlCmd[128] = { 0 };
|
||||
|
||||
//
|
||||
// get token from caller session or caller process. note that on
|
||||
|
@ -2309,14 +2311,42 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(MSG_HEADER *msg, HANDLE idProcess, bool i
|
|||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if(isSandboxed || msg->length <= sizeof(MSG_HEADER))
|
||||
status = RunSbieCtrl(hToken, NULL);
|
||||
else
|
||||
status = RunSbieCtrl(hToken, NULL, (WCHAR*)((UCHAR*)msg + sizeof(MSG_HEADER)), (msg->length - sizeof(MSG_HEADER)) / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
//
|
||||
// finish
|
||||
//
|
||||
|
||||
if (hToken)
|
||||
CloseHandle(hToken);
|
||||
|
||||
return SHORT_REPLY(status);
|
||||
}
|
||||
|
||||
NTSTATUS SbieIniServer::RunSbieCtrl(HANDLE hToken, const WCHAR* DeskName, const WCHAR* CtrlCmd, size_t CtrlCmdLen)
|
||||
{
|
||||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
BOOL ok = TRUE;
|
||||
|
||||
WCHAR ctrlCmd[128] = { 0 };
|
||||
|
||||
//
|
||||
// get the agent binary name
|
||||
//
|
||||
|
||||
if (isSandboxed) {
|
||||
if (!CtrlCmd) {
|
||||
|
||||
WCHAR m_username[256];
|
||||
WCHAR m_sectionname[128];
|
||||
|
||||
const WCHAR* _Setting2 = SBIECTRL_ L"AutoStartAgent";
|
||||
bool ok2 = SetUserSettingsSectionName(hToken);
|
||||
bool ok2 = SetUserSettingsSectionName(hToken, m_username, m_sectionname);
|
||||
if (ok2) {
|
||||
SbieApi_QueryConfAsIs(
|
||||
m_sectionname, _Setting2, 0, ctrlCmd, sizeof(ctrlCmd) - 2);
|
||||
|
@ -2327,11 +2357,10 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(MSG_HEADER *msg, HANDLE idProcess, bool i
|
|||
m_sectionname, _Setting2, 0, ctrlCmd, sizeof(ctrlCmd) - 2);
|
||||
}
|
||||
|
||||
} else if (msg->length > sizeof(MSG_HEADER)) {
|
||||
} else if (CtrlCmdLen > 0) {
|
||||
|
||||
ULONG len = (ULONG)(msg->length - sizeof(MSG_HEADER));
|
||||
memcpy(ctrlCmd, (UCHAR*)msg + sizeof(MSG_HEADER), len);
|
||||
ctrlCmd[len / sizeof(WCHAR)] = L'\0';
|
||||
memcpy(ctrlCmd, CtrlCmd, CtrlCmdLen * sizeof(WCHAR));
|
||||
ctrlCmd[CtrlCmdLen] = L'\0';
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2370,6 +2399,10 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(MSG_HEADER *msg, HANDLE idProcess, bool i
|
|||
memzero(&si, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.dwFlags = STARTF_FORCEOFFFEEDBACK;
|
||||
if (DeskName) {
|
||||
si.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
si.lpDesktop = (wchar_t*)DeskName;
|
||||
}
|
||||
|
||||
ok = CreateProcessAsUser(
|
||||
hToken, NULL, CmdLine, NULL, NULL, FALSE,
|
||||
|
@ -2391,14 +2424,7 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(MSG_HEADER *msg, HANDLE idProcess, bool i
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// finish
|
||||
//
|
||||
|
||||
if (hToken)
|
||||
CloseHandle(hToken);
|
||||
|
||||
return SHORT_REPLY(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ protected:
|
|||
|
||||
bool SetUserSettingsSectionName(HANDLE hToken);
|
||||
|
||||
static bool SetUserSettingsSectionName(HANDLE hToken, WCHAR* m_username, WCHAR* m_sectionname);
|
||||
|
||||
bool UserCanEdit(HANDLE hToken);
|
||||
|
||||
#ifdef NEW_INI_MODE
|
||||
|
@ -107,6 +109,9 @@ protected:
|
|||
|
||||
MSG_HEADER *RC4Crypt(MSG_HEADER *msg, HANDLE idProcess, bool isSandboxed);
|
||||
|
||||
public:
|
||||
|
||||
static NTSTATUS RunSbieCtrl(HANDLE hToken, const WCHAR* DeskName, const WCHAR* CtrlCmd = NULL, size_t CtrlCmdLen = 0);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -122,7 +127,6 @@ protected:
|
|||
WCHAR m_line[1500];
|
||||
//BOOLEAN m_insertbom;
|
||||
#endif
|
||||
BOOLEAN m_admin;
|
||||
HANDLE m_hLockFile;
|
||||
ULONG m_session_id;
|
||||
|
||||
|
|
|
@ -767,6 +767,10 @@ SBIE2337 Failed to start program: %2
|
|||
SBIE2338 Encountered unsupported architecture in process: %2
|
||||
.
|
||||
|
||||
2340;pop;err;01
|
||||
SBIE2340 Desktop worker failed to switch to caller Desktop: %2
|
||||
.
|
||||
|
||||
# 2398;txt;01
|
||||
# SBIE2398 Service suffers exception ... at address ...
|
||||
# .
|
||||
|
@ -921,7 +925,7 @@ Programs
|
|||
.
|
||||
|
||||
3198;txt;01
|
||||
Do you want to start a new program in the %2 sandbox?
|
||||
Do you want to start a new program into the sandbox %2?
|
||||
You received this message because you set AlertBeforeStart=y.
|
||||
.
|
||||
|
||||
|
|
|
@ -293,6 +293,17 @@ private slots:
|
|||
}
|
||||
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent* event) override
|
||||
{
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (!index.isValid()) {
|
||||
emit doubleClicked(index);
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeView::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
QMenu* m_pMenu;
|
||||
QMap<QAction*, int> m_Columns;
|
||||
QSet<int> m_FixedColumns;
|
||||
|
|
|
@ -824,3 +824,10 @@ SB_STATUS CSandBox::ImBoxUnmount()
|
|||
{
|
||||
return m_pAPI->ImBoxUnmount(this);
|
||||
}
|
||||
|
||||
SB_STATUS CSandBox::SwitchToDesktop()
|
||||
{
|
||||
if (m_Desktop.isEmpty())
|
||||
return SB_OK; // nothign to do
|
||||
return m_pAPI->SwitchToDesktop(m_Desktop);
|
||||
}
|
|
@ -84,6 +84,10 @@ public:
|
|||
virtual SB_STATUS ImBoxMount(const QString& Password = QString(), bool bProtect = false, bool bAutoUnmount = false);
|
||||
virtual SB_STATUS ImBoxUnmount();
|
||||
|
||||
// Desktop Manager
|
||||
virtual QString GetDesktop() const { return m_Desktop; }
|
||||
virtual SB_STATUS SwitchToDesktop();
|
||||
|
||||
class CSbieAPI* Api() { return m_pAPI; }
|
||||
|
||||
protected:
|
||||
|
@ -102,6 +106,8 @@ protected:
|
|||
QString m_IpcPath;
|
||||
QString m_Mount;
|
||||
|
||||
QString m_Desktop;
|
||||
|
||||
bool m_IsEnabled;
|
||||
|
||||
QMap<quint32, CBoxedProcessPtr> m_ProcessList;
|
||||
|
|
|
@ -2626,6 +2626,84 @@ SB_RESULT(QVariantMap) CSbieAPI::ImBoxQuery(const QString& Root)
|
|||
return CSbieResult<QVariantMap>(Info);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Desktop Manager
|
||||
//
|
||||
|
||||
BOOL CALLBACK CSbieAPI__EnumDesktopsProc(LPWSTR lpszDesktop, LPARAM lParam)
|
||||
{
|
||||
CSbieAPI::TDesktopMap* pDesktops = (CSbieAPI::TDesktopMap*)lParam;
|
||||
QString Name = QString::fromWCharArray(lpszDesktop); // Sandboxie_[BoxName]_Session_[Num]_Desktop
|
||||
QStringList Names = Name.split("_");
|
||||
if (Names.count() > 3 && Names[0] == "Sandboxie" && Names[2] == "Session")
|
||||
pDesktops->insert(Names[1].toLower(), Name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SB_RESULT(CSbieAPI::TDesktopMap) CSbieAPI::EnumBoxDesktops()
|
||||
{
|
||||
TDesktopMap Desktops;
|
||||
|
||||
HWINSTA hWinSta = GetProcessWindowStation();
|
||||
if (hWinSta == NULL)
|
||||
return SB_ERR(STATUS_UNSUCCESSFUL);
|
||||
|
||||
// Enumerate all desktops associated with the current window station
|
||||
if (!EnumDesktopsW(hWinSta, CSbieAPI__EnumDesktopsProc, (LPARAM)&Desktops))
|
||||
return SB_ERR(STATUS_UNSUCCESSFUL);
|
||||
|
||||
foreach(const CSandBoxPtr & pBox, m_SandBoxes)
|
||||
pBox->m_Desktop = Desktops.value(pBox->m_Name.toLower());
|
||||
|
||||
return CSbieResult<TDesktopMap>(Desktops);
|
||||
}
|
||||
|
||||
SB_STATUS CSbieAPI::SwitchToDesktop(const QString& Desktop)
|
||||
{
|
||||
BOOL ok = FALSE;
|
||||
|
||||
HDESK hDesktop = OpenDesktop(Desktop.toStdWString().c_str(), 0, FALSE, DESKTOP_SWITCHDESKTOP);
|
||||
if (hDesktop != NULL)
|
||||
{
|
||||
ok = SwitchDesktop(hDesktop);
|
||||
|
||||
CloseDesktop(hDesktop);
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
return SB_ERR(STATUS_UNSUCCESSFUL);
|
||||
return SB_OK;
|
||||
}
|
||||
|
||||
QString CSbieAPI__GetDesktopName(HDESK hDesktop)
|
||||
{
|
||||
wchar_t desktopName[MAX_PATH];
|
||||
DWORD neededLength = sizeof(desktopName);
|
||||
if (!GetUserObjectInformationW(hDesktop, UOI_NAME, desktopName, neededLength, &neededLength))
|
||||
return QString();
|
||||
|
||||
return QString::fromWCharArray(desktopName);
|
||||
}
|
||||
|
||||
QString CSbieAPI::GetCurrentDesktopName()
|
||||
{
|
||||
HDESK hDesktop = GetThreadDesktop(GetCurrentThreadId());
|
||||
if (hDesktop == NULL)
|
||||
return QString();
|
||||
return CSbieAPI__GetDesktopName(hDesktop);
|
||||
}
|
||||
|
||||
bool CSbieAPI::IsCurrentDesktopActive()
|
||||
{
|
||||
QString CurrentDesktop = CSbieAPI::GetCurrentDesktopName();
|
||||
QString ActiveDesktop;
|
||||
HDESK hInputDesktop = OpenInputDesktop(0, FALSE, DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP);
|
||||
if (hInputDesktop) {
|
||||
ActiveDesktop = CSbieAPI__GetDesktopName(hInputDesktop);
|
||||
CloseDesktop(hInputDesktop);
|
||||
}
|
||||
return CurrentDesktop.compare(ActiveDesktop, Qt::CaseInsensitive) == 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Monitor
|
||||
|
|
|
@ -140,6 +140,13 @@ public:
|
|||
virtual SB_RESULT(QVariantMap) ImBoxQuery(const QString& Root = QString());
|
||||
//virtual SB_STATUS ImBoxUpdate( // todo
|
||||
|
||||
// Desktop Manager
|
||||
typedef QMultiMap<QString, QString> TDesktopMap;
|
||||
virtual SB_RESULT(TDesktopMap) EnumBoxDesktops();
|
||||
virtual SB_STATUS SwitchToDesktop(const QString& Desktop);
|
||||
static QString GetCurrentDesktopName();
|
||||
static bool IsCurrentDesktopActive();
|
||||
|
||||
// Monitor
|
||||
virtual SB_STATUS EnableMonitor(bool Enable);
|
||||
virtual bool IsMonitoring();
|
||||
|
|
|
@ -170,3 +170,26 @@ QString GetProductVersion(const QString &filePath)
|
|||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool KillProcessById(DWORD processId)
|
||||
{
|
||||
bool ok = false;
|
||||
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, processId);
|
||||
if (hProcess && hProcess != INVALID_HANDLE_VALUE) {
|
||||
if (TerminateProcess(hProcess, 0))
|
||||
ok = true;
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool KillProcessByWnd(const QString& WndName)
|
||||
{
|
||||
HWND hwnd = FindWindowW(WndName.toStdWString().c_str(), 0);
|
||||
if (hwnd) {
|
||||
DWORD processId;
|
||||
if (GetWindowThreadProcessId(hwnd, &processId))
|
||||
return KillProcessById(processId);
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -9,3 +9,5 @@ bool PickWindowsIcon(QWidget* pParent, QString& Path, quint32& Index);
|
|||
void ProtectWindow(void* hWnd);
|
||||
|
||||
QString GetProductVersion(const QString& filePath);
|
||||
|
||||
bool KillProcessByWnd(const QString& WndName);
|
|
@ -115,7 +115,7 @@ CSandMan* theGUI = NULL;
|
|||
extern QString g_PendingMessage;
|
||||
|
||||
|
||||
CSandMan::CSandMan(QWidget *parent)
|
||||
CSandMan::CSandMan(const QString& BoxDesktop, bool bAutoRun, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -126,6 +126,8 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
|
||||
CArchive::Init();
|
||||
|
||||
m_BoxDesktop = BoxDesktop;
|
||||
|
||||
theGUI = this;
|
||||
|
||||
m_DarkTheme = false;
|
||||
|
@ -181,6 +183,7 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
connect(theAPI, SIGNAL(StatusChanged()), this, SLOT(OnStatusChanged()));
|
||||
|
||||
connect(theAPI, SIGNAL(BoxAdded(const CSandBoxPtr&)), this, SLOT(OnBoxAdded(const CSandBoxPtr&)));
|
||||
connect(theAPI, SIGNAL(BoxOpened(const CSandBoxPtr&)), this, SLOT(OnBoxOpened(const CSandBoxPtr&)));
|
||||
connect(theAPI, SIGNAL(BoxClosed(const CSandBoxPtr&)), this, SLOT(OnBoxClosed(const CSandBoxPtr&)));
|
||||
connect(theAPI, SIGNAL(BoxCleaned(CSandBoxPlus*)), this, SLOT(OnBoxCleaned(CSandBoxPlus*)));
|
||||
|
||||
|
@ -256,7 +259,7 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
m_BoxColors[CSandBoxPlus::eOpen] = qRgb(255,255,255);
|
||||
m_BoxColors[CSandBoxPlus::ePrivate] = qRgb(56,56,56);
|
||||
|
||||
CreateTrayIcon();
|
||||
CreateTrayIcon(bAutoRun);
|
||||
|
||||
LoadState();
|
||||
|
||||
|
@ -284,7 +287,6 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
|
||||
m_uTimerID = startTimer(1000);
|
||||
|
||||
bool bAutoRun = QApplication::arguments().contains("-autorun");
|
||||
if (!bAutoRun && g_PendingMessage.isEmpty())
|
||||
SafeShow(this);
|
||||
|
||||
|
@ -537,6 +539,8 @@ void CSandMan::CreateMenus(bool bAdvanced)
|
|||
//m_pUpdateCore = NULL;
|
||||
}
|
||||
|
||||
m_pDefaultDesktop = m_pMenuFile->addAction(CSandMan::GetIcon("Monitor"), tr("Return to Default Desktop"), this, SLOT(OnDefaultDesktop()));
|
||||
if (m_BoxDesktop.isEmpty()) m_pDefaultDesktop->setEnabled(false);
|
||||
m_pMenuFile->addSeparator();
|
||||
m_pRestart = m_pMenuFile->addAction(CSandMan::GetIcon("Shield9"), tr("Restart As Admin"), this, SLOT(OnRestartAsAdmin()));
|
||||
m_pExit = m_pMenuFile->addAction(CSandMan::GetIcon("Exit"), tr("Exit"), this, SLOT(OnExit()));
|
||||
|
@ -694,6 +698,8 @@ void CSandMan::CreateOldMenus()
|
|||
m_pSetupWizard = NULL;
|
||||
//m_pUpdateCore = NULL;
|
||||
}
|
||||
m_pDefaultDesktop = m_pMenuFile->addAction(CSandMan::GetIcon("Monitor"), tr("Return to Default Desktop"), this, SLOT(OnDefaultDesktop()));
|
||||
if (m_BoxDesktop.isEmpty()) m_pDefaultDesktop->setEnabled(false);
|
||||
m_pRestart = m_pMenuFile->addAction(CSandMan::GetIcon("Shield9"), tr("Restart As Admin"), this, SLOT(OnRestartAsAdmin()));
|
||||
m_pExit = m_pMenuFile->addAction(CSandMan::GetIcon("Exit"), tr("Exit"), this, SLOT(OnExit()));
|
||||
|
||||
|
@ -866,6 +872,8 @@ QList<ToolBarAction> CSandMan::GetAvailableToolBarActions()
|
|||
ToolBarAction{ "CheckForUpdates", m_pUpdate },
|
||||
ToolBarAction{ "About", m_pAbout },
|
||||
ToolBarAction{ "", nullptr }, // separator
|
||||
ToolBarAction{ "pApp", m_pDefaultDesktop },
|
||||
ToolBarAction{ "", nullptr }, // separator
|
||||
ToolBarAction{ "RestartAsAdmin", m_pRestart },
|
||||
ToolBarAction{ "Exit", m_pExit },
|
||||
ToolBarAction{ "", nullptr }, // separator
|
||||
|
@ -1300,24 +1308,35 @@ void CSandMan::CheckForUpdates(bool bManual)
|
|||
m_pUpdater->CheckForUpdates(bManual);
|
||||
}
|
||||
|
||||
#include "SandManTray.cpp"
|
||||
void CSandMan::OnDefaultDesktop()
|
||||
{
|
||||
theAPI->SwitchToDesktop("Default");
|
||||
}
|
||||
|
||||
void CSandMan::OnRestartAsAdmin()
|
||||
{
|
||||
theAPI->Disconnect();
|
||||
Restart(true);
|
||||
OnExit();
|
||||
}
|
||||
|
||||
void CSandMan::Restart(bool AsAdmin)
|
||||
{
|
||||
WCHAR buf[255] = { 0 };
|
||||
GetModuleFileNameW(NULL, buf, 255);
|
||||
SHELLEXECUTEINFO se;
|
||||
memset(&se, 0, sizeof(SHELLEXECUTEINFO));
|
||||
se.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
se.lpVerb = L"runas";
|
||||
if(AsAdmin)
|
||||
se.lpVerb = L"runas";
|
||||
se.lpFile = buf;
|
||||
se.nShow = SW_HIDE;
|
||||
se.nShow = SW_SHOWNORMAL;
|
||||
se.fMask = 0;
|
||||
ShellExecuteEx(&se);
|
||||
OnExit();
|
||||
}
|
||||
|
||||
#include "SandManTray.cpp"
|
||||
|
||||
void CSandMan::OnExit()
|
||||
{
|
||||
m_bExit = true;
|
||||
|
@ -1353,7 +1372,17 @@ void CSandMan::closeEvent(QCloseEvent *e)
|
|||
|
||||
emit Closed();
|
||||
|
||||
if (IsFullyPortable() && theAPI->IsConnected())
|
||||
if (!m_BoxDesktop.isEmpty())
|
||||
{
|
||||
auto pBoxEx = theAPI->GetBoxByName(m_BoxDesktop).objectCast<CSandBoxPlus>();
|
||||
if (pBoxEx) pBoxEx->TerminateAll();
|
||||
theAPI->SwitchToDesktop("Default");
|
||||
if (!KillProcessByWnd("Shell_TrayWnd")) {
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (IsFullyPortable() && theAPI->IsConnected())
|
||||
{
|
||||
int PortableStop = theConf->GetInt("Options/PortableStop", -1);
|
||||
if (PortableStop == -1)
|
||||
|
@ -1716,14 +1745,24 @@ bool CSandMan::RunSandboxed(const QStringList& Commands, QString BoxName, const
|
|||
SB_RESULT(quint32) CSandMan::RunStart(const QString& BoxName, const QString& Command, CSbieAPI::EStartFlags Flags, const QString& WorkingDir, QProcess* pProcess)
|
||||
{
|
||||
auto pBoxEx = theAPI->GetBoxByName(BoxName).objectCast<CSandBoxPlus>();
|
||||
if (pBoxEx && pBoxEx->UseImageFile() && pBoxEx->GetMountRoot().isEmpty()) {
|
||||
|
||||
if (pBoxEx && pBoxEx->UseImageFile() && pBoxEx->GetMountRoot().isEmpty())
|
||||
{
|
||||
SB_STATUS Status = ImBoxMount(pBoxEx, true);
|
||||
if (Status.IsError())
|
||||
return Status;
|
||||
}
|
||||
|
||||
return theAPI->RunStart(BoxName, Command, Flags, WorkingDir, pProcess);
|
||||
auto Res = theAPI->RunStart(BoxName, Command, Flags, WorkingDir, pProcess);
|
||||
|
||||
if (!Res.IsError() && pBoxEx->GetBool("UseSandboxDesktop", false) && theConf->GetBool("Options/AutoDesktopSwitch", true))
|
||||
{
|
||||
QTimer::singleShot(1000, this, [pBoxEx]() {
|
||||
theAPI->EnumBoxDesktops();
|
||||
pBoxEx->SwitchToDesktop();
|
||||
});
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
SB_STATUS CSandMan::ImBoxMount(const CSandBoxPtr& pBox, bool bAutoUnmount)
|
||||
|
@ -2121,6 +2160,7 @@ finish:
|
|||
void CSandMan::UpdateProcesses()
|
||||
{
|
||||
theAPI->UpdateProcesses(KeepTerminated() ? -1 : 1500, ShowAllSessions()); // keep for 1.5 sec
|
||||
theAPI->EnumBoxDesktops();
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxAdded(const CSandBoxPtr& pBox)
|
||||
|
@ -2297,8 +2337,19 @@ void CSandMan::OnStartMenuChanged()
|
|||
}
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxOpened(const CSandBoxPtr& pBox)
|
||||
{
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxClosed(const CSandBoxPtr& pBox)
|
||||
{
|
||||
if (!m_BoxDesktop.isEmpty())
|
||||
{
|
||||
if (!theAPI->IsCurrentDesktopActive())
|
||||
OnExit();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(const QString & Value, pBox->GetTextList("OnBoxTerminate", true, false, true)) {
|
||||
QString Value2 = pBox->Expand(Value);
|
||||
CSbieProgressPtr pProgress = CSbieUtils::RunCommand(Value2, true);
|
||||
|
|
|
@ -39,7 +39,7 @@ class CSandMan : public QMainWindow
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CSandMan(QWidget *parent = Q_NULLPTR);
|
||||
CSandMan(const QString& BoxDesktop, bool bAutoRun, QWidget *parent = Q_NULLPTR);
|
||||
virtual ~CSandMan();
|
||||
|
||||
CSbieTemplatesEx* GetCompat() { return m_SbieTemplates; }
|
||||
|
@ -79,6 +79,7 @@ public:
|
|||
bool IsShowHidden() { return m_pShowHidden && m_pShowHidden->isChecked(); }
|
||||
bool KeepTerminated();
|
||||
bool ShowAllSessions() { return m_pShowAllSessions && m_pShowAllSessions->isChecked(); }
|
||||
const QString& GetBoxDesktop() const { return m_BoxDesktop; }
|
||||
bool IsSilentMode();
|
||||
bool IsDisableRecovery() {return IsSilentMode() || m_pDisableRecovery && m_pDisableRecovery->isChecked();}
|
||||
bool IsDisableMessages() {return IsSilentMode() || m_pDisableMessages && m_pDisableMessages->isChecked();}
|
||||
|
@ -119,6 +120,8 @@ public:
|
|||
|
||||
void SaveMessageLog(QIODevice* pFile);
|
||||
|
||||
static void Restart(bool AsAdmin = false);
|
||||
|
||||
signals:
|
||||
void DrivesChanged();
|
||||
|
||||
|
@ -154,6 +157,7 @@ protected:
|
|||
bool m_bConnectPending;
|
||||
bool m_bStopPending;
|
||||
CBoxBorder* m_pBoxBorder;
|
||||
QString m_BoxDesktop;
|
||||
CSbieTemplatesEx* m_SbieTemplates;
|
||||
|
||||
CScriptManager* m_SbieScripts;
|
||||
|
@ -226,6 +230,7 @@ public slots:
|
|||
void OnCancelAsync();
|
||||
|
||||
void OnBoxAdded(const CSandBoxPtr& pBox);
|
||||
void OnBoxOpened(const CSandBoxPtr& pBox);
|
||||
void OnBoxClosed(const CSandBoxPtr& pBox);
|
||||
void OnBoxCleaned(CSandBoxPlus* pBoxEx);
|
||||
|
||||
|
@ -262,6 +267,7 @@ private slots:
|
|||
void OnDisableForce2();
|
||||
void OnDisablePopUp();
|
||||
void OnMaintenance();
|
||||
void OnDefaultDesktop();
|
||||
|
||||
void OnViewMode(QAction* action);
|
||||
void OnAlwaysTop();
|
||||
|
@ -311,7 +317,7 @@ private:
|
|||
void CreateToolBar(bool bRebuild);
|
||||
void CreateLabel();
|
||||
void CreateView(int iViewMode);
|
||||
void CreateTrayIcon();
|
||||
void CreateTrayIcon(bool bAutoRun);
|
||||
void CreateTrayMenu();
|
||||
void CreateBoxMenu(QMenu* pMenu, int iOffset = 0, int iSysTrayFilter = 0);
|
||||
|
||||
|
@ -371,7 +377,6 @@ private:
|
|||
QHBoxLayout* m_pMenuLayout;
|
||||
|
||||
QMenu* m_pMenuFile;
|
||||
QAction* m_pRestart;
|
||||
QAction* m_pRunBoxed;
|
||||
QAction* m_pNewBox;
|
||||
QAction* m_pNewGroup;
|
||||
|
@ -401,6 +406,8 @@ private:
|
|||
QAction* m_pImDiskCpl;
|
||||
QAction* m_pUninstallAll;
|
||||
QAction* m_pSetupWizard;
|
||||
QAction* m_pDefaultDesktop;
|
||||
QAction* m_pRestart;
|
||||
QAction* m_pExit;
|
||||
|
||||
QMenu* m_pMenuView;
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
|
||||
bool CTrayBoxesItemDelegate::m_Hold = false;
|
||||
|
||||
void CSandMan::CreateTrayIcon()
|
||||
void CSandMan::CreateTrayIcon(bool bAutoRun)
|
||||
{
|
||||
m_pTrayIcon = new QSystemTrayIcon(GetTrayIcon(), this);
|
||||
m_pTrayIcon->setToolTip(GetTrayText());
|
||||
|
@ -30,8 +30,6 @@ void CSandMan::CreateTrayIcon()
|
|||
|
||||
CreateTrayMenu();
|
||||
|
||||
bool bAutoRun = QApplication::arguments().contains("-autorun");
|
||||
|
||||
if(g_PendingMessage.isEmpty()){
|
||||
m_pTrayIcon->show(); // Note: qt bug; hide does not work if not showing first :/
|
||||
if(!bAutoRun && theConf->GetInt("Options/SysTrayIcon", 1) == 0)
|
||||
|
@ -125,6 +123,11 @@ void CSandMan::CreateTrayMenu()
|
|||
//m_pTrayMenu->addAction(pBoxWidget);
|
||||
//m_pTrayMenu->addSeparator();
|
||||
|
||||
if (m_pDefaultDesktop->isEnabled()) {
|
||||
m_pTrayMenu->addAction(m_pDefaultDesktop);
|
||||
m_pTrayMenu->addSeparator();
|
||||
}
|
||||
|
||||
m_pTrayMenu->addAction(m_pExit);
|
||||
}
|
||||
|
||||
|
|
|
@ -197,6 +197,8 @@ void CSbieView::CreateMenu()
|
|||
m_iMenuRun = m_pMenuRun->actions().count();
|
||||
m_pMenuEmptyBox = m_pMenuBox->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate All Programs"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuBox->addSeparator();
|
||||
m_pMenuSwitchDesk = m_pMenuBox->addAction(CSandMan::GetIcon("Monitor"), tr("Switch to Isoalted Desktop"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuBox->addSeparator();
|
||||
m_pMenuContent = m_pMenuBox->addMenu(CSandMan::GetIcon("Compatibility"), tr("Box Content"));
|
||||
m_pMenuBrowse = m_pMenuContent->addAction(CSandMan::GetIcon("Folder"), tr("Browse Files"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuContent->addSeparator();
|
||||
|
@ -327,6 +329,7 @@ void CSbieView::CreateOldMenu()
|
|||
|
||||
m_pMenuBox->addSeparator();
|
||||
m_pMenuEmptyBox = m_pMenuBox->addAction(CSandMan::GetIcon("EmptyAll"), tr("Terminate Programs"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuSwitchDesk = m_pMenuBox->addAction(CSandMan::GetIcon("Monitor"), tr("Switch to Isoalted Desktop"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuMount = m_pMenuBox->addAction(CSandMan::GetIcon("LockOpen"), tr("Mount Box Image"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuUnmount = m_pMenuBox->addAction(CSandMan::GetIcon("LockClosed"), tr("Unmount Box Image"), this, SLOT(OnSandBoxAction()));
|
||||
m_pMenuRecover = m_pMenuBox->addAction(CSandMan::GetIcon("Recover"), tr("Quick Recover"), this, SLOT(OnSandBoxAction()));
|
||||
|
@ -416,6 +419,8 @@ void CSbieView::CreateTrayMenu()
|
|||
m_pMenuTray->addMenu(m_pMenuRun);
|
||||
m_pMenuTray->addAction(m_pMenuEmptyBox);
|
||||
m_pMenuTray->addSeparator();
|
||||
m_pMenuTray->addAction(m_pMenuSwitchDesk);
|
||||
m_pMenuTray->addSeparator();
|
||||
m_pMenuTray->addAction(m_pMenuBrowse);
|
||||
m_pMenuTray->addAction(m_pMenuExplore);
|
||||
m_pMenuTray->addAction(m_pMenuRegEdit);
|
||||
|
@ -477,7 +482,16 @@ QString CSbieView__SerializeGroup(QMap<QString, QStringList>& m_Groups, const QS
|
|||
|
||||
void CSbieView::Refresh()
|
||||
{
|
||||
QList<QVariant> Added = m_pSbieModel->Sync(theAPI->GetAllBoxes(), m_Groups, theGUI->IsShowHidden());
|
||||
QMap<QString, CSandBoxPtr> Boxes;
|
||||
if (!theGUI->GetBoxDesktop().isEmpty()
|
||||
#ifdef _DEBUG
|
||||
&& !theGUI->ShowAllSessions()
|
||||
#endif
|
||||
)
|
||||
Boxes.insert(theGUI->GetBoxDesktop().toLower(), theAPI->GetBoxByName(theGUI->GetBoxDesktop()));
|
||||
else
|
||||
Boxes = theAPI->GetAllBoxes();
|
||||
QList<QVariant> Added = m_pSbieModel->Sync(Boxes, m_Groups, theGUI->IsShowHidden());
|
||||
|
||||
if (m_pSbieModel->IsTree())
|
||||
{
|
||||
|
@ -628,6 +642,7 @@ bool CSbieView::UpdateMenu(bool bAdvanced, const CSandBoxPtr &pBox, int iSandBox
|
|||
m_pMenuCleanUp->setEnabled(iSandBoxeCount > 0);
|
||||
if (m_pMenuContent) m_pMenuContent->setEnabled(iSandBoxeCount > 0);
|
||||
m_pMenuEmptyBox->setEnabled(iSandBoxeCount > 0);
|
||||
m_pMenuSwitchDesk->setEnabled(iSandBoxeCount == 1 && !pBoxEx->GetDesktop().isEmpty());
|
||||
|
||||
m_pMenuBrowse->setEnabled(iSandBoxeCount == 1);
|
||||
m_pMenuExplore->setEnabled(iSandBoxeCount == 1);
|
||||
|
@ -1551,6 +1566,10 @@ void CSbieView::OnSandBoxAction(QAction* Action, const QList<CSandBoxPtr>& SandB
|
|||
foreach(const CSandBoxPtr& pBox, SandBoxes)
|
||||
Results.append(pBox->TerminateAll());
|
||||
}
|
||||
else if (Action == m_pMenuSwitchDesk)
|
||||
{
|
||||
Results.append(SandBoxes.first()->SwitchToDesktop());
|
||||
}
|
||||
else if (Action == m_pMenuMkLink)
|
||||
{
|
||||
if (theConf->GetInt("Options/InfoMkLink", -1) == -1)
|
||||
|
@ -1759,6 +1778,12 @@ void CSbieView::ShowBrowse(const CSandBoxPtr& pBox)
|
|||
|
||||
void CSbieView::OnDoubleClicked(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
if (!theGUI->GetBoxDesktop().isEmpty() && theConf->GetBool("Options/QuickDesktopSwitch", true))
|
||||
theAPI->SwitchToDesktop("Default");
|
||||
return;
|
||||
}
|
||||
|
||||
QModelIndex ModelIndex = m_pSortProxy->mapToSource(index);
|
||||
CSandBoxPtr pBox = m_pSbieModel->GetSandBox(ModelIndex);
|
||||
if (pBox.isNull())
|
||||
|
@ -1774,6 +1799,11 @@ void CSbieView::OnDoubleClicked(const QModelIndex& index)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!pBox->GetDesktop().isEmpty() && theConf->GetBool("Options/QuickDesktopSwitch", true) && theGUI->GetBoxDesktop().compare(pBox->GetName(), Qt::CaseInsensitive) != 0) {
|
||||
pBox->SwitchToDesktop();
|
||||
return;
|
||||
}
|
||||
|
||||
//if (index.column() != CSbieModel::eName)
|
||||
// return;
|
||||
|
||||
|
@ -2207,7 +2237,7 @@ void CSbieView::ClearUserUIConfig(const QMap<QString, CSandBoxPtr> AllBoxes)
|
|||
|
||||
void CSbieView::SaveBoxGrouping()
|
||||
{
|
||||
if (!theAPI->IsConnected())
|
||||
if (!theAPI->IsConnected() || !theGUI->GetBoxDesktop().isEmpty())
|
||||
return;
|
||||
|
||||
theAPI->GetUserSettings()->SetRefreshOnChange(false);
|
||||
|
|
|
@ -186,6 +186,7 @@ private:
|
|||
QAction* m_pMenuOptions;
|
||||
QAction* m_pMenuSnapshots;
|
||||
QAction* m_pMenuEmptyBox;
|
||||
QAction* m_pMenuSwitchDesk;
|
||||
QMenu* m_pMenuContent;
|
||||
QAction* m_pMenuExplore;
|
||||
QAction* m_pMenuBrowse;
|
||||
|
|
|
@ -32,6 +32,8 @@ int main(int argc, char *argv[])
|
|||
// use a shared setting location when used in a business environment for easier administration
|
||||
theConf = new CSettings(ConfDir, "Sandboxie-Plus");
|
||||
|
||||
QString AppID = "SandMan";
|
||||
|
||||
#ifndef _DEBUG
|
||||
InitMiniDumpWriter(QString("SandMan-v%1").arg(CSandMan::GetVersion()).toStdWString().c_str() , QString(theConf->GetConfigDir()).replace("/", "\\").toStdWString().c_str());
|
||||
#endif
|
||||
|
@ -60,8 +62,37 @@ int main(int argc, char *argv[])
|
|||
QApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
|
||||
#endif
|
||||
|
||||
QtSingleApplication app(argc, argv);
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
QString BoxDesktop;
|
||||
QString CurDesk = CSbieAPI::GetCurrentDesktopName();
|
||||
QStringList CurDeskNames = CurDesk.split("_");
|
||||
if (CurDeskNames.length() >= 3 && CurDeskNames[0] == "Sandboxie" && CurDeskNames[2] == "Session")
|
||||
BoxDesktop = CurDeskNames[1];
|
||||
|
||||
if (!BoxDesktop.isEmpty())
|
||||
{
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (stricmp(argv[i], "-autorun") != 0)
|
||||
continue;
|
||||
|
||||
WCHAR cmdline[MAX_PATH];
|
||||
GetSystemWindowsDirectoryW(cmdline, MAX_PATH);
|
||||
wcscat_s(cmdline, MAX_PATH, L"\\Explorer.exe");
|
||||
QStringList StartArgs;
|
||||
StartArgs << "/Box:" + BoxDesktop;
|
||||
StartArgs << "/fcp";
|
||||
StartArgs << QString::fromWCharArray(cmdline);
|
||||
QProcess::startDetached(AppDir + "\\start.exe", StartArgs);
|
||||
|
||||
CSandMan::Restart();
|
||||
return 0;
|
||||
}
|
||||
|
||||
AppID.append("_" + BoxDesktop);
|
||||
}
|
||||
|
||||
QtSingleApplication* pApp = new QtSingleApplication(AppID, argc, argv);
|
||||
pApp->setQuitOnLastWindowClosed(false);
|
||||
|
||||
//InitConsole(false);
|
||||
|
||||
|
@ -165,30 +196,34 @@ int main(int argc, char *argv[])
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool bAutoRun = pApp->arguments().contains("-autorun");
|
||||
|
||||
if (!g_PendingMessage.isEmpty()) {
|
||||
if(app.sendMessage(g_PendingMessage))
|
||||
if(pApp->sendMessage(g_PendingMessage))
|
||||
return 0;
|
||||
app.disableSingleApp(); // we start to do one job and exit, don't interfere with starting a regular instance
|
||||
pApp->disableSingleApp(); // we start to do one job and exit, don't interfere with starting a regular instance
|
||||
}
|
||||
else {
|
||||
if (app.arguments().contains("-autorun") && app.isRunning())
|
||||
if (bAutoRun && pApp->isRunning())
|
||||
return 0;
|
||||
if (app.sendMessage("ShowWnd"))
|
||||
if (pApp->sendMessage("ShowWnd"))
|
||||
return 0;
|
||||
}
|
||||
|
||||
//QThreadPool::globalInstance()->setMaxThreadCount(theConf->GetInt("Options/MaxThreadPool", 10));
|
||||
|
||||
CSandMan* pWnd = new CSandMan();
|
||||
CSandMan* pWnd = new CSandMan(BoxDesktop, bAutoRun);
|
||||
|
||||
QObject::connect(&app, SIGNAL(messageReceived(const QString&)), pWnd, SLOT(OnMessage(const QString&)), Qt::QueuedConnection);
|
||||
QObject::connect(pApp, SIGNAL(messageReceived(const QString&)), pWnd, SLOT(OnMessage(const QString&)), Qt::QueuedConnection);
|
||||
|
||||
int ret = app.exec();
|
||||
int ret = pApp->exec();
|
||||
|
||||
delete pWnd;
|
||||
|
||||
delete theConf;
|
||||
theConf = NULL;
|
||||
|
||||
delete pApp;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#define VERSION_MJR 1
|
||||
#define VERSION_MIN 14
|
||||
#define VERSION_MIN 15
|
||||
#define VERSION_REV 0
|
||||
#define VERSION_UPD 0
|
||||
|
||||
|
|
Loading…
Reference in New Issue