commit
be74d08923
96
CHANGELOG.md
96
CHANGELOG.md
|
@ -4,20 +4,85 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
|
||||
|
||||
## [0.5.5 / 5.46.4] - 2021-01-17
|
||||
|
||||
### Added
|
||||
- added "SandboxService=..." to force selected services to be started in the sandbox
|
||||
- added template cleanup functionality to plus UI
|
||||
- allow internet prompt now also allow internet access pemanently
|
||||
- added browse button for box root folder in the SandMan UI
|
||||
- added explorer info message
|
||||
- added option to keep the sandman UI always on top
|
||||
- added drag and drop file on to sandman exe to open/run it sandboxed
|
||||
- added start SandMan UI when a sandboxed application starts
|
||||
- recovery window can now list all files
|
||||
- added file cunter to recovery window
|
||||
- when "NoAddProcessToJob=y" is specified chrome and alike now can fully use the job system
|
||||
-- Note: "NoAddProcessToJob=y" reduces the box isolation, but the affected functions are mostly covered by UIPI anyways
|
||||
- added obtimized default column widths to tha sbie view
|
||||
|
||||
### Changed
|
||||
- updated templates (thanks isaak654)
|
||||
- when trying to take a snapshot of an empty sandbox a proper error message is displayed
|
||||
- new layout for the recovery window
|
||||
- sbie view sorting is now case insensitive
|
||||
|
||||
### Fixed
|
||||
- fixed issue child window closing terminating application when main was hidden
|
||||
- fixed issues with non modal windows
|
||||
- fixed issues connecting in portable mode to driver
|
||||
- fixed minor issues with snapshot window
|
||||
- fixed missing error message when atempting to create an aleady existing sandbox
|
||||
- fixed issue allowing to save setting when a sandbox was alrady deleted
|
||||
- fixed issues with disabled items in dark mode
|
||||
- fixed some dialogs not closing on esc
|
||||
- fixed tab stops on many windows
|
||||
|
||||
|
||||
|
||||
## [0.5.4d / 5.46.3] - 2021-01-11
|
||||
|
||||
### Changed
|
||||
- improved access tracing, removed redundant entries
|
||||
- OpenIpcPath=\BaseNamedObjects\[CoreUI]-* is now hardcoded in the driver no need for the template entry
|
||||
- WindowsFontCache is now open by default
|
||||
- refactored some IPC code in the driver
|
||||
|
||||
### Fixed
|
||||
- fixed issue allowing to bypass the registry isolation, present since Windows 10 Creators Update
|
||||
- fixed creation time not always being properly updated in the SandMan UI
|
||||
|
||||
|
||||
|
||||
## [0.5.4c / 5.46.2] - 2021-01-10
|
||||
|
||||
### Added
|
||||
- added "CallTrace=*" to log all system calls to the access log
|
||||
|
||||
### Changed
|
||||
- improved IPC logging code
|
||||
- improved MSG_2101 logging
|
||||
|
||||
### Fixed
|
||||
- fixed more issues with IPC tracing
|
||||
- fixed SBIE2101 issue with Chrome and derivatives
|
||||
|
||||
|
||||
|
||||
## [0.5.4b / 5.46.1] - 2021-01-08
|
||||
|
||||
### Added
|
||||
- added "RunServiceAsSystem=..." allows specific named services to be ran as system
|
||||
- added "RunServiceAsSystem=..." allows specific named services to be run as system
|
||||
|
||||
### Changed
|
||||
- refactored some code around SCM access
|
||||
|
||||
### Fixed
|
||||
- fixed a crash issue in SbieSvc.exe introduced with the last build
|
||||
- fixed issue with sandman ui update check
|
||||
- fixed issue with SandMan UI update check
|
||||
|
||||
### Removed
|
||||
- removed "ProtectRpcSs=y" due to incompatybility with new isolation defaults
|
||||
- removed "ProtectRpcSs=y" due to incompatibility with new isolation defaults
|
||||
|
||||
|
||||
|
||||
|
@ -81,13 +146,13 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
### Added
|
||||
- added prompt to choose if links in the SandMan UI should be opened in a sandboxed or unsandboxed browser
|
||||
- added more recovery options
|
||||
- added "ClosedClsid=" to block com objects from being used when they cause compatibility issues
|
||||
- added "ClosedClsid=" to block COM objects from being used when they cause compatibility issues
|
||||
- added "ClsidTrace=*" option to trace COM usage
|
||||
- added "ClosedRT=" option to block access to problematic Windows RT interfaces
|
||||
- added option to make a link for any selected process to SandMan UI
|
||||
- added option to reset all hidden messages
|
||||
- added more process presets "force program" and "allow internet access"
|
||||
- added "SpecialImage=chrome,some_electron_app.exe" option to sandboxie.ini, valid image types "chrome", "firefox"
|
||||
- added "SpecialImage=chrome,some_electron_app.exe" option to Sandboxie.ini, valid image types "chrome", "firefox"
|
||||
-- with this option you can enable special hardcoded workarounds to new obscure forks of those browsers
|
||||
- added German translation (thanks bastik-1001) to the SandMan UI
|
||||
- added Russian translation (thanks lufog) to the SandMan UI
|
||||
|
@ -109,7 +174,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- fixed missing template setup when creating new boxes
|
||||
|
||||
### removed
|
||||
- removed obsolete "OpenDefaultClsid=n" use "ClosedClsid=" with the apropriate values instead
|
||||
- removed obsolete "OpenDefaultClsid=n" use "ClosedClsid=" with the appropriate values instead
|
||||
- removed suspend/resume menu entry, pooling that state wastes substantial CPU cycles; use task explorer for that functionality
|
||||
|
||||
|
||||
|
@ -126,9 +191,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
## [0.5.2 / 5.45.1] - 2020-12-23
|
||||
|
||||
### Added
|
||||
- added advanced new box creation dialog to SandMan UI
|
||||
- added advanced new box creation dialogue to SandMan UI
|
||||
- added show/hide tray context menu entry
|
||||
- added refresh button to file recovery dialog
|
||||
- added refresh button to file recovery dialogue
|
||||
- added mechanism to load icons from {install-dir}/Icons/{icon}.png for UI customization
|
||||
- added tray indicator to show disabled forced program status in the SandMan UI
|
||||
- added program name suggestions to box options in SandMan UI
|
||||
|
@ -138,7 +203,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- reorganized the advanced box options a bit
|
||||
- changed icons (thanks Valinwolf for picking the new ones)
|
||||
- updated Template.ini (thanks isaak654)
|
||||
- increates max value for disable forced process time in SandMan UI
|
||||
- increased max value for disable forced process time in SandMan UI
|
||||
|
||||
### Fixed
|
||||
- fixed BSOD introduced in 5.45.0 when using Windows 10 "core isolation"
|
||||
|
@ -173,8 +238,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- updated SandMan UI to use Qt5.15.1
|
||||
|
||||
### Fixed
|
||||
- fixed crash issue with progress dialog
|
||||
- fixed progress dialog cancel button not working for update checker
|
||||
- fixed crash issue with progress dialogue
|
||||
- fixed progress dialogue cancel button not working for update checker
|
||||
- fixed issue around NtQueryDirectoryFile when deleting sandbox content
|
||||
- fixed dark theme in the notification window
|
||||
- fixed issue with disable force programs tray menu
|
||||
|
@ -323,7 +388,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
-- it caused issues with unity games, will be investigated and re enabled later
|
||||
|
||||
### Fixed
|
||||
- fixed color issue with vertical tabs in dark mode
|
||||
- fixed colour issue with vertical tabs in dark mode
|
||||
- fixed wrong path separators when adding new forced folders
|
||||
- fixed directory listing bug introduced in 5.43
|
||||
- fixed issues with settings window when not being connected to driver
|
||||
|
@ -357,7 +422,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- fixed issues with the new box settings editor
|
||||
|
||||
### Removed
|
||||
- removes deprecated workaround in the hooking mechanism for an obsolete antimalware product
|
||||
- removes deprecated workaround in the hooking mechanism for an obsolete anti-malware product
|
||||
|
||||
|
||||
|
||||
|
@ -412,7 +477,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Sandbox names now replace "_" with " " for display allowing to use names that are made of separated words
|
||||
|
||||
### Fixed
|
||||
- added mising PreferExternalManifest itialization to portable mode
|
||||
- added missing PreferExternalManifest initialization to portable mode
|
||||
- fixed permission issues with sandboxed system processes
|
||||
-- Note: you can use "ExposeBoxedSystem=y" for the old behaviour (debug option)
|
||||
- fixed missing SCM access check for sandboxed services
|
||||
|
@ -452,7 +517,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
-- Note: using these options weakens the sandboxing, they are intended for debugging and may be used for better application virtualization later
|
||||
|
||||
### Changed
|
||||
- SbieDll.dll when processing InjectDll now looks in the SbieHome folder for the Dll's if the entered path starts with a backslash
|
||||
- SbieDll.dll when processing InjectDll now looks in the SbieHome folder for the DLLs if the entered path starts with a backslash
|
||||
-- i.e. "InjectDll=\LogAPI\i386\logapi32v.dll" or "InjectDll64=\LogAPI\amd64\logapi64v.dll"
|
||||
|
||||
### Fixed
|
||||
|
@ -502,4 +567,3 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
### Fixed
|
||||
- fixed "Windows Installer Service could not be accessed" that got introduced with Windows 1903
|
||||
|
||||
|
|
|
@ -1557,6 +1557,5 @@ void CAppPage::SetDefaultTemplates6(CBox &box)
|
|||
void CAppPage::SetDefaultTemplates7(CBox &box)
|
||||
{
|
||||
box.EnableTemplate(L"BlockPorts", TRUE);
|
||||
box.EnableTemplate(L"WindowsFontCache", TRUE);
|
||||
box.EnableTemplate(L"qWave", TRUE);
|
||||
}
|
||||
|
|
|
@ -97,13 +97,15 @@ BOOL CMonitorDialog::OnInitDialog()
|
|||
void CMonitorDialog::OnIdle()
|
||||
{
|
||||
static const WCHAR *_Unknown = L"(Unk) ";
|
||||
static const WCHAR *_SysCall = L"SysCall ";
|
||||
static const WCHAR *_Pipe = L"Pipe ";
|
||||
static const WCHAR *_Ipc = L"Ipc ";
|
||||
static const WCHAR *_WinClass = L"WinCls ";
|
||||
static const WCHAR *_Drive = L"(Drive) ";
|
||||
static const WCHAR *_Clsid = L"Clsid ";
|
||||
static const WCHAR *_Image = L"Image ";
|
||||
static const WCHAR *_FileOrKey = L"File/Key ";
|
||||
static const WCHAR *_File = L"File ";
|
||||
static const WCHAR *_Key = L"Key ";
|
||||
static const WCHAR *_Other = L"Other ";
|
||||
static const WCHAR *_Separator = L" -------------------------------";
|
||||
|
||||
|
@ -146,7 +148,9 @@ void CMonitorDialog::OnIdle()
|
|||
type &= 0x0FFF;
|
||||
|
||||
const WCHAR *PrefixPtr = _Unknown;
|
||||
if (type == MONITOR_PIPE)
|
||||
if (type == MONITOR_SYSCALL)
|
||||
PrefixPtr = _SysCall;
|
||||
else if (type == MONITOR_PIPE)
|
||||
PrefixPtr = _Pipe;
|
||||
else if (type == MONITOR_IPC)
|
||||
PrefixPtr = _Ipc;
|
||||
|
@ -158,8 +162,10 @@ void CMonitorDialog::OnIdle()
|
|||
PrefixPtr = _Clsid;
|
||||
else if (type == MONITOR_IMAGE)
|
||||
PrefixPtr = _Image;
|
||||
else if (type == MONITOR_FILE_OR_KEY)
|
||||
PrefixPtr = _FileOrKey;
|
||||
else if (type == MONITOR_FILE)
|
||||
PrefixPtr = _File;
|
||||
else if (type == MONITOR_KEY)
|
||||
PrefixPtr = _Key;
|
||||
else if (type == MONITOR_OTHER)
|
||||
PrefixPtr = _Other;
|
||||
wcsncpy(name, PrefixPtr, 9);
|
||||
|
@ -189,7 +195,11 @@ void CMonitorDialog::OnIdle()
|
|||
wcscat(name, _Separator);
|
||||
listbox->AddString(name);
|
||||
|
||||
wcscpy(name, _FileOrKey);
|
||||
wcscpy(name, _File);
|
||||
wcscat(name, _Separator);
|
||||
listbox->AddString(name);
|
||||
|
||||
wcscpy(name, _Key);
|
||||
wcscat(name, _Separator);
|
||||
listbox->AddString(name);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ BOOL CShellDialog::OnInitDialog()
|
|||
|
||||
CUserSettings &user = CUserSettings::GetInstance();
|
||||
user.GetBool(_EnableLogonStart, logonstart, TRUE);
|
||||
user.GetBool(_EnableAutoStart, autostart, FALSE);
|
||||
user.GetBool(_EnableAutoStart, autostart, TRUE);
|
||||
user.GetBool(_AddDesktopIcon, desktop, TRUE);
|
||||
user.GetBool(_AddQuickLaunchIcon, quicklaunch, TRUE);
|
||||
user.GetBool(_AddContextMenu, contextmenu, TRUE);
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#ifndef _MY_VERSION_H
|
||||
#define _MY_VERSION_H
|
||||
|
||||
#define MY_VERSION_BINARY 5,46,1
|
||||
#define MY_VERSION_STRING "5.46.1"
|
||||
#define MY_VERSION_BINARY 5,46,4
|
||||
#define MY_VERSION_STRING "5.46.4"
|
||||
#define MY_VERSION_COMPAT "5.46.0" // this refers to the driver ABI compatibility
|
||||
|
||||
// These #defines are used by either Resource Compiler, or by NSIC installer
|
||||
|
|
|
@ -154,6 +154,10 @@ static void Com_Trace(
|
|||
const WCHAR *TraceType, REFCLSID rclsid, REFIID riid,
|
||||
ULONG ProcNum, HRESULT hr);
|
||||
|
||||
static void Com_Trace2(
|
||||
const WCHAR* TraceType, REFCLSID rclsid, REFIID riid,
|
||||
ULONG ProcNum, HRESULT hr, USHORT monflag);
|
||||
|
||||
static void Com_Monitor(REFCLSID rclsid, USHORT monflag);
|
||||
|
||||
#define HSTRING void*
|
||||
|
@ -596,8 +600,8 @@ _FX HRESULT Com_CoGetClassObject(
|
|||
}
|
||||
|
||||
if (clsctx & CLSCTX_LOCAL_SERVER) {
|
||||
Com_Trace(TraceType, rclsid, riid, 0, hr);
|
||||
Com_Monitor(rclsid, monflag);
|
||||
Com_Trace2(TraceType, rclsid, riid, 0, hr, monflag);
|
||||
if(!Com_TraceFlag) Com_Monitor(rclsid, monflag);
|
||||
}
|
||||
|
||||
return hr;
|
||||
|
@ -642,8 +646,8 @@ _FX HRESULT Com_CoGetObject(
|
|||
else
|
||||
monflag |= MONITOR_DENY;
|
||||
|
||||
Com_Trace(TraceType, &clsid, riid, 0, hr);
|
||||
Com_Monitor(&clsid, monflag);
|
||||
Com_Trace2(TraceType, &clsid, riid, 0, hr, monflag);
|
||||
if (!Com_TraceFlag) Com_Monitor(&clsid, monflag);
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -696,8 +700,8 @@ _FX HRESULT Com_CoCreateInstance(
|
|||
}
|
||||
|
||||
if (clsctx & CLSCTX_LOCAL_SERVER) {
|
||||
Com_Trace(TraceType, rclsid, riid, 0, hr);
|
||||
Com_Monitor(rclsid, monflag);
|
||||
Com_Trace2(TraceType, rclsid, riid, 0, hr, monflag);
|
||||
if (!Com_TraceFlag) Com_Monitor(rclsid, monflag);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -808,8 +812,8 @@ _FX HRESULT Com_CoCreateInstanceEx(
|
|||
|
||||
for (i = 0; i < cmq; ++i) {
|
||||
MULTI_QI *mqi = &pmqs[i];
|
||||
Com_Trace(TraceType, rclsid, mqi->pIID, 0, mqi->hr);
|
||||
Com_Monitor(rclsid, monflag);
|
||||
Com_Trace2(TraceType, rclsid, mqi->pIID, 0, mqi->hr, monflag);
|
||||
if (!Com_TraceFlag) Com_Monitor(rclsid, monflag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3304,8 +3308,15 @@ _FX void Com_Trace_Guid(
|
|||
|
||||
|
||||
_FX void Com_Trace(
|
||||
const WCHAR *TraceType, REFCLSID rclsid, REFIID riid,
|
||||
const WCHAR* TraceType, REFCLSID rclsid, REFIID riid,
|
||||
ULONG ProcNum, HRESULT hr)
|
||||
{
|
||||
Com_Trace2(TraceType, rclsid, riid, ProcNum, hr, MONITOR_TRACE);
|
||||
}
|
||||
|
||||
_FX void Com_Trace2(
|
||||
const WCHAR* TraceType, REFCLSID rclsid, REFIID riid,
|
||||
ULONG ProcNum, HRESULT hr, USHORT monflag)
|
||||
{
|
||||
WCHAR *text;
|
||||
WCHAR *ptr;
|
||||
|
@ -3314,7 +3325,7 @@ _FX void Com_Trace(
|
|||
return;
|
||||
|
||||
text = Com_Alloc(1024 * sizeof(WCHAR));
|
||||
ptr = text + Sbie_snwprintf(text, 1024, L"SBIE %s <%08X> ", TraceType, hr);
|
||||
ptr = text + Sbie_snwprintf(text, 1024, L"COM %s <%08X> ", TraceType, hr);
|
||||
|
||||
if (rclsid) {
|
||||
Com_Trace_Guid(ptr, rclsid, L"CLSID");
|
||||
|
@ -3341,7 +3352,7 @@ _FX void Com_Trace(
|
|||
//ptr[1] = L'\0';
|
||||
//OutputDebugString(text);
|
||||
*ptr = L'\0';
|
||||
SbieApi_MonitorPut(MONITOR_COMCLASS | MONITOR_TRACE, text);
|
||||
SbieApi_MonitorPut(MONITOR_COMCLASS | monflag, text);
|
||||
|
||||
Com_Free(text);
|
||||
}
|
||||
|
|
|
@ -1557,4 +1557,28 @@ BOOLEAN SbieDll_MatchImage(const WCHAR* pat_str, const WCHAR* test_str, const WC
|
|||
{
|
||||
ULONG pat_len = wcslen(pat_str);
|
||||
return SbieDll_MatchImage_Impl(pat_str, pat_len, test_str, BoxName, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// CheckStringInList
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
BOOLEAN SbieDll_CheckStringInList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting)
|
||||
{
|
||||
WCHAR buf[66];
|
||||
ULONG index = 0;
|
||||
while (1) {
|
||||
NTSTATUS status = SbieApi_QueryConfAsIs(boxname, setting, index, buf, 64 * sizeof(WCHAR));
|
||||
++index;
|
||||
if (NT_SUCCESS(status)) {
|
||||
if (_wcsicmp(buf, string) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (status != STATUS_BUFFER_TOO_SMALL)
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -976,8 +976,11 @@ _FX BOOL Proc_UpdateProcThreadAttribute(
|
|||
// when the PROC_THREAD_ATTRIBUTE_JOB_LIST is set the call CreateProcessAsUserW -> CreateProcessInternalW -> NtCreateProcess
|
||||
// fals with an access denided error, so we need to block this attribute form being set
|
||||
// if(Dll_ImageType == DLL_IMAGE_GOOGLE_CHROME)
|
||||
if (Attribute == 0x0002000d) //PROC_THREAD_ATTRIBUTE_JOB_LIST
|
||||
return TRUE;
|
||||
if (Attribute == 0x0002000d) //PROC_THREAD_ATTRIBUTE_JOB_LIST
|
||||
{
|
||||
if (!SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// some mitigation flags break SbieDll.dll Injection, so we disable them
|
||||
if (Attribute == 0x00020007) //PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY
|
||||
|
@ -1380,11 +1383,13 @@ _FX BOOL Proc_AlternateCreateProcess(
|
|||
void *lpCurrentDirectory, LPPROCESS_INFORMATION lpProcessInformation,
|
||||
BOOL *ReturnValue)
|
||||
{
|
||||
if (SbieApi_QueryConfBool(NULL, L"BlockSoftwareUpdaters", TRUE))
|
||||
if (Proc_IsSoftwareUpdateW(lpApplicationName)) {
|
||||
|
||||
SetLastError(ERROR_ACCESS_DENIED);
|
||||
*ReturnValue = FALSE;
|
||||
|
||||
SbieApi_MonitorPut(MONITOR_OTHER, L"Blocked start of an updater");
|
||||
return TRUE; // exit CreateProcessInternal
|
||||
}
|
||||
|
||||
|
@ -1407,11 +1412,14 @@ _FX BOOL Proc_AlternateCreateProcess(
|
|||
// don't start Kaspersky Anti Virus klwtblfs.exe component
|
||||
// because Kaspersky protects the process and we can't put
|
||||
// it into a job or inject SbieLow and so on
|
||||
SbieApi_MonitorPut(MONITOR_OTHER, L"Blocked start of klwtblfs.exe");
|
||||
return TRUE; // exit CreateProcessInternal
|
||||
}
|
||||
if (Dll_ImageType == DLL_IMAGE_SANDBOXIE_DCOMLAUNCH && lpCommandLine
|
||||
&& wcsstr(lpCommandLine, L"smartscreen.exe")) {
|
||||
return TRUE; // exit CreateProcessInternal
|
||||
|
||||
SbieApi_MonitorPut(MONITOR_OTHER, L"Blocked start of smartscreen.exe");
|
||||
return TRUE; // exit CreateProcessInternal
|
||||
}
|
||||
return FALSE; // continue with CreateProcessInternal
|
||||
}
|
||||
|
|
|
@ -269,6 +269,19 @@ WCHAR* GetDynamicLpcPortName(ENUM_DYNAMIC_PORT_TYPE portType)
|
|||
|
||||
rpl = (EPMAPPER_GET_PORT_NAME_RPL*)SbieDll_CallServer(&req.h);
|
||||
|
||||
WCHAR wsTraceOptions[4];
|
||||
if (SbieApi_QueryConf(NULL, L"IpcTrace", 0, wsTraceOptions, sizeof(wsTraceOptions)) == STATUS_SUCCESS && wsTraceOptions[0] != L'\0')
|
||||
{
|
||||
WCHAR text[130];
|
||||
|
||||
if (rpl && NT_SUCCESS(rpl->h.status))
|
||||
Sbie_snwprintf(text, 130, L"Resolved dynamic port: %d; endpoint: %s", req.portType, rpl->wszPortName);
|
||||
else
|
||||
Sbie_snwprintf(text, 130, L"Failed to resolve dynamic port: %d; status: %08X", req.portType, rpl ? rpl->h.status : 0);
|
||||
|
||||
SbieApi_MonitorPut2(MONITOR_IPC | MONITOR_TRACE, text, FALSE);
|
||||
}
|
||||
|
||||
if (rpl && NT_SUCCESS(rpl->h.status))
|
||||
{
|
||||
wcsncpy(g_Ipc_DynamicPortNames[portType], rpl->wszPortName, DYNAMIC_PORT_NAME_CHARS);
|
||||
|
@ -377,15 +390,16 @@ _FX ULONG RpcRt_RpcBindingFromStringBindingW(
|
|||
status = __sys_RpcBindingFromStringBindingW(StringBinding, OutBinding);
|
||||
// If there are any IpcTrace options set, then output this debug string
|
||||
WCHAR wsTraceOptions[4];
|
||||
if (SbieApi_QueryConf(NULL, L"IpcTrace", 0, wsTraceOptions, sizeof(wsTraceOptions)) == STATUS_SUCCESS && wsTraceOptions != L'\0')
|
||||
if (SbieApi_QueryConf(NULL, L"IpcTrace", 0, wsTraceOptions, sizeof(wsTraceOptions)) == STATUS_SUCCESS && wsTraceOptions[0] != L'\0')
|
||||
{
|
||||
WCHAR msg[512];
|
||||
Sbie_snwprintf(msg, 512, L"SBIE p=%06d t=%06d RpcBindingFromStringBindingW StringBinding = '%s', BindingHandle = 0x%X, status = 0x%X\n", GetCurrentProcessId(), GetCurrentThreadId(),
|
||||
StringBinding,
|
||||
OutBinding,
|
||||
status);
|
||||
|
||||
//Sbie_snwprintf(msg, 512, L"SBIE p=%06d t=%06d RpcBindingFromStringBindingW StringBinding = '%s', BindingHandle = 0x%X, status = 0x%X\n", GetCurrentProcessId(), GetCurrentThreadId(),
|
||||
Sbie_snwprintf(msg, 512, L"StringBinding = '%s', BindingHandle = 0x%X, status = 0x%08X",
|
||||
StringBinding, OutBinding, status);
|
||||
|
||||
//OutputDebugString(msg);
|
||||
SbieApi_MonitorPut(MONITOR_IPC | MONITOR_TRACE, msg);
|
||||
SbieApi_MonitorPut2(MONITOR_IPC | MONITOR_TRACE, msg, FALSE);
|
||||
}
|
||||
__sys_RpcMgmtSetComTimeout(*OutBinding, RPC_C_BINDING_TIMEOUT);
|
||||
return status;
|
||||
|
@ -442,14 +456,14 @@ _FX RPC_STATUS RpcRt_RpcBindingCreateW(
|
|||
RPC_CSTR StringUuid;
|
||||
|
||||
__sys_UuidToStringW(&Template->ObjectUuid, &StringUuid);
|
||||
Sbie_snwprintf(msg, 512, L"SBIE p=%06d t=%06d RpcBindingCreateW Endpoint = '%s', UUID = %s, status = 0x%X\n", GetCurrentProcessId(), GetCurrentThreadId(),
|
||||
//Sbie_snwprintf(msg, 512, L"SBIE p=%06d t=%06d RpcBindingCreateW Endpoint = '%s', UUID = %s, status = 0x%X\n", GetCurrentProcessId(), GetCurrentThreadId(),
|
||||
Sbie_snwprintf(msg, 512, L"Endpoint = '%s', UUID = %s, status = 0x%08X",
|
||||
Template && Template->StringEndpoint ? Template->StringEndpoint : L"null",
|
||||
StringUuid,
|
||||
status);
|
||||
StringUuid, status);
|
||||
__sys_RpcStringFreeW(&StringUuid);
|
||||
|
||||
//OutputDebugString(msg);
|
||||
SbieApi_MonitorPut(MONITOR_IPC | MONITOR_TRACE, msg);
|
||||
SbieApi_MonitorPut2(MONITOR_IPC | MONITOR_TRACE, msg, FALSE);
|
||||
}
|
||||
__sys_RpcMgmtSetComTimeout(*Binding, RPC_C_BINDING_TIMEOUT);
|
||||
return status;
|
||||
|
|
|
@ -202,6 +202,9 @@ SBIEDLL_EXPORT ULONG SbieDll_InjectLow(HANDLE hProcess, BOOLEAN is_wow64, BOOLE
|
|||
|
||||
SBIEDLL_EXPORT BOOLEAN SbieDll_MatchImage(const WCHAR* pat_str, const WCHAR* test_str, const WCHAR* BoxName);
|
||||
|
||||
SBIEDLL_EXPORT BOOLEAN SbieDll_CheckStringInList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -888,6 +888,9 @@ _FX BOOLEAN Scm_IsBoxedService(const WCHAR *ServiceName)
|
|||
|
||||
Dll_Free(names);
|
||||
|
||||
if (SbieDll_CheckStringInList(ServiceName, NULL, L"SandboxService"))
|
||||
found = TRUE;
|
||||
|
||||
/*
|
||||
if (_wcsicmp(ServiceName, _eventsystem) == 0) {
|
||||
//
|
||||
|
|
|
@ -122,9 +122,13 @@ _FX BOOLEAN SysInfo_Init(void)
|
|||
SBIEDLL_HOOK(SysInfo_,NtQuerySystemInformation);
|
||||
}
|
||||
|
||||
SBIEDLL_HOOK(SysInfo_,NtCreateJobObject);
|
||||
SBIEDLL_HOOK(SysInfo_,NtAssignProcessToJobObject);
|
||||
SBIEDLL_HOOK(SysInfo_,NtSetInformationJobObject);
|
||||
SBIEDLL_HOOK(SysInfo_, NtCreateJobObject);
|
||||
if (!SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE))
|
||||
{
|
||||
SBIEDLL_HOOK(SysInfo_, NtAssignProcessToJobObject);
|
||||
SBIEDLL_HOOK(SysInfo_, NtSetInformationJobObject);
|
||||
}
|
||||
|
||||
|
||||
SBIEDLL_HOOK(SysInfo_,SetLocaleInfoW);
|
||||
SBIEDLL_HOOK(SysInfo_,SetLocaleInfoA);
|
||||
|
@ -392,7 +396,8 @@ _FX NTSTATUS SysInfo_NtCreateJobObject(
|
|||
// job object, and to not request some specific rights
|
||||
//
|
||||
|
||||
DesiredAccess &= ~(JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_TERMINATE);
|
||||
if (!SbieApi_QueryConfBool(NULL, L"NoAddProcessToJob", FALSE))
|
||||
DesiredAccess &= ~(JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_TERMINATE);
|
||||
|
||||
jobname_len = Dll_BoxIpcPathLen + wcslen(Dll_ImageName) + 64;
|
||||
jobname = Dll_AllocTemp(jobname_len * sizeof(WCHAR));
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define DUPLICATE_INHERIT 0x00040000
|
||||
#define DUPLICATE_INTO_OTHER 0x00080000 // otherwise DUP_FROM_OTHER
|
||||
|
||||
|
||||
#define MONITOR_SYSCALL 0x000B
|
||||
#define MONITOR_PIPE 0x011B
|
||||
#define MONITOR_IPC 0x022B
|
||||
#define MONITOR_WINCLASS 0x033B
|
||||
|
@ -49,10 +49,17 @@
|
|||
#define MONITOR_COMCLASS 0x055B
|
||||
#define MONITOR_IGNORE 0x066B
|
||||
#define MONITOR_IMAGE 0x077B
|
||||
#define MONITOR_FILE_OR_KEY 0x088B
|
||||
#define MONITOR_OTHER 0x099B
|
||||
#define MONITOR_FILE 0x088B
|
||||
#define MONITOR_KEY 0x099B
|
||||
#define MONITOR_OTHER 0x0AAB
|
||||
//#define MONITOR_ 0x0BBB
|
||||
//#define MONITOR_ 0x0CCB
|
||||
//#define MONITOR_ 0x0DDB
|
||||
//#define MONITOR_ 0x0EEB
|
||||
//#define MONITOR_ 0x0FFB
|
||||
#define MONITOR_OPEN 0x1000
|
||||
#define MONITOR_DENY 0x2000
|
||||
//#define MONITOR_ 0x4000
|
||||
#define MONITOR_TRACE 0x8000
|
||||
|
||||
|
||||
|
|
|
@ -994,7 +994,7 @@ _FX NTSTATUS File_Generic_MyParseProc(
|
|||
if (proc->file_trace & TRACE_IGNORE)
|
||||
Log_Debug_Msg(MONITOR_IGNORE, ignore_str, Driver_Empty);
|
||||
|
||||
if (Session_MonitorCount &&
|
||||
else if (Session_MonitorCount &&
|
||||
device_type != FILE_DEVICE_PHYSICAL_NETCARD)
|
||||
Session_MonitorPut(MONITOR_IGNORE, ignore_str + 4, proc->pid);
|
||||
|
||||
|
@ -1492,14 +1492,25 @@ skip_due_to_home_folder:
|
|||
letter = 0;
|
||||
|
||||
if (letter) {
|
||||
|
||||
USHORT mon_type = IsPipeDevice ? MONITOR_PIPE : MONITOR_FILE;
|
||||
if (!IsBoxedPath) {
|
||||
if (ShouldMonitorAccess == TRUE)
|
||||
mon_type |= MONITOR_DENY;
|
||||
else
|
||||
mon_type |= MONITOR_OPEN;
|
||||
}
|
||||
if(!IsPipeDevice && !ShouldMonitorAccess)
|
||||
mon_type |= MONITOR_TRACE;
|
||||
|
||||
swprintf(access_str, L"(F%c) %08X.%02X.%08X",
|
||||
letter, DesiredAccess,
|
||||
CreateDisposition & 0x0F, CreateOptions);
|
||||
Log_Debug_Msg(IsPipeDevice ? MONITOR_PIPE : MONITOR_FILE_OR_KEY, access_str, Name->Name.Buffer);
|
||||
Log_Debug_Msg(mon_type, access_str, Name->Name.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsPipeDevice && Session_MonitorCount) {
|
||||
else if (IsPipeDevice && Session_MonitorCount) {
|
||||
|
||||
USHORT mon_type = MONITOR_PIPE;
|
||||
WCHAR *mon_name = Name->Name.Buffer;
|
||||
|
@ -1515,9 +1526,12 @@ skip_due_to_home_folder:
|
|||
|
||||
} else if (ShouldMonitorAccess) {
|
||||
|
||||
Session_MonitorPut(MONITOR_FILE_OR_KEY | MONITOR_DENY, Name->Name.Buffer, proc->pid);
|
||||
Session_MonitorPut(MONITOR_FILE | MONITOR_DENY, Name->Name.Buffer, proc->pid);
|
||||
|
||||
} else if (msg1313 && status == STATUS_ACCESS_DENIED
|
||||
}
|
||||
|
||||
if (!ShouldMonitorAccess && msg1313
|
||||
&& status == STATUS_ACCESS_DENIED
|
||||
&& device_type == FILE_DEVICE_DISK
|
||||
&& RemainingName && RemainingName->Length == 0) {
|
||||
|
||||
|
|
|
@ -1442,7 +1442,7 @@ _FX ULONG_PTR Gui_NtUserSendInput(
|
|||
if (letter) {
|
||||
|
||||
swprintf(access_str, L"(G%c) SendInput", letter);
|
||||
Log_Debug_Msg(MONITOR_WINCLASS, access_str, Driver_Empty);
|
||||
Log_Debug_Msg(MONITOR_WINCLASS | MONITOR_TRACE, access_str, Driver_Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1538,7 +1538,7 @@ _FX ULONG_PTR Gui_NtUserSetWindowsHookEx(
|
|||
swprintf(access_str,
|
||||
L"(G%c) WinHook %04d on tid=%06d pid=%06d",
|
||||
letter, HookType, idThread, idProcess);
|
||||
Log_Debug_Msg(MONITOR_WINCLASS, access_str, Driver_Empty);
|
||||
Log_Debug_Msg(MONITOR_WINCLASS | MONITOR_TRACE, access_str, Driver_Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1595,7 +1595,7 @@ _FX ULONG_PTR Gui_NtUserSetWinEventHook(
|
|||
|
||||
swprintf(access_str, L"(G%c) AccHook on tid=%06d pid=%06d",
|
||||
letter, idThread, idProcess);
|
||||
Log_Debug_Msg(MONITOR_WINCLASS, access_str, Driver_Empty);
|
||||
Log_Debug_Msg(MONITOR_WINCLASS | MONITOR_TRACE, access_str, Driver_Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -210,14 +210,13 @@ _FX BOOLEAN Ipc_Init(void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// Note: those don't have a special treatment
|
||||
//if (Driver_OsVersion >= DRIVER_WINDOWS_10) {
|
||||
//
|
||||
// if(!Mem_GetLockResource(&Ipc_Dynamic_Ports[WPAD_PORT].pPortLock, TRUE)
|
||||
// || !Mem_GetLockResource(&Ipc_Dynamic_Ports[GAME_CONFIG_STORE_PORT].pPortLock, TRUE)
|
||||
// || !Mem_GetLockResource(&Ipc_Dynamic_Ports[SMART_CARD_PORT].pPortLock, TRUE)
|
||||
// ) return FALSE;
|
||||
//}
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_10) {
|
||||
|
||||
if(!Mem_GetLockResource(&Ipc_Dynamic_Ports[WPAD_PORT].pPortLock, TRUE)
|
||||
|| !Mem_GetLockResource(&Ipc_Dynamic_Ports[GAME_CONFIG_STORE_PORT].pPortLock, TRUE)
|
||||
|| !Mem_GetLockResource(&Ipc_Dynamic_Ports[SMART_CARD_PORT].pPortLock, TRUE)
|
||||
) return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// finish
|
||||
|
@ -521,6 +520,8 @@ _FX BOOLEAN Ipc_InitPaths(PROCESS *proc)
|
|||
L"\\RPC Control\\LSARPC_ENDPOINT",
|
||||
L"\\RPC Control\\umpo",
|
||||
L"*\\BaseNamedObjects*\\FlipEx*",
|
||||
L"*\\BaseNamedObjects*\\FontCachePort",
|
||||
L"*\\BaseNamedObjects*\\FntCache-*",
|
||||
NULL
|
||||
};
|
||||
static const WCHAR *openpaths_windows8[] = {
|
||||
|
@ -542,6 +543,7 @@ _FX BOOLEAN Ipc_InitPaths(PROCESS *proc)
|
|||
L"*\\BaseNamedObjects*\\CoreMessagingRegistrar",
|
||||
L"\\RPC Control\\webcache_*",
|
||||
L"*\\BaseNamedObjects\\windows_webcache_counters_*",
|
||||
L"*\\BaseNamedObjects\\[CoreUI]-*",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -872,34 +874,34 @@ _FX NTSTATUS Ipc_CheckGenericObject(
|
|||
status = STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
// Note: since version 5.46 these are open only per process
|
||||
//else if (!is_open && !is_closed)
|
||||
//{
|
||||
// int i;
|
||||
// for (i = 0; i < NUM_DYNAMIC_PORTS; i++)
|
||||
// {
|
||||
// if (Ipc_Dynamic_Ports[i].pPortLock)
|
||||
// {
|
||||
// KeEnterCriticalRegion();
|
||||
// ExAcquireResourceSharedLite(Ipc_Dynamic_Ports[i].pPortLock, TRUE);
|
||||
//
|
||||
// if (*Ipc_Dynamic_Ports[i].wstrPortName
|
||||
// && (Name->Length >= 32 * sizeof(WCHAR))
|
||||
// && _wcsicmp(Name->Buffer, Ipc_Dynamic_Ports[i].wstrPortName) == 0)
|
||||
// {
|
||||
// // dynamic version of RPC ports, see also ipc_spl.c
|
||||
// // and RpcBindingFromStringBindingW in core/dll/rpcrt.c
|
||||
// is_open = TRUE;
|
||||
// }
|
||||
//
|
||||
// ExReleaseResourceLite(Ipc_Dynamic_Ports[i].pPortLock);
|
||||
// KeLeaveCriticalRegion();
|
||||
//
|
||||
// if (is_open)
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
else if (!is_open && !is_closed)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NUM_DYNAMIC_PORTS; i++)
|
||||
{
|
||||
if (Ipc_Dynamic_Ports[i].pPortLock)
|
||||
{
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceSharedLite(Ipc_Dynamic_Ports[i].pPortLock, TRUE);
|
||||
|
||||
if (*Ipc_Dynamic_Ports[i].wstrPortName
|
||||
&& (Name->Length >= 32 * sizeof(WCHAR))
|
||||
&& _wcsicmp(Name->Buffer, Ipc_Dynamic_Ports[i].wstrPortName) == 0)
|
||||
{
|
||||
// dynamic version of RPC ports, see also ipc_spl.c
|
||||
// and RpcBindingFromStringBindingW in core/dll/rpcrt.c
|
||||
is_open = TRUE;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(Ipc_Dynamic_Ports[i].pPortLock);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
if (is_open)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_closed || (! is_open))
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
@ -936,12 +938,21 @@ _FX NTSTATUS Ipc_CheckGenericObject(
|
|||
}
|
||||
|
||||
if (letter) {
|
||||
|
||||
USHORT mon_type = MONITOR_IPC;
|
||||
if (!IsBoxedPath) {
|
||||
if (NT_SUCCESS(status))
|
||||
mon_type |= MONITOR_OPEN;
|
||||
else
|
||||
mon_type |= MONITOR_DENY;
|
||||
}
|
||||
|
||||
swprintf(access_str, L"(I%c) %08X", letter, GrantedAccess);
|
||||
Log_Debug_Msg(MONITOR_IPC, access_str, Name->Buffer);
|
||||
Log_Debug_Msg(mon_type, access_str, Name->Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (Session_MonitorCount) {
|
||||
else if (Session_MonitorCount) {
|
||||
|
||||
USHORT mon_type = MONITOR_IPC;
|
||||
WCHAR *mon_name = Name->Buffer;
|
||||
|
@ -995,6 +1006,7 @@ _FX NTSTATUS Ipc_CheckJobObject(
|
|||
// is inside the sandbox
|
||||
//
|
||||
|
||||
if (!Conf_Get_Boolean(proc->box->name, L"NoAddProcessToJob", 0, FALSE))
|
||||
if (GrantedAccess & (JOB_OBJECT_ASSIGN_PROCESS | JOB_OBJECT_TERMINATE))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
|
|
|
@ -28,12 +28,220 @@
|
|||
#include "session.h"
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Structures and Types
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef struct _LSA_MESSAGE_XP {
|
||||
|
||||
PORT_MESSAGE port_msg;
|
||||
ULONG api_code;
|
||||
ULONG status;
|
||||
ULONG auth_pkg_code;
|
||||
ULONG* buf;
|
||||
ULONG buf_len;
|
||||
|
||||
} LSA_MESSAGE_XP;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef _WIN64
|
||||
|
||||
static ULONG Ipc_MSV10_AuthPackageNumber = 0;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Functions
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
BOOLEAN Ipc_Filter_Lsa_Ep_Msg(PROCESS* proc, UCHAR uMsg);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_CheckPortRequest_Lsa
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_CheckPortRequest_Lsa(
|
||||
PROCESS* proc, OBJECT_NAME_INFORMATION* Name, PORT_MESSAGE* msg)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (!proc->ipc_block_password)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// check that it is \LsaAuthenticationPort
|
||||
// or that it is \RPC Control\lsasspirpc (Windows 7 variant)
|
||||
//
|
||||
|
||||
if (Name->Name.Length == 22 * sizeof(WCHAR)) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\LsaAuthenticationPort") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
}
|
||||
else if (Name->Name.Length == 23 * sizeof(WCHAR)) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\RPC Control\\lsasspirpc") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
}
|
||||
else
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// examine message
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
__try {
|
||||
|
||||
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_VISTA) {
|
||||
|
||||
//
|
||||
// in Windows Vista and Windows 7, a password change request
|
||||
// includes the WCHAR string Negotiate immediately followed
|
||||
// by a non-zero WCHAR
|
||||
//
|
||||
|
||||
WCHAR* ptr = (WCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
|
||||
ULONG len = msg->u1.s1.DataLength;
|
||||
|
||||
ProbeForRead(ptr, len, sizeof(WCHAR));
|
||||
len /= sizeof(WCHAR);
|
||||
|
||||
while (len > 9 + 1) {
|
||||
|
||||
if (ptr[0] == L'N' && ptr[9] != 0
|
||||
&& wmemcmp(ptr, L"Negotiate", 9) == 0) {
|
||||
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
break;
|
||||
}
|
||||
|
||||
++ptr;
|
||||
--len;
|
||||
}
|
||||
|
||||
}
|
||||
#ifndef _WIN64
|
||||
else { // xp support
|
||||
|
||||
//
|
||||
// prior to Windows Vista, we have a 'call package' api
|
||||
// call (value 2), which identifies the MSV10 auth package,
|
||||
// and a change password sub code (value 5)
|
||||
//
|
||||
|
||||
if (msg->u1.s1.TotalLength >= sizeof(LSA_MESSAGE_XP)) {
|
||||
|
||||
LSA_MESSAGE_XP* msg2 = (LSA_MESSAGE_XP*)msg;
|
||||
|
||||
ProbeForRead(
|
||||
msg2, sizeof(LSA_MESSAGE_XP), sizeof(ULONG_PTR));
|
||||
|
||||
if (msg2->api_code == 2 && // LsaCallAuthenticationPackage
|
||||
msg2->auth_pkg_code == Ipc_MSV10_AuthPackageNumber &&
|
||||
msg2->buf_len >= sizeof(ULONG)) {
|
||||
|
||||
ULONG* buf = msg2->buf;
|
||||
ProbeForRead(buf, sizeof(ULONG), sizeof(ULONG));
|
||||
|
||||
if (*buf == 5) { // change password
|
||||
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED)
|
||||
Log_Msg_Process(MSG_PASSWORD_CHANGE_DENIED, NULL, NULL, -1, proc->pid);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_CheckPortRequest_LsaEP
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_CheckPortRequest_LsaEP(
|
||||
PROCESS* proc, OBJECT_NAME_INFORMATION* Name, PORT_MESSAGE* msg)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (proc->ipc_open_lsa_endpoint)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
if (Name->Name.Length == 28 * sizeof(WCHAR)) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\RPC Control\\LSARPC_ENDPOINT") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
}
|
||||
else
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// examine message
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
__try {
|
||||
|
||||
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_7) {
|
||||
|
||||
ULONG len = msg->u1.s1.DataLength;
|
||||
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
|
||||
int i = 0;
|
||||
int rc = -2;
|
||||
|
||||
ProbeForRead(ptr, len, sizeof(WCHAR));
|
||||
|
||||
if (Ipc_Filter_Lsa_Ep_Msg(proc, ptr[20]))
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
||||
//DbgPrint("\\RPC Control\\LSARPC_ENDPOINT message ID: %d\n", (int)ptr[20]);
|
||||
}
|
||||
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Filter_Lsa_Ep_Msg
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN Ipc_Filter_Lsa_Ep_Msg(UCHAR uMsg)
|
||||
_FX BOOLEAN Ipc_Filter_Lsa_Ep_Msg(PROCESS* proc, UCHAR uMsg)
|
||||
{
|
||||
BOOLEAN filter = FALSE;
|
||||
|
||||
|
@ -120,14 +328,54 @@ _FX BOOLEAN Ipc_Filter_Lsa_Ep_Msg(UCHAR uMsg)
|
|||
filter = TRUE;
|
||||
}
|
||||
|
||||
if (Session_MonitorCount) {
|
||||
if (Session_MonitorCount && (proc->ipc_trace & (TRACE_ALLOW | TRACE_DENY))) {
|
||||
|
||||
WCHAR access_str[24];
|
||||
swprintf(access_str, L" Msg: %02X", (ULONG)uMsg);
|
||||
const WCHAR* strings[3] = { L"\\RPC Control\\LSARPC_ENDPOINT", access_str, NULL };
|
||||
Session_MonitorPutEx(MONITOR_IPC | (filter ? MONITOR_DENY : MONITOR_OPEN), strings, PsGetCurrentProcessId());
|
||||
USHORT mon_type = MONITOR_IPC;
|
||||
|
||||
if (filter && (proc->ipc_trace & TRACE_DENY))
|
||||
mon_type |= MONITOR_DENY;
|
||||
else if (!filter && (proc->ipc_trace & TRACE_ALLOW))
|
||||
mon_type |= MONITOR_OPEN;
|
||||
else
|
||||
mon_type = 0;
|
||||
|
||||
if (mon_type) {
|
||||
WCHAR msg_str[24];
|
||||
swprintf(msg_str, L" Msg: %02X", (ULONG)uMsg);
|
||||
const WCHAR* strings[3] = { L"\\RPC Control\\LSARPC_ENDPOINT", msg_str, NULL };
|
||||
Session_MonitorPutEx(mon_type, strings, NULL, PsGetCurrentProcessId());
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_SetLsaAuthPkg
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_Api_SetLsaAuthPkg(PROCESS* proc, ULONG64* parms) // xp support
|
||||
{
|
||||
//
|
||||
// caller must be our service process
|
||||
//
|
||||
|
||||
if (proc || (PsGetCurrentProcessId() != Api_ServiceProcessId))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
//
|
||||
// collect msv10 auth package number
|
||||
//
|
||||
|
||||
if (Ipc_MSV10_AuthPackageNumber)
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
Ipc_MSV10_AuthPackageNumber = (ULONG)parms[1];
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -82,18 +82,6 @@ typedef struct _WINAPI_MESSAGE {
|
|||
|
||||
} WINAPI_MESSAGE;
|
||||
|
||||
|
||||
typedef struct _LSA_MESSAGE_XP {
|
||||
|
||||
PORT_MESSAGE port_msg;
|
||||
ULONG api_code;
|
||||
ULONG status;
|
||||
ULONG auth_pkg_code;
|
||||
ULONG *buf;
|
||||
ULONG buf_len;
|
||||
|
||||
} LSA_MESSAGE_XP;
|
||||
|
||||
typedef struct _POWER_API_MESSAGE
|
||||
{
|
||||
PORT_MESSAGE port_msg;
|
||||
|
@ -122,32 +110,37 @@ typedef struct _POWER_API_MESSAGE
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
static NTSTATUS Ipc_CheckPortRequest(
|
||||
NTSTATUS Ipc_CheckPortRequest(
|
||||
PROCESS *proc, HANDLE PortHandle, PORT_MESSAGE *msg);
|
||||
|
||||
static NTSTATUS Ipc_CheckPortRequest_WinApi(
|
||||
NTSTATUS Ipc_CheckPortRequest_WinApi(
|
||||
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg);
|
||||
|
||||
static NTSTATUS Ipc_CheckPortRequest_Lsa(
|
||||
NTSTATUS Ipc_CheckPortRequest_Lsa(
|
||||
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg);
|
||||
|
||||
static NTSTATUS Ipc_CheckPortRequest_LsaEP(
|
||||
NTSTATUS Ipc_CheckPortRequest_LsaEP(
|
||||
PROCESS* proc, OBJECT_NAME_INFORMATION* Name, PORT_MESSAGE* msg);
|
||||
|
||||
static NTSTATUS Ipc_CheckPortRequest_PowerManagement(
|
||||
NTSTATUS Ipc_CheckPortRequest_PowerManagement(
|
||||
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg);
|
||||
|
||||
static NTSTATUS Ipc_CheckPortRequest_SpoolerPort(
|
||||
NTSTATUS Ipc_CheckPortRequest_SpoolerPort(
|
||||
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg);
|
||||
|
||||
|
||||
static NTSTATUS Ipc_Api_GetRpcPortName_2(
|
||||
PEPROCESS ProcessObject, WCHAR* pDstPortName);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
static ULONG Ipc_MSV10_AuthPackageNumber = 0;
|
||||
IPC_DYNAMIC_PORTS Ipc_Dynamic_Ports[NUM_DYNAMIC_PORTS];
|
||||
|
||||
static const WCHAR* _rpc_control = L"\\RPC Control";
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -269,121 +262,6 @@ finish:
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_CheckPortRequest_SpoolerPort
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// This routine is currently not used. We chose to block spooler CreateFile in the minifilter instead. But I (Curt) am keeping this code
|
||||
// around because it demonstrates how to examine & filter RPC requests going to the spooler.
|
||||
|
||||
// todo: move this code to ipc_spl.c
|
||||
|
||||
BOOLEAN Ipc_Filter_Spooler_Msg(UCHAR uMsg);
|
||||
|
||||
_FX NTSTATUS Ipc_CheckPortRequest_SpoolerPort(
|
||||
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (proc->ipc_openPrintSpooler) // see if we are not filtering spooler requests
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// check that it is the spooler port
|
||||
//
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_81) {
|
||||
|
||||
if (Name->Name.Length < 13 * sizeof(WCHAR))
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
BOOLEAN is_spooler = FALSE;
|
||||
|
||||
if (Ipc_Dynamic_Ports[SPOOLER_PORT].pPortLock)
|
||||
{
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceSharedLite(Ipc_Dynamic_Ports[SPOOLER_PORT].pPortLock, TRUE);
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, Ipc_Dynamic_Ports[SPOOLER_PORT].wstrPortName) == 0)
|
||||
{
|
||||
// dynamic version of RPC ports, see also ipc_spl.c
|
||||
// and RpcBindingFromStringBindingW in core/dll/rpcrt.c
|
||||
is_spooler = TRUE;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(Ipc_Dynamic_Ports[SPOOLER_PORT].pPortLock);
|
||||
KeLeaveCriticalRegion();
|
||||
}
|
||||
|
||||
if(!is_spooler)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
}
|
||||
else if (Driver_OsVersion >= DRIVER_WINDOWS_VISTA) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\RPC Control\\spoolss") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
} else
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// examine message
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
__try {
|
||||
|
||||
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_VISTA) {
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
ULONG len = msg->u1.s1.DataLength;
|
||||
UCHAR *ptr = (UCHAR *)((UCHAR *)msg + sizeof(PORT_MESSAGE));
|
||||
int i = 0;
|
||||
int rc = -2;
|
||||
|
||||
ProbeForRead(ptr, len, sizeof(WCHAR));
|
||||
|
||||
/*if (ptr[20] == 17) { // RpcStartDocPrinter = Opnum 17
|
||||
|
||||
if (!proc->ipc_allowSpoolerPrintToFile)
|
||||
{
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
//for (i = 20; i < len - 12; i++)
|
||||
//{
|
||||
// rc = memcmp((void*)&(ptr[i]), "\4\0\0\0\0\0\0\0\4\0\0\0\0", 12); // search for marshaled "RAW" field length bytes
|
||||
// if (rc == 0)
|
||||
// {
|
||||
// rc = _wcsnicmp((void*)&(ptr[i + 12]), L"raw", 3); // search for case insensitive "RAW"
|
||||
// if (rc == 0)
|
||||
// status = STATUS_ACCESS_DENIED;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED)
|
||||
Log_MsgP0(MSG_1319, proc->pid);
|
||||
}
|
||||
else*/
|
||||
|
||||
if (Ipc_Filter_Spooler_Msg(ptr[20]))
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
||||
//DbgPrint("Spooler IPC Port message ID: %d\n", (int)ptr[20]);
|
||||
|
||||
}
|
||||
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_DisplayPowerMsg
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -543,6 +421,7 @@ _FX NTSTATUS Ipc_CheckPortRequest_PowerManagement(
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_CheckPortRequest_WinApi
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -625,174 +504,6 @@ _FX NTSTATUS Ipc_CheckPortRequest_WinApi(
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_CheckPortRequest_Lsa
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_CheckPortRequest_Lsa(
|
||||
PROCESS *proc, OBJECT_NAME_INFORMATION *Name, PORT_MESSAGE *msg)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (! proc->ipc_block_password)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// check that it is \LsaAuthenticationPort
|
||||
// or that it is \RPC Control\lsasspirpc (Windows 7 variant)
|
||||
//
|
||||
|
||||
if (Name->Name.Length == 22 * sizeof(WCHAR)) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\LsaAuthenticationPort") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
} else if (Name->Name.Length == 23 * sizeof(WCHAR)) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\RPC Control\\lsasspirpc") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
} else
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// examine message
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
__try {
|
||||
|
||||
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_VISTA) {
|
||||
|
||||
//
|
||||
// in Windows Vista and Windows 7, a password change request
|
||||
// includes the WCHAR string Negotiate immediately followed
|
||||
// by a non-zero WCHAR
|
||||
//
|
||||
|
||||
WCHAR *ptr = (WCHAR *)((UCHAR *)msg + sizeof(PORT_MESSAGE));
|
||||
ULONG len = msg->u1.s1.DataLength;
|
||||
|
||||
ProbeForRead(ptr, len, sizeof(WCHAR));
|
||||
len /= sizeof(WCHAR);
|
||||
|
||||
while (len > 9 + 1) {
|
||||
|
||||
if (ptr[0] == L'N' && ptr[9] != 0
|
||||
&& wmemcmp(ptr, L"Negotiate", 9) == 0) {
|
||||
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
break;
|
||||
}
|
||||
|
||||
++ptr;
|
||||
--len;
|
||||
}
|
||||
|
||||
} else { // xp support
|
||||
|
||||
//
|
||||
// prior to Windows Vista, we have a 'call package' api
|
||||
// call (value 2), which identifies the MSV10 auth package,
|
||||
// and a change password sub code (value 5)
|
||||
//
|
||||
|
||||
if (msg->u1.s1.TotalLength >= sizeof(LSA_MESSAGE_XP)) {
|
||||
|
||||
LSA_MESSAGE_XP *msg2 = (LSA_MESSAGE_XP *)msg;
|
||||
|
||||
ProbeForRead(
|
||||
msg2, sizeof(LSA_MESSAGE_XP), sizeof(ULONG_PTR));
|
||||
|
||||
if (msg2->api_code == 2 && // LsaCallAuthenticationPackage
|
||||
msg2->auth_pkg_code == Ipc_MSV10_AuthPackageNumber &&
|
||||
msg2->buf_len >= sizeof(ULONG)) {
|
||||
|
||||
ULONG *buf = msg2->buf;
|
||||
ProbeForRead(buf, sizeof(ULONG), sizeof(ULONG));
|
||||
|
||||
if (*buf == 5) { // change password
|
||||
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED)
|
||||
Log_Msg_Process(MSG_PASSWORD_CHANGE_DENIED, NULL, NULL, -1, proc->pid);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_CheckPortRequest_LsaEP
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// todo: move the lsa code to code to ipc_lsa.c
|
||||
|
||||
BOOLEAN Ipc_Filter_Lsa_Ep_Msg(UCHAR uMsg);
|
||||
|
||||
_FX NTSTATUS Ipc_CheckPortRequest_LsaEP(
|
||||
PROCESS* proc, OBJECT_NAME_INFORMATION* Name, PORT_MESSAGE* msg)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (proc->ipc_open_lsa_endpoint)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
if (Name->Name.Length == 28 * sizeof(WCHAR)) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\RPC Control\\LSARPC_ENDPOINT") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
}
|
||||
else
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// examine message
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
__try {
|
||||
|
||||
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_7) {
|
||||
|
||||
ULONG len = msg->u1.s1.DataLength;
|
||||
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
|
||||
int i = 0;
|
||||
int rc = -2;
|
||||
|
||||
ProbeForRead(ptr, len, sizeof(WCHAR));
|
||||
|
||||
if (Ipc_Filter_Lsa_Ep_Msg(ptr[20]))
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
||||
//DbgPrint("\\RPC Control\\LSARPC_ENDPOINT message ID: %d\n", (int)ptr[20]);
|
||||
}
|
||||
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_ImpersonatePort
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -856,6 +567,288 @@ _FX NTSTATUS Ipc_AlpcSendWaitReceivePort(
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_OpenDynamicPort
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Param 1 is dynamic port name (e.g. "\RPC Control\LRPC-f760d5b40689a98168"), WCHAR[DYNAMIC_PORT_NAME_CHARS]
|
||||
// Param 2 is the process PID for which to open the port, can be 0 when port is special
|
||||
// Param 3 is the port type/identifier, can be -1 indicating non special port
|
||||
|
||||
_FX NTSTATUS Ipc_Api_OpenDynamicPort(PROCESS* proc, ULONG64* parms)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
//KIRQL irql;
|
||||
API_OPEN_DYNAMIC_PORT_ARGS* pArgs = (API_OPEN_DYNAMIC_PORT_ARGS*)parms;
|
||||
WCHAR portName[DYNAMIC_PORT_NAME_CHARS];
|
||||
|
||||
if (proc) // is caller sandboxed?
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
//if (PsGetCurrentProcessId() != Api_ServiceProcessId)
|
||||
// return STATUS_ACCESS_DENIED;
|
||||
|
||||
ENUM_DYNAMIC_PORT_TYPE ePortType = NUM_DYNAMIC_PORTS;
|
||||
//if (pArgs->port_type.val == -1)
|
||||
// ePortType = NUM_DYNAMIC_PORTS;
|
||||
//else
|
||||
if (pArgs->port_type.val <= NUM_DYNAMIC_PORTS)
|
||||
ePortType = (ENUM_DYNAMIC_PORT_TYPE)pArgs->port_type.val;
|
||||
//else
|
||||
// return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if (pArgs->port_name.val == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
try {
|
||||
ProbeForRead(pArgs->port_name.val, sizeof(WCHAR) * DYNAMIC_PORT_NAME_CHARS, sizeof(WCHAR));
|
||||
wmemcpy(portName, pArgs->port_name.val, DYNAMIC_PORT_NAME_CHARS - 1);
|
||||
portName[DYNAMIC_PORT_NAME_CHARS - 1] = L'\0';
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// When this is a special port save it our global Ipc_Dynamic_Ports structure
|
||||
//
|
||||
|
||||
if (ePortType != NUM_DYNAMIC_PORTS && Ipc_Dynamic_Ports[ePortType].pPortLock)
|
||||
{
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(Ipc_Dynamic_Ports[ePortType].pPortLock, TRUE);
|
||||
|
||||
wmemcpy(Ipc_Dynamic_Ports[ePortType].wstrPortName, portName, DYNAMIC_PORT_NAME_CHARS);
|
||||
|
||||
ExReleaseResourceLite(Ipc_Dynamic_Ports[ePortType].pPortLock);
|
||||
KeLeaveCriticalRegion();
|
||||
}
|
||||
|
||||
//
|
||||
// Open the port for the selected process
|
||||
//
|
||||
|
||||
if (pArgs->process_id.val != 0)
|
||||
{
|
||||
//proc = Process_Find(pArgs->process_id.val, &irql);
|
||||
proc = Process_Find(pArgs->process_id.val, NULL);
|
||||
if (proc && (proc != PROCESS_TERMINATED))
|
||||
{
|
||||
KIRQL irql2;
|
||||
|
||||
KeRaiseIrql(APC_LEVEL, &irql2);
|
||||
ExAcquireResourceExclusiveLite(proc->ipc_lock, TRUE);
|
||||
|
||||
Process_AddPath(proc, &proc->open_ipc_paths, NULL, FALSE, portName, FALSE);
|
||||
|
||||
ExReleaseResourceLite(proc->ipc_lock);
|
||||
KeLowerIrql(irql2);
|
||||
}
|
||||
else
|
||||
status = STATUS_NOT_FOUND;
|
||||
//ExReleaseResourceLite(Process_ListLock);
|
||||
//KeLowerIrql(irql);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_GetDynamicPortFromPid
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Param 1 is the service PID
|
||||
// Param 2 will return the port name with "\RPC Control\" prepended
|
||||
|
||||
_FX NTSTATUS Ipc_Api_GetDynamicPortFromPid(PROCESS* proc, ULONG64* parms)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PEPROCESS ProcessObject;
|
||||
//BOOLEAN done = FALSE;
|
||||
API_GET_DYNAMIC_PORT_FROM_PID_ARGS* pArgs = (API_GET_DYNAMIC_PORT_FROM_PID_ARGS*)parms;
|
||||
|
||||
if (proc) // is caller sandboxed?
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
//
|
||||
// this function determines the dynamic RPC endpoint that is used by a service/process
|
||||
//
|
||||
|
||||
status = PsLookupProcessByProcessId(pArgs->process_id.val, &ProcessObject);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//if (PsGetProcessSessionId(ProcessObject) == 0) {
|
||||
//
|
||||
// void *nbuf;
|
||||
// ULONG nlen;
|
||||
// WCHAR *nptr;
|
||||
//
|
||||
// Process_GetProcessName(
|
||||
// Driver_Pool, (ULONG_PTR)pArgs->process_id.val, &nbuf, &nlen, &nptr);
|
||||
//
|
||||
// if (nbuf) {
|
||||
//
|
||||
// if (_wcsicmp(nptr, pArgs->exe_name.val) == 0
|
||||
// && MyIsProcessRunningAsSystemAccount(pArgs->process_id.val)) {
|
||||
|
||||
status = Ipc_Api_GetRpcPortName_2(ProcessObject, pArgs->full_port_name.val);
|
||||
|
||||
// done = TRUE;
|
||||
// }
|
||||
//
|
||||
// Mem_Free(nbuf, nlen);
|
||||
// }
|
||||
//}
|
||||
|
||||
ObDereferenceObject(ProcessObject);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_GetRpcPortName_2
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_Api_GetRpcPortName_2(PEPROCESS ProcessObject, WCHAR* pDstPortName)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG len, dummy_len;
|
||||
ULONG context;
|
||||
HANDLE handle;
|
||||
OBJECT_DIRECTORY_INFORMATION* info;
|
||||
void* buf, * PortObject;
|
||||
UNICODE_STRING objname;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
WCHAR name[DYNAMIC_PORT_NAME_CHARS];
|
||||
|
||||
InitializeObjectAttributes(&objattrs,
|
||||
&objname, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
RtlInitUnicodeString(&objname, _rpc_control);
|
||||
|
||||
status = ZwOpenDirectoryObject(&handle, 0, &objattrs);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// get a list of all objects in the system
|
||||
//
|
||||
|
||||
len = 0;
|
||||
while (1) {
|
||||
|
||||
len += PAGE_SIZE * 2;
|
||||
buf = ExAllocatePoolWithTag(PagedPool, len, tzuk);
|
||||
if (!buf) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
dummy_len = 0;
|
||||
status = ZwQueryDirectoryObject(
|
||||
handle, buf, len, FALSE, TRUE, &context, &dummy_len);
|
||||
|
||||
if (status == STATUS_MORE_ENTRIES || status == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
ExFreePoolWithTag(buf, tzuk);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// go through list looking for LRPC-* objects of type ALPC Port
|
||||
//
|
||||
|
||||
info = (OBJECT_DIRECTORY_INFORMATION*)buf;
|
||||
while (1) {
|
||||
|
||||
UNICODE_STRING* ObjName = &info->ObjectName;
|
||||
UNICODE_STRING* TypeName = &info->ObjectTypeName;
|
||||
|
||||
if ((!ObjName->Buffer) && (!TypeName->Buffer))
|
||||
break;
|
||||
|
||||
if (TypeName->Length == 9 * sizeof(WCHAR) && TypeName->Buffer
|
||||
&& _wcsicmp(TypeName->Buffer, L"ALPC Port") == 0) {
|
||||
|
||||
if ((ObjName->Length > 5 * sizeof(WCHAR)) &&
|
||||
(ObjName->Length < 64 * sizeof(WCHAR)) &&
|
||||
_wcsnicmp(ObjName->Buffer, L"LRPC-", 5) == 0) {
|
||||
|
||||
swprintf(name, L"%s\\%s", _rpc_control, ObjName->Buffer);
|
||||
|
||||
RtlInitUnicodeString(&objname, name);
|
||||
|
||||
status = ObReferenceObjectByName(
|
||||
&objname, OBJ_CASE_INSENSITIVE, NULL, 0,
|
||||
*LpcPortObjectType, KernelMode, NULL,
|
||||
&PortObject);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
// make sure the owner process for the LRPC-* port
|
||||
// is the process that was specified as a parameter
|
||||
//
|
||||
|
||||
struct {
|
||||
LIST_ENTRY PortListEntry;
|
||||
void* CommunicationInfo;
|
||||
PEPROCESS OwnerProcess;
|
||||
} *AlpcPortObject = PortObject;
|
||||
|
||||
if (AlpcPortObject->OwnerProcess == ProcessObject) {
|
||||
|
||||
__try {
|
||||
|
||||
if (pDstPortName)
|
||||
{
|
||||
ProbeForWrite(pDstPortName, sizeof(WCHAR) * DYNAMIC_PORT_NAME_CHARS, sizeof(WCHAR));
|
||||
wmemcpy(pDstPortName, name, DYNAMIC_PORT_NAME_CHARS - 1);
|
||||
pDstPortName[DYNAMIC_PORT_NAME_CHARS - 1] = L'\0';
|
||||
}
|
||||
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
ObDereferenceObject(PortObject);
|
||||
break;
|
||||
}
|
||||
|
||||
ObDereferenceObject(PortObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++info;
|
||||
}
|
||||
|
||||
//
|
||||
// release storage
|
||||
//
|
||||
|
||||
ExFreePoolWithTag(buf, tzuk);
|
||||
|
||||
ZwClose(handle);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 32-bit hooks for Windows XP
|
||||
|
@ -871,32 +864,6 @@ _FX NTSTATUS Ipc_AlpcSendWaitReceivePort(
|
|||
#ifndef _WIN64
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_SetLsaAuthPkg
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_Api_SetLsaAuthPkg(PROCESS *proc, ULONG64 *parms)
|
||||
{
|
||||
//
|
||||
// caller must be our service process
|
||||
//
|
||||
|
||||
if (proc || (PsGetCurrentProcessId() != Api_ServiceProcessId))
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
//
|
||||
// collect msv10 auth package number
|
||||
//
|
||||
|
||||
if (Ipc_MSV10_AuthPackageNumber)
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
Ipc_MSV10_AuthPackageNumber = (ULONG)parms[1];
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// IPC_PORT_HEADER
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -33,17 +33,9 @@
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
static NTSTATUS Ipc_Api_GetRpcPortName_2(PEPROCESS ProcessObject, WCHAR *pDstPortName);
|
||||
BOOLEAN Ipc_Filter_Spooler_Msg(PROCESS* proc, UCHAR uMsg);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Variables
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
IPC_DYNAMIC_PORTS Ipc_Dynamic_Ports[NUM_DYNAMIC_PORTS];
|
||||
|
||||
static const WCHAR *_rpc_control = L"\\RPC Control";
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_AllowSpoolerPrintToFile
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -67,278 +59,112 @@ static const WCHAR *_rpc_control = L"\\RPC Control";
|
|||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_OpenDynamicPort
|
||||
// Ipc_CheckPortRequest_SpoolerPort
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Param 1 is dynamic port name (e.g. "\RPC Control\LRPC-f760d5b40689a98168"), WCHAR[DYNAMIC_PORT_NAME_CHARS]
|
||||
// Param 2 is the process PID for which to open the port
|
||||
// Param 3 is the port type/identifier, can be -1 indicating non special port
|
||||
|
||||
_FX NTSTATUS Ipc_Api_OpenDynamicPort(PROCESS* proc, ULONG64* parms)
|
||||
_FX NTSTATUS Ipc_CheckPortRequest_SpoolerPort(
|
||||
PROCESS* proc, OBJECT_NAME_INFORMATION* Name, PORT_MESSAGE* msg)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
//KIRQL irql;
|
||||
API_OPEN_DYNAMIC_PORT_ARGS* pArgs = (API_OPEN_DYNAMIC_PORT_ARGS*)parms;
|
||||
WCHAR portName[DYNAMIC_PORT_NAME_CHARS];
|
||||
NTSTATUS status;
|
||||
|
||||
if (proc) // is caller sandboxed?
|
||||
return STATUS_ACCESS_DENIED;
|
||||
if (proc->ipc_openPrintSpooler) // see if we are not filtering spooler requests
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//if (PsGetCurrentProcessId() != Api_ServiceProcessId)
|
||||
// return STATUS_ACCESS_DENIED;
|
||||
//
|
||||
// check that it is the spooler port
|
||||
//
|
||||
|
||||
ENUM_DYNAMIC_PORT_TYPE ePortType = NUM_DYNAMIC_PORTS;
|
||||
//if (pArgs->port_type.val == -1)
|
||||
// ePortType = NUM_DYNAMIC_PORTS;
|
||||
//else
|
||||
if (pArgs->port_type.val <= NUM_DYNAMIC_PORTS)
|
||||
ePortType = (ENUM_DYNAMIC_PORT_TYPE)pArgs->port_type.val;
|
||||
//else
|
||||
// return STATUS_INVALID_PARAMETER;
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_81) {
|
||||
|
||||
if (Name->Name.Length < 13 * sizeof(WCHAR))
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
BOOLEAN is_spooler = FALSE;
|
||||
|
||||
if (Ipc_Dynamic_Ports[SPOOLER_PORT].pPortLock)
|
||||
{
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceSharedLite(Ipc_Dynamic_Ports[SPOOLER_PORT].pPortLock, TRUE);
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, Ipc_Dynamic_Ports[SPOOLER_PORT].wstrPortName) == 0)
|
||||
{
|
||||
// dynamic version of RPC ports, see also ipc_spl.c
|
||||
// and RpcBindingFromStringBindingW in core/dll/rpcrt.c
|
||||
is_spooler = TRUE;
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(Ipc_Dynamic_Ports[SPOOLER_PORT].pPortLock);
|
||||
KeLeaveCriticalRegion();
|
||||
}
|
||||
|
||||
if (!is_spooler)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
}
|
||||
else if (Driver_OsVersion >= DRIVER_WINDOWS_VISTA) {
|
||||
|
||||
if (_wcsicmp(Name->Name.Buffer, L"\\RPC Control\\spoolss") != 0)
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
}
|
||||
else
|
||||
return STATUS_BAD_INITIAL_PC;
|
||||
|
||||
//
|
||||
// examine message
|
||||
//
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
__try {
|
||||
|
||||
ProbeForRead(msg, sizeof(PORT_MESSAGE), sizeof(ULONG_PTR));
|
||||
|
||||
if (Driver_OsVersion >= DRIVER_WINDOWS_VISTA) {
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
ULONG len = msg->u1.s1.DataLength;
|
||||
UCHAR* ptr = (UCHAR*)((UCHAR*)msg + sizeof(PORT_MESSAGE));
|
||||
int i = 0;
|
||||
int rc = -2;
|
||||
|
||||
ProbeForRead(ptr, len, sizeof(WCHAR));
|
||||
|
||||
/*if (ptr[20] == 17) { // RpcStartDocPrinter = Opnum 17
|
||||
|
||||
if (!proc->ipc_allowSpoolerPrintToFile)
|
||||
{
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
//for (i = 20; i < len - 12; i++)
|
||||
//{
|
||||
// rc = memcmp((void*)&(ptr[i]), "\4\0\0\0\0\0\0\0\4\0\0\0\0", 12); // search for marshaled "RAW" field length bytes
|
||||
// if (rc == 0)
|
||||
// {
|
||||
// rc = _wcsnicmp((void*)&(ptr[i + 12]), L"raw", 3); // search for case insensitive "RAW"
|
||||
// if (rc == 0)
|
||||
// status = STATUS_ACCESS_DENIED;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if (status == STATUS_ACCESS_DENIED)
|
||||
Log_MsgP0(MSG_1319, proc->pid);
|
||||
}
|
||||
else*/
|
||||
|
||||
if (Ipc_Filter_Spooler_Msg(proc, ptr[20]))
|
||||
status = STATUS_ACCESS_DENIED;
|
||||
|
||||
//DbgPrint("Spooler IPC Port message ID: %d\n", (int)ptr[20]);
|
||||
|
||||
}
|
||||
|
||||
if(pArgs->port_name.val == NULL)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
try {
|
||||
ProbeForRead(pArgs->port_name.val, sizeof(WCHAR) * DYNAMIC_PORT_NAME_CHARS, sizeof(WCHAR));
|
||||
wmemcpy(portName, pArgs->port_name.val, DYNAMIC_PORT_NAME_CHARS - 1);
|
||||
portName[DYNAMIC_PORT_NAME_CHARS - 1] = L'\0';
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//proc = Process_Find(pArgs->process_id.val, &irql);
|
||||
proc = Process_Find(pArgs->process_id.val, NULL);
|
||||
if (proc && (proc != PROCESS_TERMINATED))
|
||||
{
|
||||
//
|
||||
// When this is a special port save it our global Ipc_Dynamic_Ports structure
|
||||
//
|
||||
|
||||
if (ePortType != NUM_DYNAMIC_PORTS && Ipc_Dynamic_Ports[ePortType].pPortLock)
|
||||
{
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(Ipc_Dynamic_Ports[ePortType].pPortLock, TRUE);
|
||||
|
||||
wmemcpy(Ipc_Dynamic_Ports[ePortType].wstrPortName, portName, DYNAMIC_PORT_NAME_CHARS);
|
||||
|
||||
ExReleaseResourceLite(Ipc_Dynamic_Ports[ePortType].pPortLock);
|
||||
KeLeaveCriticalRegion();
|
||||
}
|
||||
|
||||
//
|
||||
// Open the port for the selected process
|
||||
//
|
||||
|
||||
KIRQL irql2;
|
||||
|
||||
KeRaiseIrql(APC_LEVEL, &irql2);
|
||||
ExAcquireResourceExclusiveLite(proc->ipc_lock, TRUE);
|
||||
|
||||
Process_AddPath(proc, &proc->open_ipc_paths, NULL, FALSE, portName, FALSE);
|
||||
|
||||
ExReleaseResourceLite(proc->ipc_lock);
|
||||
KeLowerIrql(irql2);
|
||||
}
|
||||
else
|
||||
status = STATUS_NOT_FOUND;
|
||||
//ExReleaseResourceLite(Process_ListLock);
|
||||
//KeLowerIrql(irql);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_GetDynamicPortFromPid
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Param 1 is the service PID
|
||||
// Param 2 will return the port name with "\RPC Control\" prepended
|
||||
|
||||
_FX NTSTATUS Ipc_Api_GetDynamicPortFromPid(PROCESS *proc, ULONG64 *parms)
|
||||
{
|
||||
NTSTATUS status;
|
||||
PEPROCESS ProcessObject;
|
||||
//BOOLEAN done = FALSE;
|
||||
API_GET_DYNAMIC_PORT_FROM_PID_ARGS *pArgs = (API_GET_DYNAMIC_PORT_FROM_PID_ARGS *)parms;
|
||||
|
||||
if (proc) // is caller sandboxed?
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
||||
//
|
||||
// this function determines the dynamic RPC endpoint that is used by a service/process
|
||||
//
|
||||
|
||||
status = PsLookupProcessByProcessId(pArgs->process_id.val, &ProcessObject);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//if (PsGetProcessSessionId(ProcessObject) == 0) {
|
||||
//
|
||||
// void *nbuf;
|
||||
// ULONG nlen;
|
||||
// WCHAR *nptr;
|
||||
//
|
||||
// Process_GetProcessName(
|
||||
// Driver_Pool, (ULONG_PTR)pArgs->process_id.val, &nbuf, &nlen, &nptr);
|
||||
//
|
||||
// if (nbuf) {
|
||||
//
|
||||
// if (_wcsicmp(nptr, pArgs->exe_name.val) == 0
|
||||
// && MyIsProcessRunningAsSystemAccount(pArgs->process_id.val)) {
|
||||
|
||||
status = Ipc_Api_GetRpcPortName_2(ProcessObject, pArgs->full_port_name.val);
|
||||
|
||||
// done = TRUE;
|
||||
// }
|
||||
//
|
||||
// Mem_Free(nbuf, nlen);
|
||||
// }
|
||||
//}
|
||||
|
||||
ObDereferenceObject(ProcessObject);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ipc_Api_GetRpcPortName_2
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX NTSTATUS Ipc_Api_GetRpcPortName_2(PEPROCESS ProcessObject, WCHAR *pDstPortName)
|
||||
{
|
||||
NTSTATUS status;
|
||||
ULONG len, dummy_len;
|
||||
ULONG context;
|
||||
HANDLE handle;
|
||||
OBJECT_DIRECTORY_INFORMATION *info;
|
||||
void *buf, *PortObject;
|
||||
UNICODE_STRING objname;
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
WCHAR name[DYNAMIC_PORT_NAME_CHARS];
|
||||
|
||||
InitializeObjectAttributes(&objattrs,
|
||||
&objname, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
|
||||
RtlInitUnicodeString(&objname, _rpc_control);
|
||||
|
||||
status = ZwOpenDirectoryObject(&handle, 0, &objattrs);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// get a list of all objects in the system
|
||||
//
|
||||
|
||||
len = 0;
|
||||
while (1) {
|
||||
|
||||
len += PAGE_SIZE * 2;
|
||||
buf = ExAllocatePoolWithTag(PagedPool, len, tzuk);
|
||||
if (!buf) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
dummy_len = 0;
|
||||
status = ZwQueryDirectoryObject(
|
||||
handle, buf, len, FALSE, TRUE, &context, &dummy_len);
|
||||
|
||||
if (status == STATUS_MORE_ENTRIES || status == STATUS_INFO_LENGTH_MISMATCH)
|
||||
{
|
||||
ExFreePoolWithTag(buf, tzuk);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
return status;
|
||||
|
||||
//
|
||||
// go through list looking for LRPC-* objects of type ALPC Port
|
||||
//
|
||||
|
||||
info = (OBJECT_DIRECTORY_INFORMATION *)buf;
|
||||
while (1) {
|
||||
|
||||
UNICODE_STRING *ObjName = &info->ObjectName;
|
||||
UNICODE_STRING *TypeName = &info->ObjectTypeName;
|
||||
|
||||
if ((!ObjName->Buffer) && (!TypeName->Buffer))
|
||||
break;
|
||||
|
||||
if (TypeName->Length == 9 * sizeof(WCHAR) && TypeName->Buffer
|
||||
&& _wcsicmp(TypeName->Buffer, L"ALPC Port") == 0) {
|
||||
|
||||
if ((ObjName->Length > 5 * sizeof(WCHAR)) &&
|
||||
(ObjName->Length < 64 * sizeof(WCHAR)) &&
|
||||
_wcsnicmp(ObjName->Buffer, L"LRPC-", 5) == 0) {
|
||||
|
||||
swprintf(name, L"%s\\%s", _rpc_control, ObjName->Buffer);
|
||||
|
||||
RtlInitUnicodeString(&objname, name);
|
||||
|
||||
status = ObReferenceObjectByName(
|
||||
&objname, OBJ_CASE_INSENSITIVE, NULL, 0,
|
||||
*LpcPortObjectType, KernelMode, NULL,
|
||||
&PortObject);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
//
|
||||
// make sure the owner process for the LRPC-* port
|
||||
// is the process that was specified as a parameter
|
||||
//
|
||||
|
||||
struct {
|
||||
LIST_ENTRY PortListEntry;
|
||||
void *CommunicationInfo;
|
||||
PEPROCESS OwnerProcess;
|
||||
} *AlpcPortObject = PortObject;
|
||||
|
||||
if (AlpcPortObject->OwnerProcess == ProcessObject) {
|
||||
|
||||
__try {
|
||||
|
||||
if (pDstPortName)
|
||||
{
|
||||
ProbeForWrite(pDstPortName, sizeof(WCHAR) * DYNAMIC_PORT_NAME_CHARS, sizeof(WCHAR));
|
||||
wmemcpy(pDstPortName, name, DYNAMIC_PORT_NAME_CHARS - 1);
|
||||
pDstPortName[DYNAMIC_PORT_NAME_CHARS - 1] = L'\0';
|
||||
}
|
||||
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
}
|
||||
|
||||
ObDereferenceObject(PortObject);
|
||||
break;
|
||||
}
|
||||
|
||||
ObDereferenceObject(PortObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++info;
|
||||
}
|
||||
|
||||
//
|
||||
// release storage
|
||||
//
|
||||
|
||||
ExFreePoolWithTag(buf, tzuk);
|
||||
|
||||
ZwClose(handle);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -349,7 +175,7 @@ _FX NTSTATUS Ipc_Api_GetRpcPortName_2(PEPROCESS ProcessObject, WCHAR *pDstPortNa
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX BOOLEAN Ipc_Filter_Spooler_Msg(UCHAR uMsg)
|
||||
_FX BOOLEAN Ipc_Filter_Spooler_Msg(PROCESS* proc, UCHAR uMsg)
|
||||
{
|
||||
BOOLEAN filter = FALSE;
|
||||
|
||||
|
@ -471,12 +297,23 @@ _FX BOOLEAN Ipc_Filter_Spooler_Msg(UCHAR uMsg)
|
|||
filter = TRUE;
|
||||
}
|
||||
|
||||
if (Session_MonitorCount) {
|
||||
if (Session_MonitorCount && (proc->ipc_trace & (TRACE_ALLOW | TRACE_DENY))) {
|
||||
|
||||
WCHAR access_str[24];
|
||||
swprintf(access_str, L" Msg: %02X", (ULONG)uMsg);
|
||||
const WCHAR* strings[3] = { L"\\RPC Control\\spoolss", access_str, NULL };
|
||||
Session_MonitorPutEx(MONITOR_IPC | (filter ? MONITOR_DENY : MONITOR_OPEN), strings, PsGetCurrentProcessId());
|
||||
USHORT mon_type = MONITOR_IPC;
|
||||
|
||||
if (filter && (proc->ipc_trace & TRACE_DENY))
|
||||
mon_type |= MONITOR_DENY;
|
||||
else if (!filter && (proc->ipc_trace & TRACE_ALLOW))
|
||||
mon_type |= MONITOR_OPEN;
|
||||
else
|
||||
mon_type = 0;
|
||||
|
||||
if (mon_type) {
|
||||
WCHAR msg_str[24];
|
||||
swprintf(msg_str, L" Msg: %02X", (ULONG)uMsg);
|
||||
const WCHAR* strings[3] = { L"\\RPC Control\\spoolss", msg_str, NULL };
|
||||
Session_MonitorPutEx(mon_type, strings, NULL, PsGetCurrentProcessId());
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
|
|
|
@ -463,15 +463,26 @@ _FX NTSTATUS Key_MyParseProc_2(OBJ_PARSE_PROC_ARGS_2)
|
|||
letter = 0;
|
||||
|
||||
if (letter) {
|
||||
|
||||
USHORT mon_type = MONITOR_KEY;
|
||||
if (!IsBoxedPath) {
|
||||
if (ShouldMonitorAccess == TRUE)
|
||||
mon_type |= MONITOR_DENY;
|
||||
else
|
||||
mon_type |= MONITOR_OPEN;
|
||||
}
|
||||
if (!ShouldMonitorAccess)
|
||||
mon_type |= MONITOR_TRACE;
|
||||
|
||||
swprintf(access_str, L"(K%c) %08X",
|
||||
letter, AccessState->OriginalDesiredAccess);
|
||||
Log_Debug_Msg(MONITOR_FILE_OR_KEY, access_str, Name->Name.Buffer);
|
||||
Log_Debug_Msg(mon_type, access_str, Name->Name.Buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (ShouldMonitorAccess) {
|
||||
else if (ShouldMonitorAccess) {
|
||||
|
||||
Session_MonitorPut(MONITOR_FILE_OR_KEY | MONITOR_DENY, Name->Name.Buffer, proc->pid);
|
||||
Session_MonitorPut(MONITOR_KEY | MONITOR_DENY, Name->Name.Buffer, proc->pid);
|
||||
}
|
||||
|
||||
Mem_Free(Name, NameLength);
|
||||
|
|
|
@ -174,13 +174,14 @@ _FX NTSTATUS Key_Callback(void *Context, void *Arg1, void *Arg2)
|
|||
REG_SET_VALUE_KEY_INFORMATION *pSetInfo = (REG_SET_VALUE_KEY_INFORMATION*)Arg2;
|
||||
status = Key_StoreValue(proc, pSetInfo, spid);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
//
|
||||
// we only handle RegNtPreCreateKeyEx and RegNtPreOpenKeyEx events before windows 10 CU
|
||||
// we only handle RegNtPreCreateKeyEx and RegNtPreOpenKeyEx events
|
||||
//
|
||||
|
||||
if (NotifyEvent != RegNtPreCreateKeyEx &&
|
||||
NotifyEvent != RegNtPreOpenKeyEx) {
|
||||
return status;
|
||||
|
@ -189,12 +190,11 @@ _FX NTSTATUS Key_Callback(void *Context, void *Arg1, void *Arg2)
|
|||
//
|
||||
// check if the caller is sandboxed before proceeding
|
||||
//
|
||||
if (Driver_OsBuild < DRIVER_BUILD_WINDOWS_10_CU)
|
||||
{
|
||||
proc = Process_Find(NULL, NULL);
|
||||
if (proc == PROCESS_TERMINATED)
|
||||
return STATUS_PROCESS_IS_TERMINATING;
|
||||
}
|
||||
|
||||
proc = Process_Find(NULL, NULL);
|
||||
if (proc == PROCESS_TERMINATED)
|
||||
return STATUS_PROCESS_IS_TERMINATING;
|
||||
|
||||
Info = (REG_OPEN_CREATE_KEY_INFORMATION_VISTA *)Arg2;
|
||||
|
||||
// HACK ALERT! If you click a link in a Word doc, it will try to start an embedded IE, which cannot be forced into Sandboxie.
|
||||
|
|
|
@ -337,6 +337,6 @@ _FX void Log_Debug_Msg(USHORT type, const WCHAR *string1, const WCHAR *string2)
|
|||
if (Session_MonitorCount) {
|
||||
|
||||
const WCHAR* strings[4] = { string1, L" ", string2, NULL };
|
||||
Session_MonitorPutEx(type | MONITOR_TRACE, strings, PsGetCurrentProcessId());
|
||||
Session_MonitorPutEx(type, strings, NULL, PsGetCurrentProcessId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -695,6 +695,7 @@ _FX PROCESS *Process_Create(
|
|||
// initialize trace flags
|
||||
//
|
||||
|
||||
proc->call_trace = Process_GetTraceFlag(proc, L"CallTrace");
|
||||
proc->file_trace = Process_GetTraceFlag(proc, L"FileTrace");
|
||||
proc->pipe_trace = Process_GetTraceFlag(proc, L"PipeTrace");
|
||||
proc->key_trace = Process_GetTraceFlag(proc, L"KeyTrace");
|
||||
|
|
|
@ -121,6 +121,8 @@ struct _PROCESS {
|
|||
|
||||
UCHAR create_console_flag;
|
||||
|
||||
ULONG call_trace;
|
||||
|
||||
// file-related
|
||||
|
||||
PERESOURCE file_lock;
|
||||
|
|
|
@ -579,7 +579,7 @@ _FX BOOLEAN Session_IsForceDisabled(ULONG SessionId)
|
|||
_FX void Session_MonitorPut(USHORT type, const WCHAR *name, HANDLE pid)
|
||||
{
|
||||
const WCHAR* strings[2] = { name, NULL };
|
||||
Session_MonitorPutEx(type, strings, pid);
|
||||
Session_MonitorPutEx(type, strings, NULL, pid);
|
||||
}
|
||||
|
||||
|
||||
|
@ -588,7 +588,7 @@ _FX void Session_MonitorPut(USHORT type, const WCHAR *name, HANDLE pid)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
_FX void Session_MonitorPutEx(USHORT type, const WCHAR** strings, HANDLE pid)
|
||||
_FX void Session_MonitorPutEx(USHORT type, const WCHAR** strings, ULONG* lengths, HANDLE pid)
|
||||
{
|
||||
SESSION *session;
|
||||
KIRQL irql;
|
||||
|
@ -601,8 +601,8 @@ _FX void Session_MonitorPutEx(USHORT type, const WCHAR** strings, HANDLE pid)
|
|||
|
||||
ULONG64 pid64 = (ULONG64)pid;
|
||||
SIZE_T data_len = 0;
|
||||
for(const WCHAR** string = strings; *string != NULL; string++)
|
||||
data_len += wcslen(*string) * sizeof(WCHAR);
|
||||
for(int i=0; strings[i] != NULL; i++)
|
||||
data_len += (lengths ? lengths [i] : wcslen(strings[i])) * sizeof(WCHAR);
|
||||
|
||||
//[Type 2][PID 8][Data n*2]
|
||||
SIZE_T entry_size = 2 + 8 + data_len;
|
||||
|
@ -613,8 +613,8 @@ _FX void Session_MonitorPutEx(USHORT type, const WCHAR** strings, HANDLE pid)
|
|||
log_buffer_push_bytes((CHAR*)&pid64, 8, &write_ptr, session->monitor_log);
|
||||
|
||||
// join strings seamlessly
|
||||
for (const WCHAR** string = strings; *string != NULL; string++)
|
||||
log_buffer_push_bytes((CHAR*)*string, wcslen(*string) * sizeof(WCHAR), &write_ptr, session->monitor_log);
|
||||
for (int i = 0; strings[i] != NULL; i++)
|
||||
log_buffer_push_bytes((CHAR*)strings[i], (lengths ? lengths[i] : wcslen(strings[i])) * sizeof(WCHAR), &write_ptr, session->monitor_log);
|
||||
}
|
||||
else // this can only happen when the entire buffer is to small to hold this one entry
|
||||
Log_Msg0(MSG_MONITOR_OVERFLOW);
|
||||
|
@ -721,8 +721,6 @@ _FX NTSTATUS Session_Api_MonitorPut(PROCESS *proc, ULONG64 *parms)
|
|||
_FX NTSTATUS Session_Api_MonitorPut2(PROCESS *proc, ULONG64 *parms)
|
||||
{
|
||||
API_MONITOR_PUT2_ARGS *args = (API_MONITOR_PUT2_ARGS *)parms;
|
||||
UNICODE_STRING objname;
|
||||
void *object;
|
||||
USHORT *log_type;
|
||||
WCHAR *log_data;
|
||||
WCHAR *name;
|
||||
|
@ -745,12 +743,12 @@ _FX NTSTATUS Session_Api_MonitorPut2(PROCESS *proc, ULONG64 *parms)
|
|||
log_len = args->log_len.val / sizeof(WCHAR);
|
||||
if (!log_len)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (log_len > 256) // truncate as we only have 260 in buffer
|
||||
log_len = 256;
|
||||
if (log_len > 1024) // truncate as we only have 1028 in buffer
|
||||
log_len = 1024;
|
||||
log_data = args->log_ptr.val;
|
||||
ProbeForRead(log_data, log_len * sizeof(WCHAR), sizeof(WCHAR));
|
||||
|
||||
name = Mem_Alloc(proc->pool, 260 * sizeof(WCHAR)); // todo: should we increase this ?
|
||||
name = Mem_Alloc(proc->pool, 1028 * sizeof(WCHAR)); // todo: should we increase this ?
|
||||
if (! name)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
|
@ -765,46 +763,48 @@ _FX NTSTATUS Session_Api_MonitorPut2(PROCESS *proc, ULONG64 *parms)
|
|||
name[log_len] = L'\0';
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
object = NULL;
|
||||
|
||||
//
|
||||
// if type is MONITOR_IPC we try to open the object
|
||||
// to get the name assigned to it at time of creation
|
||||
//
|
||||
if (args->check_object_exists.val64 && ((type & MONITOR_TRACE) == 0)) { // do not check objects if this is a trace entry
|
||||
|
||||
if ((type & 0xFFF) == MONITOR_IPC) {
|
||||
UNICODE_STRING objname;
|
||||
void* object = NULL;
|
||||
|
||||
ULONG i;
|
||||
//
|
||||
// if type is MONITOR_IPC we try to open the object
|
||||
// to get the name assigned to it at time of creation
|
||||
//
|
||||
|
||||
RtlInitUnicodeString(&objname, name);
|
||||
if ((type & 0xFFF) == MONITOR_IPC) {
|
||||
|
||||
for (i = 0; Session_ObjectTypes[i]; ++i) {
|
||||
ULONG i;
|
||||
|
||||
// ObReferenceObjectByName needs a non-zero ObjectType
|
||||
// so we have to keep going through all possible object
|
||||
// types as long as we get STATUS_OBJECT_TYPE_MISMATCH
|
||||
RtlInitUnicodeString(&objname, name);
|
||||
|
||||
status = ObReferenceObjectByName(
|
||||
&objname, OBJ_CASE_INSENSITIVE, NULL, 0,
|
||||
Session_ObjectTypes[i], KernelMode, NULL,
|
||||
&object);
|
||||
for (i = 0; Session_ObjectTypes[i]; ++i) {
|
||||
|
||||
if (status != STATUS_OBJECT_TYPE_MISMATCH)
|
||||
break;
|
||||
// ObReferenceObjectByName needs a non-zero ObjectType
|
||||
// so we have to keep going through all possible object
|
||||
// types as long as we get STATUS_OBJECT_TYPE_MISMATCH
|
||||
|
||||
status = ObReferenceObjectByName(
|
||||
&objname, OBJ_CASE_INSENSITIVE, NULL, 0,
|
||||
Session_ObjectTypes[i], KernelMode, NULL,
|
||||
&object);
|
||||
|
||||
if (status != STATUS_OBJECT_TYPE_MISMATCH)
|
||||
break;
|
||||
}
|
||||
|
||||
// DbgPrint("IPC Status = %08X Object = %08X for Open <%S>\n", status, object, name);
|
||||
}
|
||||
|
||||
// DbgPrint("IPC Status = %08X Object = %08X for Open <%S>\n", status, object, name);
|
||||
}
|
||||
//
|
||||
// if type is MONITOR_PIPE we try to open the pipe
|
||||
// to get the name assigned to it at time of creation
|
||||
//
|
||||
|
||||
//
|
||||
// if type is MONITOR_PIPE we try to open the pipe
|
||||
// to get the name assigned to it at time of creation
|
||||
//
|
||||
if ((type & 0xFFF) == MONITOR_PIPE) {
|
||||
|
||||
if ((type & 0xFFF) == MONITOR_PIPE) {
|
||||
|
||||
if (args->check_object_exists.val64)
|
||||
{
|
||||
OBJECT_ATTRIBUTES objattrs;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE handle;
|
||||
|
@ -844,35 +844,36 @@ _FX NTSTATUS Session_Api_MonitorPut2(PROCESS *proc, ULONG64 *parms)
|
|||
|
||||
//DbgPrint("PIPE Status3 = %08X Object = %08X for Open <%S>\n", status, object, name);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// if we have an object, get its name from the kernel object
|
||||
//
|
||||
//
|
||||
// if we have an object, get its name from the kernel object
|
||||
//
|
||||
|
||||
if (NT_SUCCESS(status) && object) {
|
||||
if (NT_SUCCESS(status) && object) {
|
||||
|
||||
OBJECT_NAME_INFORMATION *Name;
|
||||
ULONG NameLength;
|
||||
OBJECT_NAME_INFORMATION *Name;
|
||||
ULONG NameLength;
|
||||
|
||||
status = Obj_GetNameOrFileName(
|
||||
proc->pool, object, &Name, &NameLength);
|
||||
status = Obj_GetNameOrFileName(
|
||||
proc->pool, object, &Name, &NameLength);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
log_len = Name->Name.Length / sizeof(WCHAR);
|
||||
if (log_len > 256) // truncate as we only have 260 in buffer
|
||||
log_len = 256;
|
||||
wmemcpy(name, Name->Name.Buffer, log_len);
|
||||
name[log_len] = L'\0';
|
||||
log_len = Name->Name.Length / sizeof(WCHAR);
|
||||
if (log_len > 1024) // truncate as we only have 1028 in buffer
|
||||
log_len = 1024;
|
||||
wmemcpy(name, Name->Name.Buffer, log_len);
|
||||
name[log_len] = L'\0';
|
||||
|
||||
if (Name != &Obj_Unnamed)
|
||||
Mem_Free(Name, NameLength);
|
||||
if (Name != &Obj_Unnamed)
|
||||
Mem_Free(Name, NameLength);
|
||||
|
||||
// DbgPrint("Determined Object Name <%S>\n", name);
|
||||
// DbgPrint("Determined Object Name <%S>\n", name);
|
||||
}
|
||||
|
||||
ObDereferenceObject(object);
|
||||
}
|
||||
|
||||
ObDereferenceObject(object);
|
||||
}
|
||||
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
|
|
|
@ -44,7 +44,7 @@ BOOLEAN Session_IsForceDisabled(ULONG SessionId);
|
|||
|
||||
void Session_MonitorPut(USHORT type, const WCHAR *name, HANDLE pid);
|
||||
|
||||
void Session_MonitorPutEx(USHORT type, const WCHAR** strings, HANDLE pid);
|
||||
void Session_MonitorPutEx(USHORT type, const WCHAR** strings, ULONG* lengths, HANDLE pid);
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "obj.h"
|
||||
#include "api.h"
|
||||
#include "util.h"
|
||||
#include "session.h"
|
||||
|
||||
|
||||
|
||||
|
@ -741,6 +742,7 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
|
|||
|
||||
__try {
|
||||
|
||||
BOOLEAN traced = FALSE;
|
||||
const ULONG args_len = entry->param_count * sizeof(ULONG_PTR);
|
||||
#ifdef _WIN64
|
||||
ProbeForRead(user_args, args_len, sizeof(ULONG_PTR));
|
||||
|
@ -774,20 +776,20 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
|
|||
ProbeForRead(user_args, args_len, sizeof(UCHAR));
|
||||
#endif _WIN64
|
||||
|
||||
/*
|
||||
if (proc->ipc_trace & (TRACE_ALLOW | TRACE_DENY))
|
||||
{
|
||||
if (strcmp(entry->name, "AlpcSendWaitReceivePort") == 0)
|
||||
{
|
||||
HANDLE hConnection;
|
||||
hConnection = (HANDLE*)user_args[0];
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, handle = %X >>>>>>\n",
|
||||
PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
entry->name,
|
||||
hConnection);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//if (proc->ipc_trace & (TRACE_ALLOW | TRACE_DENY))
|
||||
//{
|
||||
// if (strcmp(entry->name, "AlpcSendWaitReceivePort") == 0)
|
||||
// {
|
||||
// HANDLE hConnection;
|
||||
// hConnection = (HANDLE*)user_args[0];
|
||||
// DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, handle = %X >>>>>>\n",
|
||||
// PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
// entry->name,
|
||||
// hConnection);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
if (entry->handler1_func) {
|
||||
|
||||
|
@ -802,17 +804,20 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
|
|||
|
||||
if (proc->ipc_trace & (TRACE_ALLOW | TRACE_DENY))
|
||||
{
|
||||
HANDLE hConnection = NULL;
|
||||
UNICODE_STRING* puStr = NULL;
|
||||
|
||||
if ((strcmp(entry->name, "ConnectPort") == 0) ||
|
||||
(strcmp(entry->name, "AlpcConnectPort") == 0) )
|
||||
{
|
||||
HANDLE hConnection = *(HANDLE*)user_args[0];
|
||||
UNICODE_STRING *puStr = (UNICODE_STRING*)user_args[1];
|
||||
hConnection = *(HANDLE*)user_args[0];
|
||||
puStr = (UNICODE_STRING*)user_args[1];
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, '%.*S', status = 0x%X, handle = %X\n",
|
||||
PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
entry->name,
|
||||
(puStr->Length / 2), puStr->Buffer,
|
||||
status, hConnection);
|
||||
//DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, '%.*S', status = 0x%X, handle = %X\n",
|
||||
// PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
// entry->name,
|
||||
// (puStr->Length / 2), puStr->Buffer,
|
||||
// status, hConnection);
|
||||
//if (puStr && puStr->Buffer && wcsstr(puStr->Buffer, L"\\RPC Control\\LRPC-"))
|
||||
//{
|
||||
//int i = 0; // place breakpoint here if you want to debug a particular port
|
||||
|
@ -821,17 +826,16 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
|
|||
else if ( (strcmp(entry->name, "AlpcCreatePort") == 0) ||
|
||||
(strcmp(entry->name, "AlpcConnectPortEx") == 0) )
|
||||
{
|
||||
HANDLE hConnection = *(HANDLE*)user_args[0];
|
||||
hConnection = *(HANDLE*)user_args[0];
|
||||
POBJECT_ATTRIBUTES pObjectAttributes = (POBJECT_ATTRIBUTES)user_args[1];
|
||||
UNICODE_STRING *puStr = NULL;
|
||||
if (pObjectAttributes)
|
||||
puStr = (UNICODE_STRING*)pObjectAttributes->ObjectName;
|
||||
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, '%.*S', status = 0x%X, handle = %X\n",
|
||||
PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
entry->name,
|
||||
(puStr->Length / 2), puStr->Buffer,
|
||||
status, hConnection);
|
||||
//DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, '%.*S', status = 0x%X, handle = %X\n",
|
||||
// PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
// entry->name,
|
||||
// (puStr->Length / 2), puStr->Buffer,
|
||||
// status, hConnection);
|
||||
}
|
||||
else if ((strcmp(entry->name, "ReplyWaitReceivePort") == 0) ||
|
||||
(strcmp(entry->name, "ReceiveMessagePort") == 0) ||
|
||||
|
@ -841,12 +845,37 @@ _FX NTSTATUS Syscall_Api_Invoke(PROCESS *proc, ULONG64 *parms)
|
|||
// these 2 APIs will generate a lot of output if we don't check status
|
||||
((status != STATUS_SUCCESS) && ((strcmp(entry->name, "AlpcSendWaitReceivePort") == 0) || (strcmp(entry->name, "RequestWaitReplyPort") == 0))) )
|
||||
{
|
||||
HANDLE hConnection = (HANDLE*)user_args[0];
|
||||
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, status = 0x%X, handle = %X\n",
|
||||
PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
entry->name,
|
||||
status, hConnection);
|
||||
hConnection = (HANDLE*)user_args[0];
|
||||
|
||||
//DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "SBIE [syscall] p=%06d t=%06d - %s, status = 0x%X, handle = %X\n",
|
||||
// PsGetCurrentProcessId(), PsGetCurrentThreadId(),
|
||||
// entry->name,
|
||||
// status, hConnection);
|
||||
}
|
||||
|
||||
if (hConnection)
|
||||
{
|
||||
WCHAR trace_str[128];
|
||||
swprintf(trace_str, L"[syscall] t=%06d - %.*S, status = 0x%X, handle = %X; ", //59 chars + entry->name
|
||||
PsGetCurrentThreadId(),
|
||||
max(strlen(entry->name), 64), entry->name,
|
||||
status, hConnection);
|
||||
const WCHAR* strings[3] = { trace_str, puStr ? puStr->Buffer : NULL, NULL };
|
||||
ULONG lengths[3] = { wcslen(trace_str), puStr ? puStr->Length / 2 : 0, 0 };
|
||||
Session_MonitorPutEx(MONITOR_IPC | MONITOR_TRACE, strings, lengths, PsGetCurrentProcessId());
|
||||
traced = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!traced && ((proc->call_trace & TRACE_ALLOW) || ((status != STATUS_SUCCESS) && (proc->call_trace & TRACE_DENY))))
|
||||
{
|
||||
WCHAR trace_str[128];
|
||||
swprintf(trace_str, L"[syscall] t=%06d - %.*S, status = 0x%X", //59 chars + entry->name
|
||||
PsGetCurrentThreadId(),
|
||||
max(strlen(entry->name), 64), entry->name,
|
||||
status);
|
||||
const WCHAR* strings[2] = { trace_str, NULL };
|
||||
Session_MonitorPutEx(MONITOR_SYSCALL | MONITOR_TRACE, strings, NULL, PsGetCurrentProcessId());
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
|
|
|
@ -37,7 +37,7 @@ static HANDLE Syscall_RestoreTargetHandle(
|
|||
|
||||
static NTSTATUS Syscall_CheckObject(
|
||||
PROCESS *proc, SYSCALL_ENTRY *syscall_entry,
|
||||
void *OpenedObject, OBJECT_HANDLE_INFORMATION *HandleInfo);
|
||||
void *OpenedObject, OBJECT_HANDLE_INFORMATION *HandleInfo, PUNICODE_STRING puName);
|
||||
|
||||
static NTSTATUS Syscall_DuplicateHandle_2(
|
||||
HANDLE TargetProcessHandle, HANDLE TargetHandle,
|
||||
|
@ -178,7 +178,7 @@ _FX HANDLE Syscall_RestoreTargetHandle(
|
|||
|
||||
_FX NTSTATUS Syscall_CheckObject(
|
||||
PROCESS *proc, SYSCALL_ENTRY *syscall_entry,
|
||||
void *OpenedObject, OBJECT_HANDLE_INFORMATION *HandleInfo)
|
||||
void *OpenedObject, OBJECT_HANDLE_INFORMATION *HandleInfo, PUNICODE_STRING puName)
|
||||
{
|
||||
OBJECT_NAME_INFORMATION *Name;
|
||||
ULONG NameLength;
|
||||
|
@ -194,9 +194,12 @@ _FX NTSTATUS Syscall_CheckObject(
|
|||
if ((status != STATUS_SUCCESS)
|
||||
&& (status != STATUS_BAD_INITIAL_PC)) {
|
||||
|
||||
if (puName == NULL && Name != NULL && Name->Name.Length != 0)
|
||||
puName = &Name->Name;
|
||||
|
||||
WCHAR msg[256];
|
||||
swprintf(msg, L"%S (%08X) access=%08X initialized=%d", syscall_entry->name, status, HandleInfo->GrantedAccess, proc->initialized);
|
||||
Log_Msg_Process(MSG_2101, msg, Name != NULL ? Name->Name.Buffer : L"Unnamed object", -1, proc->pid);
|
||||
Log_Msg_Process(MSG_2101, msg, puName != NULL ? puName->Buffer : L"Unnamed object", -1, proc->pid);
|
||||
}
|
||||
|
||||
if (Name != &Obj_Unnamed)
|
||||
|
@ -269,6 +272,10 @@ _FX NTSTATUS Syscall_OpenHandle(
|
|||
|
||||
if (! NewHandle) {
|
||||
|
||||
//WCHAR trace_str[128];
|
||||
//swprintf(trace_str, L"Syscall %.*S security violation terminating process", max(strlen(syscall_entry->name), 64), syscall_entry->name);
|
||||
//Session_MonitorPut(MONITOR_OTHER, trace_str, PsGetCurrentProcessId());
|
||||
|
||||
Process_SetTerminated(proc, 6);
|
||||
status = STATUS_PROCESS_IS_TERMINATING;
|
||||
}
|
||||
|
@ -289,15 +296,26 @@ _FX NTSTATUS Syscall_OpenHandle(
|
|||
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
PUNICODE_STRING puName = NULL;
|
||||
|
||||
if ((strcmp(syscall_entry->name, "ConnectPort") == 0) ||
|
||||
(strcmp(syscall_entry->name, "AlpcConnectPort") == 0))
|
||||
{
|
||||
puName = (UNICODE_STRING*)user_args[1];
|
||||
}
|
||||
|
||||
//
|
||||
// check the access that was granted to the object
|
||||
//
|
||||
|
||||
status = Syscall_CheckObject(
|
||||
proc, syscall_entry, OpenedObject, &HandleInfo);
|
||||
proc, syscall_entry, OpenedObject, &HandleInfo, puName);
|
||||
|
||||
ObDereferenceObject(OpenedObject);
|
||||
|
||||
if (!NT_SUCCESS(status))
|
||||
NtClose(NewHandle);
|
||||
|
||||
if (status == STATUS_BAD_INITIAL_PC) {
|
||||
|
||||
//
|
||||
|
@ -327,8 +345,14 @@ _FX NTSTATUS Syscall_OpenHandle(
|
|||
}
|
||||
}
|
||||
|
||||
if (! NT_SUCCESS(status))
|
||||
if (!NT_SUCCESS(status)) {
|
||||
|
||||
//WCHAR trace_str[128];
|
||||
//swprintf(trace_str, L"Syscall %.*S security violation, status = 0x%X, terminating process", max(strlen(syscall_entry->name), 64), syscall_entry->name, status);
|
||||
//Session_MonitorPut(MONITOR_OTHER, trace_str, PsGetCurrentProcessId());
|
||||
|
||||
Process_SetTerminated(proc, 7);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -447,6 +471,10 @@ _FX NTSTATUS Syscall_DuplicateHandle(
|
|||
|
||||
if (! NewHandle) {
|
||||
|
||||
//WCHAR trace_str[128];
|
||||
//swprintf(trace_str, L"Syscall %.*S security violation terminating process", max(strlen(syscall_entry->name), 64), syscall_entry->name);
|
||||
//Session_MonitorPut(MONITOR_OTHER, trace_str, PsGetCurrentProcessId());
|
||||
|
||||
Process_SetTerminated(proc, 8);
|
||||
status = STATUS_PROCESS_IS_TERMINATING;
|
||||
}
|
||||
|
@ -506,6 +534,11 @@ _FX NTSTATUS Syscall_DuplicateHandle(
|
|||
// if(!wcsicmp(proc->image_name,L"SandboxieBITS.exe") && status == STATUS_ACCESS_DENIED) {
|
||||
// return status;
|
||||
// }
|
||||
//
|
||||
// //WCHAR trace_str[128];
|
||||
// //swprintf(trace_str, L"Syscall %.*S security violation terminating process", max(strlen(syscall_entry->name), 64), syscall_entry->name);
|
||||
// //Session_MonitorPut(MONITOR_OTHER, trace_str, PsGetCurrentProcessId());
|
||||
//
|
||||
// Process_SetTerminated(proc, 9);
|
||||
//}
|
||||
|
||||
|
@ -633,7 +666,7 @@ _FX NTSTATUS Syscall_DuplicateHandle_2(
|
|||
//
|
||||
|
||||
status = Syscall_CheckObject(
|
||||
proc, syscall_entry, OpenedObject, &HandleInfo);
|
||||
proc, syscall_entry, OpenedObject, &HandleInfo, NULL);
|
||||
|
||||
} else if ( TypeLength == 5 * sizeof(WCHAR)
|
||||
&& wmemcmp(TypeBuffer, L"Token", 5) == 0) {
|
||||
|
|
|
@ -1060,7 +1060,7 @@ trace:
|
|||
if (Letter2) {
|
||||
swprintf(str, L"(%c%c) %08X %06d",
|
||||
Letter1, Letter2, GrantedAccess, (int)pid);
|
||||
Log_Debug_Msg(MONITOR_IPC, str, Driver_Empty);
|
||||
Log_Debug_Msg(MONITOR_IPC | MONITOR_TRACE, str, Driver_Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ MSG_HEADER *EpMapperServer::EpmapperGetPortNameHandler(MSG_HEADER *msg)
|
|||
return SHORT_REPLY(E_OUTOFMEMORY);
|
||||
|
||||
rpl->h.status = STATUS_NOT_FOUND;
|
||||
rpl->wszPortName[0] = L'\0';
|
||||
|
||||
if (pwszServiceName != NULL) {
|
||||
|
||||
|
@ -170,12 +171,18 @@ MSG_HEADER *EpMapperServer::EpmapperGetPortNameHandler(MSG_HEADER *msg)
|
|||
|
||||
if (rpl->h.status == STATUS_SUCCESS)
|
||||
{
|
||||
//
|
||||
// Note: it seams that chrome.exe resolves GAME_CONFIG_STORE_PORT in one process and accesses from an other
|
||||
// so since here we onlyonly a fre non critical ports we will use PID 0 to open it gloally
|
||||
// instead of only for the one process. Todo: make it per sandbox instead
|
||||
//
|
||||
|
||||
// Param 1 is dynamic port name (e.g. "LRPC-f760d5b40689a98168"), WCHAR[DYNAMIC_PORT_NAME_CHARS]
|
||||
// Param 2 is the process PID for which to open the port
|
||||
// Param 2 is the process PID for which to open the port, can be 0 when port is special
|
||||
// Param 3 is the port type/identifier, can be -1 indicating non special port
|
||||
rpl->h.status = SbieApi_CallThree(API_OPEN_DYNAMIC_PORT,
|
||||
(ULONG_PTR)rpl->wszPortName,
|
||||
(ULONG_PTR)idProcess,
|
||||
(ULONG_PTR)0,
|
||||
(ULONG_PTR)req->portType);
|
||||
}
|
||||
|
||||
|
|
|
@ -490,28 +490,4 @@ bool CheckDropRights(const WCHAR *BoxName)
|
|||
if (SbieApi_QueryConfBool(BoxName, L"DropAdminRights", FALSE))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// CheckStringInList
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool CheckStringInList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting)
|
||||
{
|
||||
WCHAR buf[66];
|
||||
ULONG index = 0;
|
||||
while (1) {
|
||||
NTSTATUS status = SbieApi_QueryConfAsIs(boxname, setting, index, buf, 64 * sizeof(WCHAR));
|
||||
++index;
|
||||
if (NT_SUCCESS(status)) {
|
||||
if (_wcsicmp(buf, string) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (status != STATUS_BUFFER_TOO_SMALL)
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@ void LogEvent(ULONG msgid, ULONG level, ULONG detail);
|
|||
void AbortServer(void);
|
||||
bool RestrictToken(void);
|
||||
bool CheckDropRights(const WCHAR *BoxName);
|
||||
bool CheckStringInList(const WCHAR* string, const WCHAR* boxname, const WCHAR* setting);
|
||||
|
||||
SECURITY_ATTRIBUTES *GetSecurityAttributes(ACCESS_MASK EveryoneAccess);
|
||||
|
||||
|
|
|
@ -1625,6 +1625,7 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(HANDLE idProcess, bool isSandboxed)
|
|||
NTSTATUS status = STATUS_UNSUCCESSFUL;
|
||||
HANDLE hToken = NULL;
|
||||
BOOL ok = TRUE;
|
||||
WCHAR ctrlName[64];
|
||||
|
||||
//
|
||||
// get token from caller session or caller process. note that on
|
||||
|
@ -1668,21 +1669,28 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(HANDLE idProcess, bool isSandboxed)
|
|||
if (ok && isSandboxed) {
|
||||
|
||||
const WCHAR *_Setting = SBIECTRL_ L"EnableAutoStart";
|
||||
const WCHAR* _Setting2 = SBIECTRL_ L"AutoStartAgent";
|
||||
WCHAR buf[10], ch = 0;
|
||||
bool ok2 = SetUserSettingsSectionName(hToken);
|
||||
if (ok2) {
|
||||
SbieApi_QueryConfAsIs(
|
||||
m_sectionname, _Setting, 0, buf, 8 * sizeof(WCHAR));
|
||||
m_sectionname, _Setting, 0, buf, sizeof(buf) - 2);
|
||||
ch = towlower(buf[0]);
|
||||
|
||||
SbieApi_QueryConfAsIs(
|
||||
m_sectionname, _Setting2, 0, ctrlName, sizeof(ctrlName) - 2);
|
||||
}
|
||||
if (! ch) {
|
||||
wcscpy(m_sectionname + 13, L"Default"); // UserSettings_Default
|
||||
SbieApi_QueryConfAsIs(
|
||||
m_sectionname, _Setting, 0, buf, 8 * sizeof(WCHAR));
|
||||
ch = towlower(buf[0]);
|
||||
|
||||
SbieApi_QueryConfAsIs(
|
||||
m_sectionname, _Setting2, 0, ctrlName, sizeof(ctrlName) - 2);
|
||||
}
|
||||
|
||||
if (ch != L'y') {
|
||||
if (ch == L'n') {
|
||||
status = STATUS_LOGON_NOT_GRANTED;
|
||||
ok = FALSE;
|
||||
}
|
||||
|
@ -1699,11 +1707,11 @@ MSG_HEADER *SbieIniServer::RunSbieCtrl(HANDLE idProcess, bool isSandboxed)
|
|||
|
||||
WCHAR *args;
|
||||
if (isSandboxed)
|
||||
args = NULL;
|
||||
args = L" -autorun";
|
||||
else
|
||||
args = L" /open /sync";
|
||||
|
||||
if (SbieDll_RunFromHome(SBIECTRL_EXE, args, &si, NULL)) {
|
||||
if (SbieDll_RunFromHome(*ctrlName ? ctrlName : SBIECTRL_EXE, args, &si, NULL)) {
|
||||
|
||||
WCHAR *CmdLine = (WCHAR *)si.lpReserved;
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ bool ServiceServer::CanCallerDoElevation(
|
|||
// if this service is configured to be started on box initialization
|
||||
// by SandboxieRpcSs.exe then allow it to be started
|
||||
//
|
||||
if (CheckStringInList(ServiceName, boxname, L"StartService"))
|
||||
if (SbieDll_CheckStringInList(ServiceName, boxname, L"StartService"))
|
||||
DropRights = false;
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ bool ServiceServer__RunServiceAsSystem(const WCHAR* svcname, const WCHAR* boxnam
|
|||
return true;
|
||||
|
||||
// check exception list
|
||||
return CheckStringInList(svcname, boxname, L"RunServiceAsSystem");
|
||||
return SbieDll_CheckStringInList(svcname, boxname, L"RunServiceAsSystem");
|
||||
}
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -158,6 +158,7 @@ public:
|
|||
QStyle* pStyle = QStyleFactory::create("windows");
|
||||
m_pTreeList->setStyle(pStyle);
|
||||
#endif
|
||||
m_pTreeList->setExpandsOnDoubleClick(false);
|
||||
m_pTreeList->setSortingEnabled(true);
|
||||
|
||||
m_pTreeList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
|
|
@ -11,6 +11,8 @@ public:
|
|||
{
|
||||
m_bAlternate = bAlternate;
|
||||
m_bHighLight = false;
|
||||
|
||||
this->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -55,7 +55,6 @@ CSandBox::CSandBox(const QString& BoxName, class CSbieAPI* pAPI) : CSbieIni(BoxN
|
|||
InsertText("Template", "LingerPrograms");
|
||||
// templates L7
|
||||
InsertText("Template", "BlockPorts");
|
||||
InsertText("Template", "WindowsFontCache");
|
||||
InsertText("Template", "qWave");
|
||||
|
||||
// recovery
|
||||
|
@ -92,6 +91,11 @@ SB_STATUS CSandBox::TerminateAll()
|
|||
return m_pAPI->TerminateAll(m_Name);
|
||||
}
|
||||
|
||||
bool CSandBox::IsEmpty()
|
||||
{
|
||||
return !QDir(m_FilePath).exists();
|
||||
}
|
||||
|
||||
SB_PROGRESS CSandBox::CleanBox()
|
||||
{
|
||||
if (GetBool("NeverDelete", false))
|
||||
|
@ -149,10 +153,9 @@ void CSandBox::CleanBoxAsync(const CSbieProgressPtr& pProgress, const QStringLis
|
|||
|
||||
SB_STATUS CSandBox::RenameBox(const QString& NewName)
|
||||
{
|
||||
if (QDir(m_FilePath).exists())
|
||||
if (!IsEmpty())
|
||||
return SB_ERR(SB_RemNotEmpty);
|
||||
|
||||
|
||||
SB_STATUS Status = CSbieAPI::ValidateName(NewName);
|
||||
if (Status.IsError())
|
||||
return Status;
|
||||
|
@ -162,7 +165,7 @@ SB_STATUS CSandBox::RenameBox(const QString& NewName)
|
|||
|
||||
SB_STATUS CSandBox::RemoveBox()
|
||||
{
|
||||
if (QDir(m_FilePath).exists())
|
||||
if (!IsEmpty())
|
||||
return SB_ERR(SB_DelNotEmpty);
|
||||
|
||||
return RemoveSection();
|
||||
|
@ -215,6 +218,9 @@ SB_PROGRESS CSandBox::TakeSnapshot(const QString& Name)
|
|||
if (m_pAPI->HasProcesses(m_Name))
|
||||
return SB_ERR(SB_SnapIsRunning, OP_CONFIRM);
|
||||
|
||||
if (IsEmpty())
|
||||
return SB_ERR(SB_SnapIsEmpty);
|
||||
|
||||
QStringList Snapshots = ini.childGroups();
|
||||
|
||||
QString ID;
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
|
||||
virtual void CloseBox() {}
|
||||
|
||||
virtual bool IsEmpty();
|
||||
virtual SB_PROGRESS CleanBox();
|
||||
virtual SB_STATUS RenameBox(const QString& NewName);
|
||||
virtual SB_STATUS RemoveBox();
|
||||
|
|
|
@ -752,14 +752,13 @@ QString CSbieAPI::GetVersion()
|
|||
|
||||
SB_STATUS CSbieAPI::TakeOver()
|
||||
{
|
||||
__declspec(align(8)) ULONG64 ResultValue;
|
||||
__declspec(align(8)) ULONG64 parms[API_NUM_ARGS];
|
||||
API_SESSION_LEADER_ARGS *args = (API_SESSION_LEADER_ARGS *)parms;
|
||||
|
||||
memset(parms, 0, sizeof(parms));
|
||||
args->func_code = API_SESSION_LEADER;
|
||||
args->token_handle.val64 = 0;
|
||||
args->process_id.val64 = 0;
|
||||
args->token_handle.val64 = 0; // (ULONG64)(ULONG_PTR)GetCurrentProcessToken();
|
||||
args->process_id.val64 = 0; // (ULONG64)(ULONG_PTR)&ResultValue;
|
||||
|
||||
NTSTATUS status = m->IoControl(parms);
|
||||
if (!NT_SUCCESS(status))
|
||||
|
@ -1008,7 +1007,7 @@ SB_STATUS CSbieAPI::SbieIniSet(const QString& Section, const QString& Setting, c
|
|||
|
||||
SB_STATUS Status = SbieIniSet(req, req->password, Section, Setting);
|
||||
//if (!Status)
|
||||
// emit LogSbieMessage(2203, QStringList() << "" << Status.GetText() << "", GetCurrentProcessId());
|
||||
// emit LogSbieMessage(0xC1020000 | 2203, QStringList() << "" << Status.GetText() << "", GetCurrentProcessId());
|
||||
free(req);
|
||||
return Status;
|
||||
}
|
||||
|
@ -1062,6 +1061,9 @@ SB_STATUS CSbieAPI::CreateBox(const QString& BoxName)
|
|||
if(Status.IsError())
|
||||
return Status;
|
||||
|
||||
if(m_SandBoxes.contains(BoxName.toLower()))
|
||||
return SB_ERR(SB_NameExists);
|
||||
|
||||
Status = SbieIniSet(BoxName, "Enabled", "y");
|
||||
if (Status.IsError())
|
||||
return Status;
|
||||
|
@ -1334,7 +1336,7 @@ QString CSbieAPI::GetDeviceMap()
|
|||
status = CSbieAPI__OpenDeviceMap(m, &handle);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
emit LogSbieMessage(2321, QStringList() << "" << QString("%1").arg(status, 8, 16) << "", GetCurrentProcessId());
|
||||
emit LogSbieMessage(0xC1020000 | 2321, QStringList() << "" << QString("%1").arg(status, 8, 16) << "", GetCurrentProcessId());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1345,7 +1347,7 @@ QString CSbieAPI::GetDeviceMap()
|
|||
NtClose(handle);
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
emit LogSbieMessage(2321, QStringList() << "" << QString("%1").arg(status, 8, 16) << "", GetCurrentProcessId());
|
||||
emit LogSbieMessage(0xC1020000 | 2321, QStringList() << "" << QString("%1").arg(status, 8, 16) << "", GetCurrentProcessId());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1544,6 +1546,36 @@ QString CSbieAPI::GetBoxedPath(const CSandBoxPtr& pBox, const QString& Path)
|
|||
return BoxRoot + "\\drive\\" + Path.at(0) + Path.mid(2);
|
||||
}
|
||||
|
||||
QString CSbieAPI::GetRealPath(const CSandBoxPtr& pBox, const QString& Path)
|
||||
{
|
||||
QString RealPath;
|
||||
QString BoxRoot = pBox->m_FilePath;
|
||||
if (BoxRoot.right(1) == "\\") BoxRoot.truncate(BoxRoot.length() - 1);
|
||||
|
||||
if (Path.length() < BoxRoot.length())
|
||||
return RealPath;
|
||||
|
||||
RealPath = Path.mid(BoxRoot.length());
|
||||
|
||||
if (RealPath.left(6) == "\\share")
|
||||
RealPath = "\\device\\mup" + RealPath.mid(6);
|
||||
|
||||
if (RealPath.left(5) == "\\user")
|
||||
{
|
||||
if (RealPath.mid(5, 8) == "\\current")
|
||||
RealPath = m_UserDir + RealPath.mid(5 + 8);
|
||||
else if (RealPath.mid(5, 4) == "\\all")
|
||||
RealPath = m_ProgramDataDir + RealPath.mid(5 + 4);
|
||||
else if (RealPath.mid(5, 7) == "\\public")
|
||||
RealPath = m_PublicDir + RealPath.mid(5 + 7);
|
||||
}
|
||||
|
||||
if (RealPath.left(6) == "\\drive")
|
||||
RealPath = RealPath.mid(7, 1) + ":" + RealPath.mid(8);
|
||||
|
||||
return RealPath;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Conf
|
||||
//
|
||||
|
@ -1769,6 +1801,7 @@ CBoxedProcessPtr CSbieAPI::OnProcessBoxed(quint32 ProcessId, const QString& Path
|
|||
pBox->m_ProcessList.insert(ProcessId, pProcess);
|
||||
m_BoxedProxesses.insert(ProcessId, pProcess);
|
||||
|
||||
UpdateProcessInfo(pProcess);
|
||||
pProcess->InitProcessInfo();
|
||||
}
|
||||
|
||||
|
@ -1853,7 +1886,7 @@ bool CSbieAPI::IsMonitoring()
|
|||
|
||||
bool CSbieAPI::GetMonitor()
|
||||
{
|
||||
const int max_len = 256; // versions prioir to 5.44.1 check for max_len <= 256 increase this later
|
||||
const int max_len = 1024;
|
||||
|
||||
USHORT type;
|
||||
ULONG64 pid;
|
||||
|
@ -1879,7 +1912,7 @@ bool CSbieAPI::GetMonitor()
|
|||
return false;
|
||||
|
||||
if (RecordNum != m->lastRecordNum + 1 && !m->clearingBuffers)
|
||||
emit LogSbieMessage(1242, QStringList() << "" << "" << "", GetCurrentProcessId()); // Monitor buffer overflow
|
||||
emit LogSbieMessage(0xC1020000 | 1242, QStringList() << "" << "" << "", GetCurrentProcessId()); // Monitor buffer overflow
|
||||
m->lastRecordNum = RecordNum;
|
||||
|
||||
if (m->clearingBuffers)
|
||||
|
@ -1926,6 +1959,22 @@ QString CSbieAPI::GetSbieMsgStr(quint32 code, quint32 Lang)
|
|||
//
|
||||
//
|
||||
|
||||
QString ErrorString(qint32 err)
|
||||
{
|
||||
QString Error;
|
||||
HMODULE handle = NULL; //err < 0 ? GetModuleHandle(L"NTDLL.DLL") : NULL;
|
||||
DWORD flags = 0; //err < 0 ? FORMAT_MESSAGE_FROM_HMODULE : 0;
|
||||
LPTSTR s;
|
||||
if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | flags, handle, err, 0, (LPTSTR)&s, 0, NULL) > 0)
|
||||
{
|
||||
LPTSTR p = wcschr(s, L'\r');
|
||||
if (p != NULL) *p = L'\0';
|
||||
Error = QString::fromWCharArray(s);
|
||||
::LocalFree(s);
|
||||
}
|
||||
return Error;
|
||||
}
|
||||
|
||||
CResLogEntry::CResLogEntry(quint32 ProcessId, quint32 Type, const QString& Value)
|
||||
{
|
||||
m_ProcessId = ProcessId;
|
||||
|
@ -1935,6 +1984,19 @@ CResLogEntry::CResLogEntry(quint32 ProcessId, quint32 Type, const QString& Value
|
|||
m_TimeStamp = QDateTime::currentDateTime(); // ms resolution
|
||||
m_Counter = 0;
|
||||
|
||||
// if this is a set error, then get the actual error string
|
||||
if (m_Type.Type == MONITOR_OTHER && Value.indexOf("SetError:") == 0)
|
||||
{
|
||||
auto tmp = Value.split(":");
|
||||
if (tmp.length() >= 2)
|
||||
{
|
||||
qint32 errCode = tmp[1].trimmed().toInt();
|
||||
QString Error = ErrorString(errCode);
|
||||
if(!Error.isEmpty())
|
||||
m_Name += " (" + Error + ")";
|
||||
}
|
||||
}
|
||||
|
||||
static atomic<quint64> uid = 0;
|
||||
m_uid = uid.fetch_add(1);
|
||||
}
|
||||
|
@ -1943,6 +2005,7 @@ QString CResLogEntry::GetTypeStr() const
|
|||
{
|
||||
switch (m_Type.Type)
|
||||
{
|
||||
case MONITOR_SYSCALL: return "SysCall";
|
||||
case MONITOR_PIPE: return "Pipe";
|
||||
case MONITOR_IPC: return "Ipc";
|
||||
case MONITOR_WINCLASS: return "WinClass";
|
||||
|
@ -1950,7 +2013,8 @@ QString CResLogEntry::GetTypeStr() const
|
|||
case MONITOR_COMCLASS: return "ComClass";
|
||||
case MONITOR_IGNORE: return "Ignore";
|
||||
case MONITOR_IMAGE: return "Image";
|
||||
case MONITOR_FILE_OR_KEY: return "File/Key";
|
||||
case MONITOR_FILE: return "File";
|
||||
case MONITOR_KEY: return "Key";
|
||||
case MONITOR_OTHER: return "Debug";
|
||||
default: return "Unknown: " + QString::number(m_Type.Type);
|
||||
}
|
||||
|
@ -1958,14 +2022,19 @@ QString CResLogEntry::GetTypeStr() const
|
|||
|
||||
QString CResLogEntry::GetStautsStr() const
|
||||
{
|
||||
if (m_Type.Trace)
|
||||
return "Trace";
|
||||
QString Status;
|
||||
if (m_Type.Open)
|
||||
Status.append("Open ");
|
||||
if (m_Type.Deny)
|
||||
Status.append("Closed ");
|
||||
|
||||
if(m_Type.Open)
|
||||
return "Open";
|
||||
if(m_Type.Deny)
|
||||
return "Closed";
|
||||
return "";
|
||||
if (m_Type.Trace)
|
||||
Status.append("Trace ");
|
||||
|
||||
if (m_Counter > 1)
|
||||
Status.append(QString("(%1)").arg(m_Counter));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
|
||||
virtual QString GetBoxedPath(const QString& BoxName, const QString& Path);
|
||||
virtual QString GetBoxedPath(const CSandBoxPtr& pBox, const QString& Path);
|
||||
virtual QString GetRealPath(const CSandBoxPtr& pBox, const QString& Path);
|
||||
|
||||
enum ESetMode
|
||||
{
|
||||
|
|
|
@ -37,7 +37,8 @@ enum ESbieMsgCodes
|
|||
SB_SnapDelRegFail,
|
||||
SB_NotAuthorized,
|
||||
SB_ConfigFailed,
|
||||
|
||||
SB_SnapIsEmpty,
|
||||
SB_NameExists,
|
||||
};
|
||||
|
||||
class CSbieStatus
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<enum>QTabWidget::West</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>8</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabGeneral">
|
||||
<attribute name="title">
|
||||
|
@ -1770,8 +1770,8 @@ instead of "*".</string>
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<height>28</height>
|
||||
<width>530</width>
|
||||
<height>312</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="dbgLayout">
|
||||
|
@ -1960,6 +1960,112 @@ instead of "*".</string>
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>tabs</tabstop>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>cmbBoxIndicator</tabstop>
|
||||
<tabstop>cmbBoxBorder</tabstop>
|
||||
<tabstop>btnBorderColor</tabstop>
|
||||
<tabstop>spinBorderWidth</tabstop>
|
||||
<tabstop>chkBlockNetShare</tabstop>
|
||||
<tabstop>chkBlockNetParam</tabstop>
|
||||
<tabstop>chkDropRights</tabstop>
|
||||
<tabstop>chkBlockSpooler</tabstop>
|
||||
<tabstop>chkOpenSpooler</tabstop>
|
||||
<tabstop>chkPrintToFile</tabstop>
|
||||
<tabstop>treeRun</tabstop>
|
||||
<tabstop>btnAddCmd</tabstop>
|
||||
<tabstop>btnDelCmd</tabstop>
|
||||
<tabstop>chkCopyLimit</tabstop>
|
||||
<tabstop>txtCopyLimit</tabstop>
|
||||
<tabstop>chkNoCopyWarn</tabstop>
|
||||
<tabstop>chkAutoEmpty</tabstop>
|
||||
<tabstop>chkProtectBox</tabstop>
|
||||
<tabstop>treeAutoStart</tabstop>
|
||||
<tabstop>btnAddAutoExe</tabstop>
|
||||
<tabstop>btnAddAutoSvc</tabstop>
|
||||
<tabstop>btnDelAuto</tabstop>
|
||||
<tabstop>treeGroups</tabstop>
|
||||
<tabstop>btnAddGroup</tabstop>
|
||||
<tabstop>btnAddProg</tabstop>
|
||||
<tabstop>btnDelProg</tabstop>
|
||||
<tabstop>treeForced</tabstop>
|
||||
<tabstop>btnForceProg</tabstop>
|
||||
<tabstop>btnForceDir</tabstop>
|
||||
<tabstop>chkShowForceTmpl</tabstop>
|
||||
<tabstop>btnDelForce</tabstop>
|
||||
<tabstop>treeStop</tabstop>
|
||||
<tabstop>btnAddLingering</tabstop>
|
||||
<tabstop>btnAddLeader</tabstop>
|
||||
<tabstop>chkShowStopTmpl</tabstop>
|
||||
<tabstop>btnDelStopProg</tabstop>
|
||||
<tabstop>radStartAll</tabstop>
|
||||
<tabstop>radStartExcept</tabstop>
|
||||
<tabstop>radStartSelected</tabstop>
|
||||
<tabstop>treeStart</tabstop>
|
||||
<tabstop>btnAddStartProg</tabstop>
|
||||
<tabstop>btnDelStartProg</tabstop>
|
||||
<tabstop>chkStartBlockMsg</tabstop>
|
||||
<tabstop>chkBlockINet</tabstop>
|
||||
<tabstop>chkINetBlockPrompt</tabstop>
|
||||
<tabstop>treeINet</tabstop>
|
||||
<tabstop>btnAddINetProg</tabstop>
|
||||
<tabstop>btnDelINetProg</tabstop>
|
||||
<tabstop>chkINetBlockMsg</tabstop>
|
||||
<tabstop>treeAccess</tabstop>
|
||||
<tabstop>btnAddFile</tabstop>
|
||||
<tabstop>btnAddKey</tabstop>
|
||||
<tabstop>btnAddIPC</tabstop>
|
||||
<tabstop>btnAddWnd</tabstop>
|
||||
<tabstop>btnAddCOM</tabstop>
|
||||
<tabstop>btnMoveUp</tabstop>
|
||||
<tabstop>btnMoveDown</tabstop>
|
||||
<tabstop>chkShowAccessTmpl</tabstop>
|
||||
<tabstop>btnDelAccess</tabstop>
|
||||
<tabstop>chkAutoRecovery</tabstop>
|
||||
<tabstop>treeRecovery</tabstop>
|
||||
<tabstop>btnAddRecovery</tabstop>
|
||||
<tabstop>btnAddRecIgnore</tabstop>
|
||||
<tabstop>btnAddRecIgnoreExt</tabstop>
|
||||
<tabstop>chkShowRecoveryTmpl</tabstop>
|
||||
<tabstop>btnDelRecovery</tabstop>
|
||||
<tabstop>tabsAdvanced</tabstop>
|
||||
<tabstop>chkPreferExternalManifest</tabstop>
|
||||
<tabstop>chkNoWindowRename</tabstop>
|
||||
<tabstop>chkAddToJob</tabstop>
|
||||
<tabstop>chkRestrictServices</tabstop>
|
||||
<tabstop>chkProtectSCM</tabstop>
|
||||
<tabstop>chkProtectSystem</tabstop>
|
||||
<tabstop>chkOpenProtectedStorage</tabstop>
|
||||
<tabstop>chkOpenCredentials</tabstop>
|
||||
<tabstop>chkOpenSmartCard</tabstop>
|
||||
<tabstop>lstAutoExec</tabstop>
|
||||
<tabstop>btnAddAutoExec</tabstop>
|
||||
<tabstop>btnDelAutoExec</tabstop>
|
||||
<tabstop>chkHideOtherBoxes</tabstop>
|
||||
<tabstop>lstProcesses</tabstop>
|
||||
<tabstop>btnAddProcess</tabstop>
|
||||
<tabstop>btnDelProcess</tabstop>
|
||||
<tabstop>lstUsers</tabstop>
|
||||
<tabstop>btnAddUser</tabstop>
|
||||
<tabstop>btnDelUser</tabstop>
|
||||
<tabstop>chkMonitorAdminOnly</tabstop>
|
||||
<tabstop>chkFileTrace</tabstop>
|
||||
<tabstop>chkPipeTrace</tabstop>
|
||||
<tabstop>chkKeyTrace</tabstop>
|
||||
<tabstop>chkIpcTrace</tabstop>
|
||||
<tabstop>chkGuiTrace</tabstop>
|
||||
<tabstop>chkComTrace</tabstop>
|
||||
<tabstop>chkDbgTrace</tabstop>
|
||||
<tabstop>scrollArea</tabstop>
|
||||
<tabstop>treeTemplates</tabstop>
|
||||
<tabstop>cmbCategories</tabstop>
|
||||
<tabstop>txtTemplates</tabstop>
|
||||
<tabstop>btnEditIni</tabstop>
|
||||
<tabstop>txtIniSection</tabstop>
|
||||
<tabstop>btnSaveIni</tabstop>
|
||||
<tabstop>btnCancelEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -36,80 +36,90 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="5" column="1">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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="5" column="3">
|
||||
<widget class="QPushButton" name="btnClose">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="btnRecoverTo">
|
||||
<property name="text">
|
||||
<string>Recover to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="btnAddFolder">
|
||||
<property name="text">
|
||||
<string>Add Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeView" name="treeFiles"/>
|
||||
<widget class="QPushButton" name="btnRecover">
|
||||
<property name="text">
|
||||
<string>Recover</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnAddFolder">
|
||||
<property name="text">
|
||||
<string>Add Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnRefresh">
|
||||
<property name="text">
|
||||
<string>Refresh</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
<widget class="QPushButton" name="btnRecover">
|
||||
<property name="text">
|
||||
<string>Recover</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnRecoverTo">
|
||||
<property name="text">
|
||||
<string>Recover to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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>
|
||||
<widget class="QPushButton" name="btnDeleteAll">
|
||||
<property name="text">
|
||||
<string>Delete all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btnClose">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<spacer name="verticalSpacer">
|
||||
<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="5" column="0">
|
||||
<widget class="QPushButton" name="btnRefresh">
|
||||
<property name="text">
|
||||
<string>Refresh</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QPushButton" name="btnDeleteAll">
|
||||
<property name="text">
|
||||
<string>Delete all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="chkShowAll">
|
||||
<property name="text">
|
||||
<string>Show All Files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="4" colspan="3">
|
||||
<widget class="QTreeView" name="treeFiles"/>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="3">
|
||||
<widget class="QLabel" name="lblInfo">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
@ -117,6 +127,16 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>btnAddFolder</tabstop>
|
||||
<tabstop>btnRecover</tabstop>
|
||||
<tabstop>btnRecoverTo</tabstop>
|
||||
<tabstop>treeFiles</tabstop>
|
||||
<tabstop>chkShowAll</tabstop>
|
||||
<tabstop>btnRefresh</tabstop>
|
||||
<tabstop>btnDeleteAll</tabstop>
|
||||
<tabstop>btnClose</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>573</width>
|
||||
<width>576</width>
|
||||
<height>451</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -45,7 +45,7 @@
|
|||
<enum>QTabWidget::North</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabGeneral">
|
||||
<attribute name="title">
|
||||
|
@ -54,20 +54,7 @@
|
|||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkNotifications">
|
||||
<property name="text">
|
||||
<string>Show Notifications for relevant log Messages</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="uiLang"/>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
@ -80,32 +67,18 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkAutoUpdate">
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkNotifications">
|
||||
<property name="text">
|
||||
<string>Check periodically for updates of Sandboxie-Plus</string>
|
||||
<string>Show Notifications for relevant log Messages</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>On main window close:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="chkAutoStart">
|
||||
<property name="text">
|
||||
<string>Start with Windows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QComboBox" name="onClose"/>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="uiLang"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="chkDarkTheme">
|
||||
|
@ -114,57 +87,31 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkShellMenu">
|
||||
<property name="text">
|
||||
<string>Add 'Run Sandboxed' to the explorer context menu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="chkShowTray">
|
||||
<property name="text">
|
||||
<string>Show Sys-Tray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<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="8" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<item row="7" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkSandboxUrls">
|
||||
<property name="text">
|
||||
<string>Tray options</string>
|
||||
<string>Open urls from this ui sandboxed</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkAutoUpdate">
|
||||
<property name="text">
|
||||
<string>Restart required (!)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
<string>Check periodically for updates of Sandboxie-Plus</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="12" column="0">
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
@ -177,20 +124,80 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkSandboxUrls">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Open urls from this ui sandboxed</string>
|
||||
<string>Restart required (!)</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="chkWatchConfig">
|
||||
<item row="11" column="1">
|
||||
<widget class="QComboBox" name="onClose"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="chkAutoStart">
|
||||
<property name="text">
|
||||
<string>Watch Sandboxie.ini for changes</string>
|
||||
<string>Start UI with Windows</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkShellMenu">
|
||||
<property name="text">
|
||||
<string>Add 'Run Sandboxed' to the explorer context menu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>On main window close:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<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="9" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tray options</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkSvcStart">
|
||||
<property name="text">
|
||||
<string>Start UI when a sandboxed process is started</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkShowRecovery">
|
||||
<property name="text">
|
||||
<string>Show first recovery window when emptying sandboxes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -205,21 +212,10 @@
|
|||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="chkAdminOnlyFP">
|
||||
<property name="text">
|
||||
<string>Only Administrator user accounts can use Disable Forced Programs command</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="1" column="2" colspan="4">
|
||||
<widget class="QLineEdit" name="fileRoot"/>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="chkAdminOnly">
|
||||
<property name="text">
|
||||
<string>Only Administrator user accounts can make changes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_44">
|
||||
<property name="font">
|
||||
<font>
|
||||
|
@ -232,25 +228,87 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="chkPassRequired">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Password must be entered in order to make changes</string>
|
||||
<string>Sandbox <a href="sbie://docs/ipcrootpath">ipc root</a>: </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="7" column="2">
|
||||
<widget class="QPushButton" name="btnSetPassword">
|
||||
<item row="12" 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="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">
|
||||
<string>Change Password</string>
|
||||
<string>Sandbox <a href="sbie://docs/keyrootpath">registry root</a>: </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="1" colspan="2">
|
||||
<widget class="QLineEdit" name="fileRoot"/>
|
||||
<item row="4" column="2" colspan="4">
|
||||
<widget class="QLineEdit" name="ipcRoot"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<item row="11" column="1" colspan="5">
|
||||
<widget class="QCheckBox" name="chkClearPass">
|
||||
<property name="text">
|
||||
<string>Clear password when main window becomes hidden</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="5">
|
||||
<widget class="QCheckBox" name="chkAdminOnlyFP">
|
||||
<property name="text">
|
||||
<string>Only Administrator user accounts can use Disable Forced Programs command</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Sandbox <a href="sbie://docs/filerootpath">file system root</a>: </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="2">
|
||||
<widget class="QCheckBox" name="chkSeparateUserFolders">
|
||||
<property name="text">
|
||||
<string>Separate user folders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -262,8 +320,72 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="regRoot"/>
|
||||
<item row="8" column="1" colspan="5">
|
||||
<widget class="QCheckBox" name="chkAdminOnly">
|
||||
<property name="text">
|
||||
<string>Only Administrator user accounts can make changes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="chkPassRequired">
|
||||
<property name="text">
|
||||
<string>Password must be entered in order to make changes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="5">
|
||||
<widget class="QPushButton" name="btnSetPassword">
|
||||
<property name="text">
|
||||
<string>Change Password</string>
|
||||
</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="1" column="6">
|
||||
<widget class="QPushButton" name="btnBrowse">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>23</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" 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="12" column="4">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<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">
|
||||
|
@ -278,105 +400,23 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_45">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<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">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Sandbox <a href="sbie://docs/filerootpath">file system root</a>: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
<string>Other settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<item row="6" column="1" colspan="5">
|
||||
<widget class="QCheckBox" name="chkWatchConfig">
|
||||
<property name="text">
|
||||
<string>Sandbox <a href="sbie://docs/ipcrootpath">ipc root</a>: </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="1" colspan="2">
|
||||
<widget class="QLineEdit" name="ipcRoot"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Sandbox <a href="sbie://docs/keyrootpath">registry root</a>: </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="10" column="1">
|
||||
<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="9" column="1">
|
||||
<widget class="QCheckBox" name="chkClearPass">
|
||||
<property name="text">
|
||||
<string>Clear password when main window becomes hidden</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="chkSeparateUserFolders">
|
||||
<property name="text">
|
||||
<string>Separate user folders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QCheckBox" name="chkAutoRoot">
|
||||
<property name="text">
|
||||
<string>Portable root folder</string>
|
||||
<string>Watch Sandboxie.ini for changes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -544,6 +584,42 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>tabs</tabstop>
|
||||
<tabstop>uiLang</tabstop>
|
||||
<tabstop>chkDarkTheme</tabstop>
|
||||
<tabstop>chkAutoStart</tabstop>
|
||||
<tabstop>chkSvcStart</tabstop>
|
||||
<tabstop>chkAutoUpdate</tabstop>
|
||||
<tabstop>chkShellMenu</tabstop>
|
||||
<tabstop>chkNotifications</tabstop>
|
||||
<tabstop>chkSandboxUrls</tabstop>
|
||||
<tabstop>chkShowRecovery</tabstop>
|
||||
<tabstop>chkShowTray</tabstop>
|
||||
<tabstop>onClose</tabstop>
|
||||
<tabstop>fileRoot</tabstop>
|
||||
<tabstop>btnBrowse</tabstop>
|
||||
<tabstop>chkSeparateUserFolders</tabstop>
|
||||
<tabstop>chkAutoRoot</tabstop>
|
||||
<tabstop>regRoot</tabstop>
|
||||
<tabstop>ipcRoot</tabstop>
|
||||
<tabstop>chkWatchConfig</tabstop>
|
||||
<tabstop>chkAdminOnly</tabstop>
|
||||
<tabstop>chkPassRequired</tabstop>
|
||||
<tabstop>btnSetPassword</tabstop>
|
||||
<tabstop>chkAdminOnlyFP</tabstop>
|
||||
<tabstop>chkClearPass</tabstop>
|
||||
<tabstop>chkStartBlock</tabstop>
|
||||
<tabstop>treeWarnProgs</tabstop>
|
||||
<tabstop>btnAddWarnProg</tabstop>
|
||||
<tabstop>btnAddWarnFolder</tabstop>
|
||||
<tabstop>btnDelWarnProg</tabstop>
|
||||
<tabstop>chkStartBlockMsg</tabstop>
|
||||
<tabstop>treeCompat</tabstop>
|
||||
<tabstop>btnAddCompat</tabstop>
|
||||
<tabstop>btnDelCompat</tabstop>
|
||||
<tabstop>chkNoCompat</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -38,8 +38,26 @@
|
|||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Ignored">
|
||||
<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="title">
|
||||
<string>Snapshot Details</string>
|
||||
<string>Selected Snapshot Details</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
|
@ -65,31 +83,59 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="txtName"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>125</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Snapshot Actions</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="btnRemove">
|
||||
<property name="text">
|
||||
<string>Remove Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="btnTake">
|
||||
<property name="text">
|
||||
<string>Take Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="btnSelect">
|
||||
<property name="text">
|
||||
<string>Go to Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="btnTake">
|
||||
<property name="text">
|
||||
<string>Take Snapshot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QTreeView" name="treeSnapshots"/>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -98,6 +144,14 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>btnTake</tabstop>
|
||||
<tabstop>treeSnapshots</tabstop>
|
||||
<tabstop>btnSelect</tabstop>
|
||||
<tabstop>btnRemove</tabstop>
|
||||
<tabstop>txtName</tabstop>
|
||||
<tabstop>txtInfo</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
Copyright 2020 – 2021 David Xanatos (xanasoft.com)
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -113,6 +113,8 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion());
|
||||
this->setWindowTitle(appTitle);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
m_pBoxBorder = new CBoxBorder(theAPI, this);
|
||||
|
||||
m_SbieTemplates = new CSbieTemplates(theAPI, this);
|
||||
|
@ -250,6 +252,10 @@ CSandMan::CSandMan(QWidget *parent)
|
|||
pAction->setChecked(pAction->data().toBool() == bAdvanced);
|
||||
SetViewMode(bAdvanced);
|
||||
|
||||
bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false);
|
||||
m_pWndTopMost->setChecked(bAlwaysOnTop);
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
|
||||
|
||||
m_pKeepTerminated->setChecked(theConf->GetBool("Options/KeepTerminated"));
|
||||
|
||||
m_pProgressDialog = new CProgressDialog("", this);
|
||||
|
@ -372,6 +378,11 @@ void CSandMan::CreateMenus()
|
|||
MakeAction(m_pViewMode, m_pMenuView, tr("Simple View"), false);
|
||||
MakeAction(m_pViewMode, m_pMenuView, tr("Advanced View"), true);
|
||||
connect(m_pViewMode, SIGNAL(triggered(QAction*)), this, SLOT(OnViewMode(QAction*)));
|
||||
|
||||
m_pMenuView->addSeparator();
|
||||
m_pWndTopMost = m_pMenuView->addAction(tr("Always on Top"), this, SLOT(OnAlwaysTop()));
|
||||
m_pWndTopMost->setCheckable(true);
|
||||
|
||||
m_iMenuViewPos = m_pMenuView->actions().count();
|
||||
m_pMenuView->addSeparator();
|
||||
|
||||
|
@ -466,7 +477,7 @@ void CSandMan::OnExit()
|
|||
|
||||
void CSandMan::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
if (!m_bExit)
|
||||
if (!m_bExit)// && !theAPI->IsConnected())
|
||||
{
|
||||
QString OnClose = theConf->GetString("Options/OnClose", "ToTray");
|
||||
if (m_pTrayIcon->isVisible() && OnClose.compare("ToTray", Qt::CaseInsensitive) == 0)
|
||||
|
@ -550,8 +561,12 @@ void CSandMan::OnMessage(const QString& Message)
|
|||
else
|
||||
{
|
||||
OnLogMessage(tr("Maintenance operation Successful"));
|
||||
if (m_bConnectPending)
|
||||
ConnectSbieImpl();
|
||||
if (m_bConnectPending) {
|
||||
|
||||
QTimer::singleShot(1000, [this]() {
|
||||
this->ConnectSbieImpl();
|
||||
});
|
||||
}
|
||||
}
|
||||
m_pProgressDialog->hide();
|
||||
m_bConnectPending = false;
|
||||
|
@ -559,6 +574,29 @@ void CSandMan::OnMessage(const QString& Message)
|
|||
}
|
||||
}
|
||||
|
||||
void CSandMan::dragEnterEvent(QDragEnterEvent* e)
|
||||
{
|
||||
if (e->mimeData()->hasUrls()) {
|
||||
e->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::dropEvent(QDropEvent* e)
|
||||
{
|
||||
bool ok;
|
||||
QString box = QInputDialog::getItem(this, "Sandboxie-Plus", tr("Select box:"), theAPI->GetAllBoxes().keys(), 0, false, &ok);
|
||||
if (!ok || box.isEmpty())
|
||||
return;
|
||||
|
||||
foreach(const QUrl & url, e->mimeData()->urls()) {
|
||||
if (!url.isLocalFile())
|
||||
continue;
|
||||
QString FileName = url.toLocalFile().replace("/", "\\");
|
||||
|
||||
theAPI->RunStart(box, FileName);
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::timerEvent(QTimerEvent* pEvent)
|
||||
{
|
||||
if (pEvent->timerId() != m_uTimerID)
|
||||
|
@ -566,7 +604,13 @@ void CSandMan::timerEvent(QTimerEvent* pEvent)
|
|||
|
||||
if (theAPI->IsConnected())
|
||||
{
|
||||
theAPI->ReloadBoxes();
|
||||
SB_STATUS Status = theAPI->ReloadBoxes();
|
||||
|
||||
if (!Status.IsError() && theAPI->GetAllBoxes().count() == 0) {
|
||||
OnLogMessage(tr("No sandboxes found; creating: %1").arg("DefaultBox"));
|
||||
theAPI->CreateBox("DefaultBox");
|
||||
}
|
||||
|
||||
theAPI->UpdateProcesses(m_pKeepTerminated->isChecked());
|
||||
|
||||
m_pDisableForce->setChecked(theAPI->AreForceProcessDisabled());
|
||||
|
@ -633,6 +677,41 @@ void CSandMan::timerEvent(QTimerEvent* pEvent)
|
|||
m_RequestManager->AbortAll();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_MissingTemplates.isEmpty())
|
||||
{
|
||||
if (m_MissingTemplates[0] == "") {
|
||||
m_MissingTemplates.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
int CleanupTemplates = theConf->GetInt("Options/AutoCleanupTemplates", -1);
|
||||
if (CleanupTemplates == -1)
|
||||
{
|
||||
bool State = false;
|
||||
CleanupTemplates = CCheckableMessageBox::question(this, "Sandboxie-Plus", tr("Some compatibility templates (%1) are missing, probably deleted, do you want to remove them from all boxes?")
|
||||
.arg(m_MissingTemplates.join(", "))
|
||||
, tr("Don't show this message again."), &State, QDialogButtonBox::Yes | QDialogButtonBox::No, QDialogButtonBox::Yes, QMessageBox::Information) == QDialogButtonBox::Yes ? 1 : 0;
|
||||
|
||||
if (State)
|
||||
theConf->SetValue("Options/AutoCleanupTemplates", CleanupTemplates);
|
||||
}
|
||||
|
||||
if (CleanupTemplates)
|
||||
{
|
||||
foreach(const QString& Template, m_MissingTemplates)
|
||||
{
|
||||
theAPI->GetGlobalSettings()->DelValue("Template", Template);
|
||||
foreach(const CSandBoxPtr& pBox, theAPI->GetAllBoxes())
|
||||
pBox->DelValue("Template", Template);
|
||||
}
|
||||
|
||||
OnLogMessage(tr("Cleaned up removed templates..."));
|
||||
}
|
||||
m_MissingTemplates.clear();
|
||||
|
||||
m_MissingTemplates.append("");
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::OnBoxClosed(const QString& BoxName)
|
||||
|
@ -641,7 +720,7 @@ void CSandMan::OnBoxClosed(const QString& BoxName)
|
|||
if (!pBox)
|
||||
return;
|
||||
|
||||
if (!pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false))
|
||||
if (!pBox->GetBool("NeverDelete", false) && pBox->GetBool("AutoDelete", false) && !pBox->IsEmpty())
|
||||
{
|
||||
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(pBox, this);
|
||||
if (pRecoveryWindow->FindFiles() == 0)
|
||||
|
@ -685,7 +764,8 @@ void CSandMan::OnStatusChanged()
|
|||
QString appTitle = tr("Sandboxie-Plus v%1").arg(GetVersion());
|
||||
if (isConnected)
|
||||
{
|
||||
OnLogMessage(tr("Sbie Directory: %1").arg(theAPI->GetSbiePath()));
|
||||
QString SbiePath = theAPI->GetSbiePath();
|
||||
OnLogMessage(tr("Sbie Directory: %1").arg(SbiePath));
|
||||
OnLogMessage(tr("Loaded Config: %1").arg(theAPI->GetIniPath()));
|
||||
|
||||
statusBar()->showMessage(tr("Driver version: %1").arg(theAPI->GetVersion()));
|
||||
|
@ -723,6 +803,12 @@ void CSandMan::OnStatusChanged()
|
|||
}
|
||||
}
|
||||
|
||||
if (SbiePath.compare(QApplication::applicationDirPath().replace("/", "\\"), Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
if (theAPI->GetUserSettings()->GetText("SbieCtrl_AutoStartAgent").isEmpty())
|
||||
theAPI->GetUserSettings()->SetText("SbieCtrl_AutoStartAgent", "SandMan.exe");
|
||||
}
|
||||
|
||||
m_pBoxView->Clear();
|
||||
|
||||
OnIniReloaded();
|
||||
|
@ -811,6 +897,12 @@ void CSandMan::OnLogSbieMessage(quint32 MsgCode, const QStringList& MsgData, qui
|
|||
return;
|
||||
}
|
||||
|
||||
if ((MsgCode & 0xFFFF) == 1411) // removed/missing template
|
||||
{
|
||||
if(MsgData.size() >= 3 && !m_MissingTemplates.contains(MsgData[2]))
|
||||
m_MissingTemplates.append(MsgData[2]);
|
||||
}
|
||||
|
||||
QString Message = MsgCode != 0 ? theAPI->GetSbieMsgStr(MsgCode, m_LanguageId) : (MsgData.size() > 0 ? MsgData[0] : QString());
|
||||
|
||||
for (int i = 1; i < MsgData.size(); i++)
|
||||
|
@ -1030,17 +1122,9 @@ SB_STATUS CSandMan::ConnectSbieImpl()
|
|||
if (Status && !CSbieAPI::IsSbieCtrlRunning()) // don't take over when SbieCtrl is up and running
|
||||
Status = theAPI->TakeOver();
|
||||
|
||||
if (Status)
|
||||
Status = theAPI->ReloadBoxes();
|
||||
|
||||
if (!Status)
|
||||
return Status;
|
||||
|
||||
if (theAPI->GetAllBoxes().count() == 0) {
|
||||
OnLogMessage(tr("No sandboxes found; creating: %1").arg("DefaultBox"));
|
||||
theAPI->CreateBox("DefaultBox");
|
||||
}
|
||||
|
||||
bool bIsMonitoring = theAPI->IsMonitoring();
|
||||
m_pResourceLog->setEnabled(bIsMonitoring);
|
||||
m_pEnableMonitoring->setChecked(bIsMonitoring);
|
||||
|
@ -1118,6 +1202,14 @@ void CSandMan::OnViewMode(QAction* pAction)
|
|||
SetViewMode(bAdvanced);
|
||||
}
|
||||
|
||||
void CSandMan::OnAlwaysTop()
|
||||
{
|
||||
bool bAlwaysOnTop = m_pWndTopMost->isChecked();
|
||||
theConf->SetValue("Options/AlwaysOnTop", bAlwaysOnTop);
|
||||
this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop);
|
||||
this->show(); // why is this needed?
|
||||
}
|
||||
|
||||
void CSandMan::SetViewMode(bool bAdvanced)
|
||||
{
|
||||
if (bAdvanced)
|
||||
|
@ -1179,9 +1271,16 @@ void CSandMan::OnSetKeep()
|
|||
|
||||
void CSandMan::OnSettings()
|
||||
{
|
||||
CSettingsWindow* pSettingsWindow = new CSettingsWindow(this);
|
||||
connect(pSettingsWindow, SIGNAL(OptionsChanged()), this, SLOT(UpdateSettings()));
|
||||
pSettingsWindow->show();
|
||||
static CSettingsWindow* pSettingsWindow = NULL;
|
||||
if (pSettingsWindow == NULL)
|
||||
{
|
||||
pSettingsWindow = new CSettingsWindow(this);
|
||||
connect(pSettingsWindow, SIGNAL(OptionsChanged()), this, SLOT(UpdateSettings()));
|
||||
connect(pSettingsWindow, &CSettingsWindow::Closed, [this]() {
|
||||
pSettingsWindow = NULL;
|
||||
});
|
||||
pSettingsWindow->show();
|
||||
}
|
||||
}
|
||||
|
||||
void CSandMan::UpdateSettings()
|
||||
|
@ -1214,7 +1313,12 @@ void CSandMan::OnResetMsgs()
|
|||
theConf->SetValue("Options/NoEditInfo", true);
|
||||
theConf->SetValue("Options/ApiLogInfo", true);
|
||||
|
||||
theConf->SetValue("Options/BoxedExplorerInfo", true);
|
||||
theConf->SetValue("Options/ExplorerInfo", true);
|
||||
|
||||
theConf->SetValue("Options/OpenUrlsSandboxed", 2);
|
||||
|
||||
theConf->SetValue("Options/AutoCleanupTemplates", -1);
|
||||
}
|
||||
|
||||
theAPI->GetUserSettings()->UpdateTextList("SbieCtrl_HideMessage", QStringList(), true);
|
||||
|
@ -1410,7 +1514,8 @@ QString CSandMan::FormatError(const SB_STATUS& Error)
|
|||
case SB_SnapDelRegFail: Message = tr("Failed to remove old RegHive"); break;
|
||||
case SB_NotAuthorized: Message = tr("You are not authorized to update configuration in section '%1'"); break;
|
||||
case SB_ConfigFailed: Message = tr("Failed to set configuration setting %1 in section %2: %3"); break;
|
||||
|
||||
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;
|
||||
default: return tr("Unknown Error Status: %1").arg(Error.GetStatus());
|
||||
}
|
||||
|
||||
|
@ -1796,6 +1901,10 @@ void CSandMan::SetDarkTheme(bool bDark)
|
|||
palette.setColor(QPalette::Link, QColor(218, 130, 42));
|
||||
palette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||
palette.setColor(QPalette::HighlightedText, Qt::black);
|
||||
palette.setColor(QPalette::Disabled, QPalette::WindowText, Qt::darkGray);
|
||||
palette.setColor(QPalette::Disabled, QPalette::Text, Qt::darkGray);
|
||||
palette.setColor(QPalette::Disabled, QPalette::Light, Qt::black);
|
||||
palette.setColor(QPalette::Disabled, QPalette::ButtonText, Qt::darkGray);
|
||||
QApplication::setPalette(palette);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
#define VERSION_MJR 0
|
||||
#define VERSION_MIN 5
|
||||
#define VERSION_REV 4
|
||||
#define VERSION_UPD 2
|
||||
#define VERSION_REV 5
|
||||
#define VERSION_UPD 0
|
||||
|
||||
|
||||
//#include "../QSbieAPI/SbieAPI.h"
|
||||
|
@ -56,7 +56,11 @@ protected:
|
|||
|
||||
static void RecoverFilesAsync(const CSbieProgressPtr& pProgress, const QList<QPair<QString, QString>>& FileList, int Action = 0);
|
||||
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void closeEvent(QCloseEvent* e);
|
||||
|
||||
void dragEnterEvent(QDragEnterEvent* e);
|
||||
void dropEvent(QDropEvent* e);
|
||||
|
||||
void timerEvent(QTimerEvent* pEvent);
|
||||
int m_uTimerID;
|
||||
bool m_bConnectPending;
|
||||
|
@ -71,6 +75,8 @@ protected:
|
|||
CNetworkAccessManager* m_RequestManager;
|
||||
CSbieProgressPtr m_pUpdateProgress;
|
||||
|
||||
QStringList m_MissingTemplates;
|
||||
|
||||
public slots:
|
||||
void OnMessage(const QString&);
|
||||
|
||||
|
@ -114,6 +120,7 @@ private slots:
|
|||
void OnMaintenance();
|
||||
|
||||
void OnViewMode(QAction* action);
|
||||
void OnAlwaysTop();
|
||||
void OnCleanUp();
|
||||
void OnSetKeep();
|
||||
|
||||
|
@ -187,6 +194,7 @@ private:
|
|||
|
||||
QMenu* m_pMenuView;
|
||||
QActionGroup* m_pViewMode;
|
||||
QAction* m_pWndTopMost;
|
||||
int m_iMenuViewPos;
|
||||
QMenu* m_pCleanUpMenu;
|
||||
QAction* m_pCleanUpProcesses;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "../Windows/OptionsWindow.h"
|
||||
#include "../Windows/SnapshotsWindow.h"
|
||||
#include <QFileIconProvider>
|
||||
#include "../../MiscHelpers/Common/CheckableMessageBox.h"
|
||||
#include "../Windows/RecoveryWindow.h"
|
||||
|
||||
#include "qt_windows.h"
|
||||
#include "qwindowdefs_win.h"
|
||||
|
@ -32,6 +34,7 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
|
|||
|
||||
// SbieTree
|
||||
m_pSbieTree = new QTreeViewEx();
|
||||
m_pSbieTree->setExpandsOnDoubleClick(false);
|
||||
//m_pSbieTree->setItemDelegate(theGUI->GetItemDelegate());
|
||||
|
||||
m_pSbieTree->setModel(m_pSortProxy);
|
||||
|
@ -122,7 +125,13 @@ CSbieView::CSbieView(QWidget* parent) : CPanelView(parent)
|
|||
|
||||
QByteArray Columns = theConf->GetBlob("MainWindow/BoxTree_Columns");
|
||||
if (Columns.isEmpty())
|
||||
{
|
||||
m_pSbieTree->OnResetColumns();
|
||||
m_pSbieTree->setColumnWidth(0, 300);
|
||||
m_pSbieTree->setColumnWidth(1, 70);
|
||||
m_pSbieTree->setColumnWidth(2, 70);
|
||||
m_pSbieTree->setColumnWidth(3, 70);
|
||||
}
|
||||
else
|
||||
m_pSbieTree->restoreState(Columns);
|
||||
|
||||
|
@ -380,7 +389,7 @@ void CSbieView::OnGroupAction()
|
|||
}
|
||||
else if (Action == m_pDelGroupe)
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to remove the selected group(s)?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to remove the selected group(s)?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
foreach(const QModelIndex& Index, m_pSbieTree->selectedRows())
|
||||
|
@ -459,7 +468,20 @@ void CSbieView::OnSandBoxAction()
|
|||
else if (Action == m_pMenuRunMailer)
|
||||
Results.append(SandBoxes.first()->RunStart("mail_agent"));
|
||||
else if (Action == m_pMenuRunExplorer)
|
||||
{
|
||||
if (theConf->GetBool("Options/AdvancedView", true) == false && theConf->GetBool("Options/BoxedExplorerInfo", true))
|
||||
{
|
||||
bool State = false;
|
||||
CCheckableMessageBox::question(this, "Sandboxie-Plus",
|
||||
theAPI->GetSbieMsgStr(0x00000DCDL, theGUI->m_LanguageId) // MSG_3533
|
||||
, tr("Don't show this message again."), &State, QDialogButtonBox::Ok, QDialogButtonBox::Ok, QMessageBox::Information);
|
||||
|
||||
if (State)
|
||||
theConf->SetValue("Options/BoxedExplorerInfo", false);
|
||||
}
|
||||
|
||||
Results.append(SandBoxes.first()->RunStart("explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"));
|
||||
}
|
||||
else if (Action == m_pMenuRunCmd)
|
||||
Results.append(SandBoxes.first()->RunStart("cmd.exe"));
|
||||
else if (Action == m_pMenuPresetsLogApi)
|
||||
|
@ -472,13 +494,22 @@ void CSbieView::OnSandBoxAction()
|
|||
SandBoxes.first().objectCast<CSandBoxPlus>()->SetDropRights(m_pMenuPresetsNoAdmin->isChecked());
|
||||
else if (Action == m_pMenuOptions)
|
||||
{
|
||||
COptionsWindow* pOptionsWindow = new COptionsWindow(SandBoxes.first(), SandBoxes.first()->GetName(), this);
|
||||
pOptionsWindow->show();
|
||||
OnDoubleClicked(m_pSbieTree->selectedRows().first());
|
||||
}
|
||||
else if (Action == m_pMenuExplore)
|
||||
{
|
||||
if (theConf->GetBool("Options/AdvancedView", true) == false && theConf->GetBool("Options/ExplorerInfo", true))
|
||||
{
|
||||
bool State = false;
|
||||
CCheckableMessageBox::question(this, "Sandboxie-Plus",
|
||||
theAPI->GetSbieMsgStr(0x00000DCEL, theGUI->m_LanguageId) // MSG_3534
|
||||
, tr("Don't show this message again."), &State, QDialogButtonBox::Ok, QDialogButtonBox::Ok, QMessageBox::Information);
|
||||
|
||||
if (State)
|
||||
theConf->SetValue("Options/ExplorerInfo", false);
|
||||
}
|
||||
|
||||
::ShellExecute(NULL, NULL, SandBoxes.first()->GetFileRoot().toStdWString().c_str(), NULL, NULL, SW_SHOWNORMAL);
|
||||
// if (ret <= 32) error
|
||||
}
|
||||
else if (Action == m_pMenuSnapshots)
|
||||
{
|
||||
|
@ -507,17 +538,34 @@ void CSbieView::OnSandBoxAction()
|
|||
}
|
||||
else if (Action == m_pMenuCleanUp)
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the content of the selected sandbox(es)?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
if (SandBoxes.count() == 1)
|
||||
{
|
||||
if (SandBoxes.first()->IsEmpty()) {
|
||||
QMessageBox("Sandboxie-Plus", tr("This Sandbox is already empty."), QMessageBox::Information, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton).exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if (theConf->GetBool("Options/ShowRecovery", false))
|
||||
{
|
||||
CRecoveryWindow* pRecoveryWindow = new CRecoveryWindow(SandBoxes.first(), this);
|
||||
pRecoveryWindow->FindFiles();
|
||||
if (pRecoveryWindow->exec() != 1)
|
||||
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).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
else if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the content of multiple sandboxes?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).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());
|
||||
else if(Status.IsError())
|
||||
else if (Status.IsError())
|
||||
Results.append(Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Action == m_pMenuEmptyBox)
|
||||
{
|
||||
|
@ -638,7 +686,7 @@ void CSbieView::OnProcessAction()
|
|||
{
|
||||
if (!pProcess.objectCast<CSbieProcess>()->GetBox()->IsINetBlocked())
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("This box does not have Internet restrictions in place, do you want to enable them?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
if (QMessageBox("Sandboxie-Plus", tr("This box does not have Internet restrictions in place, do you want to enable them?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
pProcess.objectCast<CSbieProcess>()->GetBox()->SetINetBlock(true);
|
||||
}
|
||||
|
@ -666,8 +714,16 @@ void CSbieView::OnDoubleClicked(const QModelIndex& index)
|
|||
if (pBox.isNull())
|
||||
return;
|
||||
|
||||
COptionsWindow* pOptionsWindow = new COptionsWindow(pBox, pBox->GetName(), this);
|
||||
pOptionsWindow->show();
|
||||
static QMap<void*, COptionsWindow*> OptionsWindows;
|
||||
if (!OptionsWindows.contains(pBox.data()))
|
||||
{
|
||||
COptionsWindow* pOptionsWindow = new COptionsWindow(pBox, pBox->GetName(), this);
|
||||
OptionsWindows.insert(pBox.data(), pOptionsWindow);
|
||||
connect(pOptionsWindow, &COptionsWindow::Closed, [this, pBox]() {
|
||||
OptionsWindows.remove(pBox.data());
|
||||
});
|
||||
pOptionsWindow->show();
|
||||
}
|
||||
}
|
||||
|
||||
void CSbieView::ProcessSelection(const QItemSelection& selected, const QItemSelection& deselected)
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
|
||||
COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QString& Name, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_pBox = pBox;
|
||||
|
||||
|
@ -53,9 +53,7 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
|
|||
if (!pBoxPlus.isNull())
|
||||
m_Programs = pBoxPlus->GetRecentPrograms();
|
||||
|
||||
QWidget* centralWidget = new QWidget();
|
||||
ui.setupUi(centralWidget);
|
||||
this->setCentralWidget(centralWidget);
|
||||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("Sandboxie Plus - '%1' Options").arg(Name));
|
||||
|
||||
ui.tabs->setTabPosition(QTabWidget::West);
|
||||
|
@ -294,9 +292,9 @@ COptionsWindow::COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QStri
|
|||
connect(ui.btnCancelEdit, SIGNAL(pressed()), this, SLOT(OnCancelEdit()));
|
||||
//
|
||||
|
||||
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(pressed()), this, SLOT(accept()));
|
||||
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(pressed()), this, SLOT(ok()));
|
||||
connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(pressed()), this, SLOT(apply()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
||||
|
||||
if (ReadOnly) {
|
||||
ui.btnEditIni->setEnabled(false);
|
||||
|
@ -351,6 +349,7 @@ COptionsWindow::~COptionsWindow()
|
|||
|
||||
void COptionsWindow::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
emit Closed();
|
||||
this->deleteLater();
|
||||
}
|
||||
|
||||
|
@ -358,9 +357,11 @@ bool COptionsWindow::eventFilter(QObject *source, QEvent *event)
|
|||
{
|
||||
if (event->type() == QEvent::KeyPress && ((QKeyEvent*)event)->key() == Qt::Key_Escape && ((QKeyEvent*)event)->modifiers() == Qt::NoModifier)
|
||||
CloseAccessEdit(false);
|
||||
if (source == ui.treeAccess->viewport() && event->type() == QEvent::MouseButtonPress)
|
||||
else if (source == ui.treeAccess->viewport() && event->type() == QEvent::MouseButtonPress)
|
||||
CloseAccessEdit();
|
||||
return QMainWindow::eventFilter(source, event);
|
||||
else
|
||||
return QDialog::eventFilter(source, event);
|
||||
return true;
|
||||
}
|
||||
|
||||
//void COptionsWindow::OnWithTemplates()
|
||||
|
@ -682,6 +683,11 @@ void COptionsWindow::SaveConfig()
|
|||
|
||||
void COptionsWindow::apply()
|
||||
{
|
||||
if (m_pBox->GetText("Enabled").isEmpty()) {
|
||||
QMessageBox::critical(this, "Sandboxie-Plus", tr("This sandbox has been deleted hence configuration can not be saved."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ui.btnEditIni->isEnabled())
|
||||
SaveIniSection();
|
||||
else
|
||||
|
@ -692,7 +698,7 @@ void COptionsWindow::apply()
|
|||
emit OptionsChanged();
|
||||
}
|
||||
|
||||
void COptionsWindow::accept()
|
||||
void COptionsWindow::ok()
|
||||
{
|
||||
apply();
|
||||
|
||||
|
@ -701,6 +707,23 @@ void COptionsWindow::accept()
|
|||
|
||||
void COptionsWindow::reject()
|
||||
{
|
||||
if (m_GeneralChanged
|
||||
|| m_GroupsChanged
|
||||
|| m_ForcedChanged
|
||||
|| m_StopChanged
|
||||
|| m_StartChanged
|
||||
// || m_RestrictionChanged
|
||||
|| m_INetBlockChanged
|
||||
|| m_AccessChanged
|
||||
|| m_TemplatesChanged
|
||||
|| m_RecoveryChanged
|
||||
|| m_AdvancedChanged)
|
||||
{
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Some changes haven't been saved yet, do you really want to close this options window?")
|
||||
, QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
@ -741,7 +764,7 @@ void COptionsWindow::OnAddAutoCmd()
|
|||
|
||||
void COptionsWindow::OnAddAutoExe()
|
||||
{
|
||||
QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe|*.cmd)")).replace("/", "\\");;
|
||||
QString Value = QFileDialog::getOpenFileName(this, tr("Select Program"), "", tr("Executables (*.exe *.cmd);;All files (*.*)")).replace("/", "\\");;
|
||||
if (Value.isEmpty())
|
||||
return;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "ui_OptionsWindow.h"
|
||||
#include "SbiePlusAPI.h"
|
||||
|
||||
class COptionsWindow : public QMainWindow
|
||||
class COptionsWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -12,13 +12,16 @@ public:
|
|||
COptionsWindow(const QSharedPointer<CSbieIni>& pBox, const QString& Name, QWidget *parent = Q_NULLPTR);
|
||||
~COptionsWindow();
|
||||
|
||||
virtual void accept() {}
|
||||
virtual void reject();
|
||||
|
||||
signals:
|
||||
void OptionsChanged();
|
||||
void Closed();
|
||||
|
||||
public slots:
|
||||
void ok();
|
||||
void apply();
|
||||
void accept();
|
||||
void reject();
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
|
@ -11,6 +11,15 @@ bool CPopUpWindow__DarkMode = false;
|
|||
|
||||
CPopUpWindow::CPopUpWindow(QWidget* parent) : QMainWindow(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);
|
||||
|
||||
this->setWindowTitle(tr("Sandboxie-Plus Notifications"));
|
||||
|
||||
QWidget* centralWidget = new QWidget();
|
||||
|
@ -232,7 +241,10 @@ void CPopUpWindow::AddUserPrompt(quint32 RequestId, const QVariantMap& Data, qui
|
|||
CPopUpPrompt* pEntry = new CPopUpPrompt(Message, RequestId, Result, pProcess, this);
|
||||
switch (pEntry->m_Result["id"].toInt())
|
||||
{
|
||||
case CSbieAPI::eInetBlockade: pEntry->m_pRemember->setChecked(true); break;
|
||||
case CSbieAPI::eInetBlockade:
|
||||
pEntry->AddAddToList();
|
||||
pEntry->m_pRemember->setChecked(true);
|
||||
break;
|
||||
}
|
||||
connect(pEntry, SIGNAL(PromptResult(int)), this, SLOT(OnPromptResult(int)));
|
||||
AddEntry(pEntry);
|
||||
|
@ -254,8 +266,14 @@ void CPopUpWindow::SendPromptResult(CPopUpPrompt* pEntry, int retval)
|
|||
{
|
||||
switch (pEntry->m_Result["id"].toInt())
|
||||
{
|
||||
case CSbieAPI::ePrintSpooler: theAPI->SetProcessExemption(pEntry->m_pProcess->GetProcessId(), 'splr', true); break;
|
||||
case CSbieAPI::eInetBlockade: theAPI->SetProcessExemption(pEntry->m_pProcess->GetProcessId(), 'inet', true); break;
|
||||
case CSbieAPI::ePrintSpooler:
|
||||
theAPI->SetProcessExemption(pEntry->m_pProcess->GetProcessId(), 'splr', true);
|
||||
break;
|
||||
case CSbieAPI::eInetBlockade:
|
||||
if (pEntry->m_bAddToList)
|
||||
pEntry->m_pProcess.objectCast<CSbieProcess>()->SetInternetAccess(true);
|
||||
theAPI->SetProcessExemption(pEntry->m_pProcess->GetProcessId(), 'inet', true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ public:
|
|||
m_RequestId = RequestId;
|
||||
m_Result = Result;
|
||||
m_pProcess = pProcess;
|
||||
m_bAddToList = false;
|
||||
|
||||
m_pLabel = new QLabel(Message);
|
||||
m_pLabel->setToolTip(Message);
|
||||
|
@ -132,10 +133,19 @@ public:
|
|||
killTimer(m_uTimerID);
|
||||
}
|
||||
|
||||
void AddAddToList()
|
||||
{
|
||||
m_pYes->setPopupMode(QToolButton::MenuButtonPopup);
|
||||
QMenu* pMenu = new QMenu();
|
||||
pMenu->addAction(tr("Yes and add to allowed programs"), this, SLOT(OnAcceptedAlways()));
|
||||
m_pYes->setMenu(pMenu);
|
||||
}
|
||||
|
||||
signals:
|
||||
void PromptResult(int retval);
|
||||
|
||||
private slots:
|
||||
void OnAcceptedAlways() { m_bAddToList = true; emit PromptResult(1); }
|
||||
void OnAccepted() { emit PromptResult(1); }
|
||||
void OnRejected() { emit PromptResult(0); }
|
||||
void OnTerminate() { emit PromptResult(-1); }
|
||||
|
@ -190,6 +200,7 @@ protected:
|
|||
quint32 m_RequestId;
|
||||
QVariantMap m_Result;
|
||||
CBoxedProcessPtr m_pProcess;
|
||||
bool m_bAddToList;
|
||||
|
||||
QLabel* m_pLabel;
|
||||
QCheckBox* m_pRemember;
|
||||
|
|
|
@ -15,10 +15,13 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
|
||||
m_pBox = pBox;
|
||||
|
||||
m_pCounter = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
QStyle* pStyle = QStyleFactory::create("windows");
|
||||
ui.treeFiles->setStyle(pStyle);
|
||||
#endif
|
||||
ui.treeFiles->setExpandsOnDoubleClick(false);
|
||||
|
||||
ui.btnDeleteAll->setVisible(false);
|
||||
|
||||
|
@ -44,6 +47,7 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
//connect(ui.treeFiles, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnSelectSnapshot()));
|
||||
|
||||
connect(ui.btnAddFolder, SIGNAL(pressed()), this, SLOT(OnAddFolder()));
|
||||
connect(ui.chkShowAll, SIGNAL(clicked(bool)), this, SLOT(FindFiles()));
|
||||
connect(ui.btnRefresh, SIGNAL(pressed()), this, SLOT(FindFiles()));
|
||||
connect(ui.btnRecover, SIGNAL(pressed()), this, SLOT(OnRecover()));
|
||||
connect(ui.btnRecoverTo, SIGNAL(pressed()), this, SLOT(OnRecoverTo()));
|
||||
|
@ -63,7 +67,7 @@ CRecoveryWindow::CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
foreach(const QString& NtFolder, m_pBox->GetTextList("RecoverFolder", true, true))
|
||||
{
|
||||
QString Folder = theAPI->Nt2DosPath(NtFolder);
|
||||
m_RecoveryFolders.insert(theAPI->GetBoxedPath(m_pBox, Folder), Folder);
|
||||
m_RecoveryFolders.append(Folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,10 +98,10 @@ void CRecoveryWindow::OnAddFolder()
|
|||
if (m_RecoveryFolders.contains(Folder))
|
||||
return;
|
||||
|
||||
m_RecoveryFolders.insert(theAPI->GetBoxedPath(m_pBox, Folder), Folder);
|
||||
m_RecoveryFolders.append(Folder);
|
||||
m_pBox->AppendText("RecoverFolder", Folder);
|
||||
|
||||
FindFiles(theAPI->GetBoxedPath(m_pBox, Folder));
|
||||
FindFiles(Folder);
|
||||
|
||||
m_pFileModel->Sync(m_FileMap);
|
||||
ui.treeFiles->expandAll();
|
||||
|
@ -111,10 +115,30 @@ void CRecoveryWindow::OnDeleteAll()
|
|||
|
||||
int CRecoveryWindow::FindFiles()
|
||||
{
|
||||
if (m_pCounter == NULL) {
|
||||
m_pCounter = new CRecoveryCounter(m_pBox->GetFileRoot(), this);
|
||||
connect(m_pCounter, SIGNAL(Count(quint32, quint32, quint64)), this, SLOT(OnCount(quint32, quint32, quint64)));
|
||||
}
|
||||
|
||||
m_FileMap.clear();
|
||||
int Count = 0;
|
||||
foreach(const QString& Folder, m_RecoveryFolders.keys())
|
||||
Count += FindFiles(Folder);
|
||||
|
||||
if (ui.chkShowAll->isChecked())
|
||||
{
|
||||
for(char drive = 'A'; drive <= 'Z'; drive++)
|
||||
Count += FindBoxFiles("\\drive\\" + QString(drive));
|
||||
if (m_pBox->GetBool("SeparateUserFolders", true)) {
|
||||
Count += FindBoxFiles("\\user\\current");
|
||||
Count += FindBoxFiles("\\user\\all");
|
||||
Count += FindBoxFiles("\\user\\public");
|
||||
}
|
||||
Count += FindBoxFiles("\\share");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(const QString & Folder, m_RecoveryFolders)
|
||||
Count += FindFiles(Folder);
|
||||
}
|
||||
|
||||
m_pFileModel->Sync(m_FileMap);
|
||||
ui.treeFiles->expandAll();
|
||||
|
@ -122,16 +146,24 @@ int CRecoveryWindow::FindFiles()
|
|||
}
|
||||
|
||||
int CRecoveryWindow::FindFiles(const QString& Folder)
|
||||
{
|
||||
return FindFiles(Folder, theAPI->GetBoxedPath(m_pBox, Folder), Folder);
|
||||
}
|
||||
|
||||
int CRecoveryWindow::FindBoxFiles(const QString& Folder)
|
||||
{
|
||||
return FindFiles(Folder, m_pBox->GetFileRoot() + Folder, theAPI->GetRealPath(m_pBox, m_pBox->GetFileRoot() + Folder));
|
||||
}
|
||||
|
||||
int CRecoveryWindow::FindFiles(const QString& RecParent, const QString& BoxedFolder, const QString& RealFolder)
|
||||
{
|
||||
QFileIconProvider IconProvider;
|
||||
|
||||
int Count = 0;
|
||||
quint64 TotalSize = 0;
|
||||
|
||||
QString RecParent = m_RecoveryFolders.value(Folder);
|
||||
|
||||
QStringList Folders;
|
||||
Folders.append(Folder);
|
||||
Folders.append(BoxedFolder);
|
||||
do {
|
||||
QDir Dir(Folders.takeFirst());
|
||||
foreach(const QFileInfo& Info, Dir.entryInfoList(QDir::AllEntries))
|
||||
|
@ -145,7 +177,7 @@ int CRecoveryWindow::FindFiles(const QString& Folder)
|
|||
Count++;
|
||||
TotalSize += Info.size();
|
||||
|
||||
QString RealPath = RecParent + Path.mid(Folder.length());
|
||||
QString RealPath = RealFolder + Path.mid(BoxedFolder.length());
|
||||
|
||||
QVariantMap RecFile;
|
||||
RecFile["ID"] = RealPath;
|
||||
|
@ -181,13 +213,7 @@ int CRecoveryWindow::FindFiles(const QString& Folder)
|
|||
|
||||
void CRecoveryWindow::RecoverFiles(bool bBrowse)
|
||||
{
|
||||
QString RecoveryFolder;
|
||||
if (bBrowse)
|
||||
{
|
||||
RecoveryFolder = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
|
||||
if (RecoveryFolder.isEmpty())
|
||||
return;
|
||||
}
|
||||
bool HasShare = false;
|
||||
|
||||
QMap<QString, QString> FileMap;
|
||||
foreach(const QModelIndex& Index, ui.treeFiles->selectionModel()->selectedIndexes())
|
||||
|
@ -201,7 +227,11 @@ void CRecoveryWindow::RecoverFiles(bool bBrowse)
|
|||
continue;
|
||||
|
||||
if (!File["ParentID"].isNull())
|
||||
{
|
||||
if (File["DiskPath"].toString().indexOf("\\device\\mup") == 0)
|
||||
HasShare = true;
|
||||
FileMap[File["BoxPath"].toString()] = File["DiskPath"].toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < m_pFileModel->rowCount(Index); i++)
|
||||
|
@ -213,11 +243,23 @@ void CRecoveryWindow::RecoverFiles(bool bBrowse)
|
|||
if (File.isEmpty())
|
||||
continue;
|
||||
|
||||
if (File["DiskPath"].toString().indexOf("\\device\\mup") == 0)
|
||||
HasShare = true;
|
||||
FileMap[File["BoxPath"].toString()] = File["DiskPath"].toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString RecoveryFolder;
|
||||
if (HasShare && !bBrowse)
|
||||
{
|
||||
if (!bBrowse)
|
||||
QMessageBox::warning(this, "Sandboxie-Plus", tr("One or more selected files are located on a network share, and must be recovered to a local drive, please select a folder to recover all selected files to."));
|
||||
|
||||
RecoveryFolder = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
|
||||
if (RecoveryFolder.isEmpty())
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QPair<QString, QString>> FileList;
|
||||
for(QMap<QString, QString>::const_iterator I = FileMap.begin(); I != FileMap.end(); ++I)
|
||||
|
@ -240,3 +282,46 @@ void CRecoveryWindow::RecoverFiles(bool bBrowse)
|
|||
theGUI->AddAsyncOp(Status.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
void CRecoveryWindow::OnCount(quint32 fileCount, quint32 folderCount, quint64 totalSize)
|
||||
{
|
||||
ui.lblInfo->setText(tr("There are %1 files and %2 folders in the sandbox, occupying %3 bytes of disk space.").arg(fileCount).arg(folderCount).arg(FormatSize(totalSize)));
|
||||
}
|
||||
|
||||
void CRecoveryCounter::run()
|
||||
{
|
||||
quint32 fileCount = 0;
|
||||
quint32 folderCount = 0;
|
||||
quint64 totalSize = 0;
|
||||
|
||||
QStringList Folders;
|
||||
Folders.append(m_BoxPath);
|
||||
do {
|
||||
if (!m_run) break;
|
||||
|
||||
QDir Dir(Folders.takeFirst());
|
||||
foreach(const QFileInfo & Info, Dir.entryInfoList(QDir::AllEntries))
|
||||
{
|
||||
if (!m_run) break;
|
||||
|
||||
QString Name = Info.fileName();
|
||||
if (Name == "." || Name == "..")
|
||||
continue;
|
||||
QString Path = Info.filePath().replace("/", "\\");
|
||||
if (Info.isFile())
|
||||
{
|
||||
fileCount++;
|
||||
totalSize += Info.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
Folders.append(Path);
|
||||
|
||||
folderCount++;
|
||||
}
|
||||
}
|
||||
|
||||
emit Count(fileCount, folderCount, totalSize);
|
||||
|
||||
} while (!Folders.isEmpty());
|
||||
}
|
|
@ -5,6 +5,31 @@
|
|||
#include "SbiePlusAPI.h"
|
||||
class CSimpleTreeModel;
|
||||
|
||||
class CRecoveryCounter : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CRecoveryCounter(const QString& BoxPath, QWidget* parent = Q_NULLPTR) : QThread(parent) {
|
||||
m_BoxPath = BoxPath;
|
||||
m_run = true;
|
||||
start(QThread::LowPriority);
|
||||
}
|
||||
~CRecoveryCounter() {
|
||||
m_run = false;
|
||||
wait(2000);
|
||||
terminate();
|
||||
}
|
||||
|
||||
signals:
|
||||
void Count(quint32 fileCount, quint32 folderCount, quint64 totalSize);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
QString m_BoxPath;
|
||||
bool m_run;
|
||||
};
|
||||
|
||||
class CRecoveryWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -13,6 +38,9 @@ public:
|
|||
CRecoveryWindow(const CSandBoxPtr& pBox, QWidget *parent = Q_NULLPTR);
|
||||
~CRecoveryWindow();
|
||||
|
||||
virtual void accept() {}
|
||||
virtual void reject() { this->close(); }
|
||||
|
||||
public slots:
|
||||
int exec();
|
||||
|
||||
|
@ -24,10 +52,14 @@ private slots:
|
|||
void OnRecoverTo() { RecoverFiles(true); }
|
||||
void OnDeleteAll();
|
||||
|
||||
void OnCount(quint32 fileCount, quint32 folderCount, quint64 totalSize);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
int FindFiles(const QString& Folder);
|
||||
int FindBoxFiles(const QString& Folder);
|
||||
int FindFiles(const QString& RecParent, const QString& BoxedFolder, const QString& RealFolder);
|
||||
|
||||
void RecoverFiles(bool bBrowse);
|
||||
|
||||
|
@ -35,7 +67,9 @@ protected:
|
|||
|
||||
QMap<QVariant, QVariantMap> m_FileMap;
|
||||
|
||||
QMap<QString, QString> m_RecoveryFolders;
|
||||
QStringList m_RecoveryFolders;
|
||||
|
||||
CRecoveryCounter* m_pCounter;
|
||||
|
||||
private:
|
||||
Ui::RecoveryWindow ui;
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
|
||||
CSettingsWindow::CSettingsWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
QWidget* centralWidget = new QWidget();
|
||||
ui.setupUi(centralWidget);
|
||||
this->setCentralWidget(centralWidget);
|
||||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("Sandboxie Plus - Settings"));
|
||||
|
||||
ui.tabs->setCurrentIndex(0);
|
||||
|
||||
ui.uiLang->addItem("International English", "");
|
||||
QDir langDir(QApplication::applicationDirPath() + "/translations/");
|
||||
foreach(const QString& langFile, langDir.entryList(QStringList("sandman_*.qm"), QDir::Files))
|
||||
|
@ -27,6 +27,7 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
|
|||
ui.uiLang->setCurrentIndex(ui.uiLang->findData(theConf->GetString("Options/Language")));
|
||||
|
||||
ui.chkAutoStart->setChecked(IsAutorunEnabled());
|
||||
ui.chkSvcStart->setChecked(theAPI->GetUserSettings()->GetBool("SbieCtrl_EnableAutoStart", true));
|
||||
|
||||
switch (theConf->GetInt("Options/CheckForUpdates", 2)) {
|
||||
case 0: ui.chkAutoUpdate->setCheckState(Qt::Unchecked); break;
|
||||
|
@ -47,6 +48,8 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
|
|||
case 2: ui.chkSandboxUrls->setCheckState(Qt::PartiallyChecked); break;
|
||||
}
|
||||
|
||||
ui.chkShowRecovery->setChecked(theConf->GetBool("Options/ShowRecovery", false));
|
||||
|
||||
ui.chkWatchConfig->setChecked(theConf->GetBool("Options/WatchIni", true));
|
||||
|
||||
ui.onClose->addItem(tr("Close to Tray"), "ToTray");
|
||||
|
@ -112,6 +115,8 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
|
|||
}
|
||||
m_WarnProgsChanged = false;
|
||||
|
||||
connect(ui.btnBrowse, SIGNAL(pressed()), this, SLOT(OnBrowse()));
|
||||
|
||||
int PortableRootDir = theConf->GetInt("Options/PortableRootDir", -1);
|
||||
if (PortableRootDir != -1 && theConf->IsPortable())
|
||||
ui.chkAutoRoot->setChecked(PortableRootDir == 0 ? Qt::Unchecked : Qt::Checked);
|
||||
|
@ -131,7 +136,7 @@ CSettingsWindow::CSettingsWindow(QWidget *parent)
|
|||
|
||||
connect(ui.tabs, SIGNAL(currentChanged(int)), this, SLOT(OnTab()));
|
||||
|
||||
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(pressed()), this, SLOT(accept()));
|
||||
connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(pressed()), this, SLOT(ok()));
|
||||
connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(pressed()), this, SLOT(apply()));
|
||||
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
|
@ -154,6 +159,7 @@ void CSettingsWindow::showCompat()
|
|||
|
||||
void CSettingsWindow::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
emit Closed();
|
||||
this->deleteLater();
|
||||
}
|
||||
|
||||
|
@ -164,6 +170,7 @@ void CSettingsWindow::apply()
|
|||
theConf->SetValue("Options/DarkTheme", ui.chkDarkTheme->isChecked());
|
||||
|
||||
AutorunEnable(ui.chkAutoStart->isChecked());
|
||||
theAPI->GetUserSettings()->SetBool("SbieCtrl_EnableAutoStart", ui.chkSvcStart->isChecked());
|
||||
|
||||
switch (ui.chkAutoUpdate->checkState()) {
|
||||
case Qt::Unchecked: theConf->SetValue("Options/CheckForUpdates", 0); break;
|
||||
|
@ -187,6 +194,8 @@ void CSettingsWindow::apply()
|
|||
case Qt::Checked: theConf->SetValue("Options/OpenUrlsSandboxed", 1); break;
|
||||
}
|
||||
|
||||
theConf->SetValue("Options/ShowRecovery", ui.chkShowRecovery->isChecked());
|
||||
|
||||
theConf->SetValue("Options/WatchIni", ui.chkWatchConfig->isChecked());
|
||||
|
||||
theConf->SetValue("Options/OnClose", ui.onClose->currentData());
|
||||
|
@ -280,7 +289,7 @@ void CSettingsWindow::apply()
|
|||
emit OptionsChanged();
|
||||
}
|
||||
|
||||
void CSettingsWindow::accept()
|
||||
void CSettingsWindow::ok()
|
||||
{
|
||||
apply();
|
||||
|
||||
|
@ -292,6 +301,15 @@ void CSettingsWindow::reject()
|
|||
this->close();
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnBrowse()
|
||||
{
|
||||
QString Value = QFileDialog::getExistingDirectory(this, tr("Select Directory")).replace("/", "\\");
|
||||
if (Value.isEmpty())
|
||||
return;
|
||||
|
||||
ui.fileRoot->setText(Value + "\\%SANDBOX%");
|
||||
}
|
||||
|
||||
void CSettingsWindow::OnChange()
|
||||
{
|
||||
//ui.chkLinuxStyle->setEnabled(!ui.chkUseCycles->isChecked());
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <QtWidgets/QMainWindow>
|
||||
#include "ui_SettingsWindow.h"
|
||||
|
||||
class CSettingsWindow : public QMainWindow
|
||||
class CSettingsWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -11,13 +11,16 @@ public:
|
|||
CSettingsWindow(QWidget *parent = Q_NULLPTR);
|
||||
~CSettingsWindow();
|
||||
|
||||
virtual void accept() {}
|
||||
virtual void reject();
|
||||
|
||||
signals:
|
||||
void OptionsChanged();
|
||||
void Closed();
|
||||
|
||||
public slots:
|
||||
void ok();
|
||||
void apply();
|
||||
void accept();
|
||||
void reject();
|
||||
|
||||
void showCompat();
|
||||
|
||||
|
@ -26,6 +29,8 @@ private slots:
|
|||
|
||||
void OnTab();
|
||||
|
||||
void OnBrowse();
|
||||
|
||||
void OnSetPassword();
|
||||
|
||||
void OnWarnChanged() { m_WarnProgsChanged = true; }
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
|
||||
|
||||
CSnapshotsWindow::CSnapshotsWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
QWidget* centralWidget = new QWidget();
|
||||
ui.setupUi(centralWidget);
|
||||
this->setCentralWidget(centralWidget);
|
||||
ui.setupUi(this);
|
||||
this->setWindowTitle(tr("%1 - Snapshots").arg(pBox->GetName()));
|
||||
|
||||
m_pBox = pBox;
|
||||
|
@ -20,6 +18,7 @@ CSnapshotsWindow::CSnapshotsWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
QStyle* pStyle = QStyleFactory::create("windows");
|
||||
ui.treeSnapshots->setStyle(pStyle);
|
||||
#endif
|
||||
ui.treeSnapshots->setExpandsOnDoubleClick(false);
|
||||
|
||||
m_pSnapshotModel = new CSimpleTreeModel();
|
||||
m_pSnapshotModel->AddColumn(tr("Snapshot"), "Name");
|
||||
|
@ -45,7 +44,11 @@ CSnapshotsWindow::CSnapshotsWindow(const CSandBoxPtr& pBox, QWidget *parent)
|
|||
connect(ui.txtName, SIGNAL(textEdited(const QString&)), this, SLOT(SaveInfo()));
|
||||
connect(ui.txtInfo, SIGNAL(textChanged()), this, SLOT(SaveInfo()));
|
||||
|
||||
statusBar();
|
||||
ui.groupBox->setEnabled(false);
|
||||
ui.btnSelect->setEnabled(false);
|
||||
ui.btnRemove->setEnabled(false);
|
||||
|
||||
//statusBar();
|
||||
|
||||
restoreGeometry(theConf->GetBlob("SnapshotsWindow/Window_Geometry"));
|
||||
|
||||
|
@ -91,6 +94,10 @@ void CSnapshotsWindow::UpdateSnapshots()
|
|||
|
||||
void CSnapshotsWindow::UpdateSnapshot(const QModelIndex& Index)
|
||||
{
|
||||
ui.groupBox->setEnabled(true);
|
||||
ui.btnSelect->setEnabled(true);
|
||||
ui.btnRemove->setEnabled(true);
|
||||
|
||||
//QModelIndex Index = ui.treeSnapshots->currentIndex();
|
||||
//QModelIndex ModelIndex = m_pSortProxy->mapToSource(Index);
|
||||
//QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex);
|
||||
|
@ -106,7 +113,7 @@ void CSnapshotsWindow::UpdateSnapshot(const QModelIndex& Index)
|
|||
ui.txtInfo->setPlainText(BoxSnapshot["Info"].toString());
|
||||
m_SaveInfoPending = 0;
|
||||
|
||||
statusBar()->showMessage(tr("Snapshot: %1 taken: %2").arg(BoxSnapshot["Name"].toString()).arg(BoxSnapshot["Date"].toDateTime().toString()));
|
||||
//statusBar()->showMessage(tr("Snapshot: %1 taken: %2").arg(BoxSnapshot["Name"].toString()).arg(BoxSnapshot["Date"].toDateTime().toString()));
|
||||
}
|
||||
|
||||
void CSnapshotsWindow::SaveInfo()
|
||||
|
@ -143,7 +150,7 @@ void CSnapshotsWindow::OnSelectSnapshot()
|
|||
//QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex);
|
||||
QVariant ID = m_pSnapshotModel->GetItemID(Index);
|
||||
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to switch the active snapshot? Doing so will delete the current state!"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to switch the active snapshot? Doing so will delete the current state!"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
HandleResult(m_pBox->SelectSnapshot(ID.toString()));
|
||||
|
@ -156,7 +163,7 @@ void CSnapshotsWindow::OnRemoveSnapshot()
|
|||
//QVariant ID = m_pSnapshotModel->GetItemID(ModelIndex);
|
||||
QVariant ID = m_pSnapshotModel->GetItemID(Index);
|
||||
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the selected snapshot?"), QMessageBox::Warning, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
if (QMessageBox("Sandboxie-Plus", tr("Do you really want to delete the selected snapshot?"), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No | QMessageBox::Default | QMessageBox::Escape, QMessageBox::NoButton).exec() != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
HandleResult(m_pBox->RemoveSnapshot(ID.toString()));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "SbiePlusAPI.h"
|
||||
class CSimpleTreeModel;
|
||||
|
||||
class CSnapshotsWindow : public QMainWindow
|
||||
class CSnapshotsWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -13,6 +13,9 @@ public:
|
|||
CSnapshotsWindow(const CSandBoxPtr& pBox, QWidget *parent = Q_NULLPTR);
|
||||
~CSnapshotsWindow();
|
||||
|
||||
virtual void accept() {}
|
||||
virtual void reject() { this->close(); }
|
||||
|
||||
private slots:
|
||||
void UpdateSnapshots();
|
||||
void UpdateSnapshot(const QModelIndex& Index);
|
||||
|
|
|
@ -20,6 +20,7 @@ int main(int argc, char *argv[])
|
|||
//QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
|
||||
|
||||
QtSingleApplication app(argc, argv);
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
|
||||
//InitConsole(false);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue