This commit is contained in:
DavidXanatos 2022-01-06 18:36:09 +01:00
parent 6aea2af125
commit bbb912ece2
18 changed files with 217 additions and 156 deletions

View File

@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- added new template "DeviceSecurity" template to lock down access to device drviers on the system
-- Note: This template requires RuleSpecificity being available to work properly
- added option to set a custom ini editor in the plus ui [#1475](https://github.com/sandboxie-plus/Sandboxie/issues/1475)
- added option "LingerLeniency=n" to solve issue [997](https://github.com/sandboxie-plus/Sandboxie/issues/997)
### Changed
- reworked syscall invocation code in the driver
@ -23,6 +24,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- fixed memory leak in driver (conf_user.c)
- fixed issue with file renaming in open paths introduced in 1.0.6
- fixed issue chromium browsers not closing properly [#1496](https://github.com/sandboxie-plus/Sandboxie/issues/1496)
- fixed issue with start.exe [#1517](https://github.com/sandboxie-plus/Sandboxie/issues/1517) [#1516](https://github.com/sandboxie-plus/Sandboxie/issues/1516)
- fixed sandman issue with resude process ID's
- fixed kmdutill sometimes not properly terminating the driver
### Removed
- removed OpenToken as its only a shorthand for UnrestrictedToken=y and UnfilteredToken=y set together

View File

@ -271,36 +271,39 @@ int DoLingerLeader(void)
Add_LL_Entry(lingers, &linger_count, image);
}
//
// see which of the LingerProcess programs were already active
// before SandboxieRpcSs started. they will not be considered
// LingerProcess programs and will not be terminated
//
if (SbieApi_QueryConfBool(NULL, L"LingerLeniency", TRUE)) {
ULONG pid_count = 0;
SbieApi_EnumProcessEx(NULL, FALSE, -1, NULL, &pid_count); // query count
pid_count += 128;
//
// see which of the LingerProcess programs were already active
// before SandboxieRpcSs started. they will not be considered
// LingerProcess programs and will not be terminated
//
ULONG* pids = HeapAlloc(
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(ULONG) * pid_count);
SbieApi_EnumProcessEx(NULL, FALSE, -1, pids, &pid_count); // query pids
ULONG pid_count = 0;
SbieApi_EnumProcessEx(NULL, FALSE, -1, NULL, &pid_count); // query count
pid_count += 128;
AddPid(pids, pid_count);
ULONG* pids = HeapAlloc(
GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(ULONG) * pid_count);
SbieApi_EnumProcessEx(NULL, FALSE, -1, pids, &pid_count); // query pids
for (i = 0; i <= pid_count; ++i) {
AddPid(pids, pid_count);
pids_i = (HANDLE) (ULONG_PTR) pids[i];
SbieApi_QueryProcess(pids_i, NULL, image, NULL, NULL);
for (i = 0; i <= pid_count; ++i) {
for (j = 0; j < linger_count; ++j) {
if (_wcsicmp(lingers[j]->image, image) == 0) {
lingers[j]->orig_pid = pids_i;
break;
pids_i = (HANDLE)(ULONG_PTR)pids[i];
SbieApi_QueryProcess(pids_i, NULL, image, NULL, NULL);
for (j = 0; j < linger_count; ++j) {
if (_wcsicmp(lingers[j]->image, image) == 0) {
lingers[j]->orig_pid = pids_i;
break;
}
}
}
}
HeapFree(GetProcessHeap(), 0, pids);
HeapFree(GetProcessHeap(), 0, pids);
}
//
// add standard lingers. note that we don't check if any of
@ -448,6 +451,7 @@ int DoLingerLeader(void)
//}
//
//if (!is_local_system_sid)
if (SbieApi_QueryConfBool(NULL, L"LingerLeniency", TRUE))
{
//
// then check if the process was started explicitly

View File

@ -1713,10 +1713,13 @@ int __stdcall WinMainCRTStartup(
while (1) {
if (display_run_dialog || execute_open_with) {
if (display_run_dialog) {
MyCoInitialize();
ChildCmdLine = DoRunDialog(GetModuleHandle(NULL));
} else if (execute_open_with) {
MyCoInitialize();
WCHAR* CmdLine = DoRunDialog(GetModuleHandle(NULL));
if (! ChildCmdLine)
if (!CmdLine) // !CmdLine -> cancel
ChildCmdLine = CmdLine;
else { // execute_open_with
WCHAR* FilePath = ChildCmdLine;
@ -1726,7 +1729,6 @@ int __stdcall WinMainCRTStartup(
MyHeapFree(CmdLine);
MyHeapFree(FilePath);
}
} else if (display_start_menu) {
if (! ChildCmdLine)
ChildCmdLine = DoStartMenu();

View File

@ -2258,6 +2258,19 @@ __declspec(dllimport) NTSTATUS RtlCreateSecurityDescriptor(
ULONG Revision
);
__declspec(dllimport) NTSTATUS RtlGetOwnerSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor,
PSID* Owner, PBOOLEAN OwnerDefaulted
);
__declspec(dllimport) NTSTATUS RtlGetGroupSecurityDescriptor(
PSECURITY_DESCRIPTOR SecurityDescriptor,
PSID* Group, PBOOLEAN GroupDefaulted
);
__declspec(dllimport) BOOLEAN RtlEqualSid(PSID Sid1, PSID Sid2);
__declspec(dllimport) PVOID RtlFreeSid(PSID Sid);
//---------------------------------------------------------------------------
typedef struct _RTL_DRIVE_LETTER_CURDIR {

View File

@ -75,7 +75,7 @@ _FX BOOLEAN CustomizeSandbox(void)
if ((Dll_ProcessFlags & SBIE_FLAG_PRIVACY_MODE) != 0) {
Key_CreateBaseKeys();
Key_CreateBaseFolders();
//Key_CreateBaseFolders(); // no longer needed those paths will be created on demand
}
if (GetSetCustomLevel(0) != '2') {

View File

@ -506,7 +506,7 @@ void Key_DeleteValueFromCLSID(
const WCHAR *Xxxid, const WCHAR *Guid, const WCHAR *ValueName);
void Key_CreateBaseKeys();
void Key_CreateBaseFolders();
//void Key_CreateBaseFolders();
//---------------------------------------------------------------------------
// Functions (sxs)

View File

@ -341,8 +341,8 @@ static void *File_Wow64DisableWow64FsRedirection = NULL;
static void *File_Wow64RevertWow64FsRedirection = NULL;
#endif WOW64_FS_REDIR
static WCHAR *File_SysVolume = NULL;
static ULONG File_SysVolumeLen = 0;
//static WCHAR *File_SysVolume = NULL;
//static ULONG File_SysVolumeLen = 0;
static WCHAR *File_AllUsers = NULL;
static ULONG File_AllUsersLen = 0;

View File

@ -4112,16 +4112,16 @@ _FX void File_UnScrambleShortName(WCHAR* ShortName, ULONG ScramKey)
//---------------------------------------------------------------------------
_FX void Key_CreateBaseFolders()
{
//
// in privacy mode we need to pre create some folders or else programs may fail
//
File_CreateBoxedPath(File_SysVolume);
if (SbieApi_QueryConfBool(NULL, L"SeparateUserFolders", TRUE)) {
File_CreateBoxedPath(File_AllUsers);
File_CreateBoxedPath(File_CurrentUser);
}
}
//_FX void Key_CreateBaseFolders()
//{
// //
// // in privacy mode we need to pre create some folders or else programs may fail
// //
//
// File_CreateBoxedPath(File_SysVolume);
//
// if (SbieApi_QueryConfBool(NULL, L"SeparateUserFolders", TRUE)) {
// File_CreateBoxedPath(File_AllUsers);
// File_CreateBoxedPath(File_CurrentUser);
// }
//}

View File

@ -79,7 +79,7 @@ typedef struct _MOUNTMGR_VOLUME_PATHS {
//---------------------------------------------------------------------------
static void File_InitPathList(void);
//static void File_InitPathList(void);
static BOOLEAN File_InitDrives(ULONG DriveMask);
@ -154,7 +154,7 @@ _FX BOOLEAN File_Init(void)
File_ProxyPipes = Dll_Alloc(sizeof(ULONG) * 256);
memzero(File_ProxyPipes, sizeof(ULONG) * 256);
File_InitPathList();
SbieDll_MatchPath(L'f', (const WCHAR *)-1); //File_InitPathList();
File_DriveAddSN = SbieApi_QueryConfBool(NULL, L"UseVolumeSerialNumbers", FALSE);
@ -291,47 +291,45 @@ _FX BOOLEAN File_IsBlockedNetParam(const WCHAR *BoxName)
//---------------------------------------------------------------------------
_FX void File_InitPathList(void)
{
OBJECT_ATTRIBUTES objattrs;
UNICODE_STRING objname;
IO_STATUS_BLOCK MyIoStatusBlock;
HANDLE handle;
WCHAR *buf, *ptr;
// why do we do that?
RtlInitUnicodeString(&objname, L"\\SystemRoot");
InitializeObjectAttributes(
&objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
handle = 0;
NtOpenFile(&handle, FILE_READ_DATA, &objattrs,
&MyIoStatusBlock, FILE_SHARE_VALID_FLAGS, 0);
// since we do that for some reason lets use it to get the system volume
const ULONG PATH_BUF_LEN = 1024;
buf = Dll_AllocTemp(PATH_BUF_LEN);
if (NT_SUCCESS(File_GetFileName(handle, PATH_BUF_LEN, buf)) && (ptr = wcsrchr(buf, L'\\')) != NULL)
ptr[1] = L'\0'; // strip the folder name
else // fallback
wcscpy(buf, L"\\??\\C:\\");
File_SysVolumeLen = wcslen(buf);
File_SysVolume =
Dll_Alloc((File_SysVolumeLen + 1) * sizeof(WCHAR));
wcscpy(File_SysVolume, buf);
Dll_Free(buf);
//
if (handle)
NtClose(handle);
SbieDll_MatchPath(L'f', (const WCHAR *)-1);
}
//_FX void File_InitPathList(void)
//{
// OBJECT_ATTRIBUTES objattrs;
// UNICODE_STRING objname;
// IO_STATUS_BLOCK MyIoStatusBlock;
// HANDLE handle;
// WCHAR *buf, *ptr;
//
// RtlInitUnicodeString(&objname, L"\\SystemRoot");
// InitializeObjectAttributes(
// &objattrs, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
// handle = 0;
// NtOpenFile(&handle, FILE_READ_DATA, &objattrs,
// &MyIoStatusBlock, FILE_SHARE_VALID_FLAGS, 0);
//
// //
//
// const ULONG PATH_BUF_LEN = 1024;
// buf = Dll_AllocTemp(PATH_BUF_LEN);
//
// if (NT_SUCCESS(File_GetFileName(handle, PATH_BUF_LEN, buf)) && (ptr = wcsrchr(buf, L'\\')) != NULL)
// ptr[1] = L'\0'; // strip the folder name
// else // fallback
// wcscpy(buf, L"\\??\\C:\\");
//
// File_SysVolumeLen = wcslen(buf);
// File_SysVolume =
// Dll_Alloc((File_SysVolumeLen + 1) * sizeof(WCHAR));
// wcscpy(File_SysVolume, buf);
//
// Dll_Free(buf);
//
// //
//
// if (handle)
// NtClose(handle);
//
// SbieDll_MatchPath(L'f', (const WCHAR *)-1);
//}
//---------------------------------------------------------------------------

View File

@ -97,6 +97,12 @@ _FX NTSTATUS SbieApi_Ioctl(ULONG64 *parms)
UNICODE_STRING uni;
IO_STATUS_BLOCK MyIoStatusBlock;
if (parms == NULL) { // close request as used by kmdutil
if(SbieApi_DeviceHandle != INVALID_HANDLE_VALUE)
NtClose(SbieApi_DeviceHandle);
SbieApi_DeviceHandle = INVALID_HANDLE_VALUE;
}
if (Dll_SbieTrace && parms[0] != API_MONITOR_PUT2) {
WCHAR dbg[1024];
extern const wchar_t* Trace_SbieDrvFunc2Str(ULONG func);

View File

@ -47,6 +47,8 @@ extern "C" {
// Sandboxie API Calls
//---------------------------------------------------------------------------
SBIEAPI_EXPORT
long SbieApi_Ioctl(ULONG64* parms);
SBIEAPI_EXPORT
LONG SbieApi_Call(ULONG api_code, LONG arg_num, ...);
@ -90,6 +92,7 @@ LONG SbieApi_GetHomePath(
WCHAR *DosPath, ULONG DosPathMaxLen);
//---------------------------------------------------------------------------

View File

@ -231,6 +231,15 @@ BOOLEAN Secure_Is_IE_NtQueryInformationToken = FALSE;
BOOLEAN Secure_FakeAdmin = FALSE;
static UCHAR AdministratorsSid[16] = {
1, // Revision
2, // SubAuthorityCount
0,0,0,0,0,5, // SECURITY_NT_AUTHORITY // IdentifierAuthority
0x20, 0, 0, 0, // SubAuthority 1 - SECURITY_BUILTIN_DOMAIN_RID
0x20, 2, 0, 0 // SubAuthority 2 - DOMAIN_ALIAS_RID_ADMINS
};
//---------------------------------------------------------------------------
// Secure_InitSecurityDescriptors
//---------------------------------------------------------------------------
@ -384,6 +393,15 @@ _FX BOOLEAN Secure_Init(void)
SBIEDLL_HOOK(Ldr_, RtlEqualSid);
//
// install hooks to fake administrator privileges
// note: when running as the built in administrator we should always act as if we have admin rights
//
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin())
&& (_wcsicmp(Dll_ImageName, L"msedge.exe") != 0); // never for msedge.exe
if (Secure_FakeAdmin || Dll_OsBuild >= 9600) {
void* NtAccessCheckByType = GetProcAddress(Dll_Ntdll, "NtAccessCheckByType");
@ -418,13 +436,6 @@ _FX BOOLEAN Secure_Init(void)
Secure_IsInternetExplorerTabProcess = TRUE;
}
//
// install hooks to fake administrator privileges
// note: when running as the built in administrator we should always act as if we have admin rights
//
Secure_FakeAdmin = Config_GetSettingsForImageName_bool(L"FakeAdminRights", Secure_IsBuiltInAdmin())
&& (_wcsicmp(Dll_ImageName, L"msedge.exe") != 0); // never for msedge.exe
RtlQueryElevationFlags =
GetProcAddress(Dll_Ntdll, "RtlQueryElevationFlags");
@ -1066,6 +1077,7 @@ NTSTATUS Ldr_NtAccessCheckByType(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID P
NTSTATUS rc;
HANDLE hTokenReal = NULL;
// todo: is that right? seams wrong
if (Dll_ImageType == DLL_IMAGE_SANDBOXIE_BITS ||
Dll_ImageType == DLL_IMAGE_SANDBOXIE_WUAU ||
Dll_ImageType == DLL_IMAGE_WUAUCLT) {
@ -1092,6 +1104,23 @@ _FX NTSTATUS Ldr_NtAccessCheck(PSECURITY_DESCRIPTOR SecurityDescriptor, HANDLE C
NTSTATUS status = 0;
HANDLE hTokenReal = NULL;
if (Secure_FakeAdmin && SecurityDescriptor) {
BOOLEAN Fake = FALSE;
PSID Group, Owner;
BOOLEAN Dummy1, Dummy2;
if (NT_SUCCESS(RtlGetGroupSecurityDescriptor(SecurityDescriptor, &Group, &Dummy1))
&& NT_SUCCESS(RtlGetOwnerSecurityDescriptor(SecurityDescriptor, &Owner, &Dummy2))) {
Fake = RtlEqualSid(Group, AdministratorsSid) || RtlEqualSid(Owner, AdministratorsSid);
}
if (Fake) {
*GrantedAccess = 1;
*AccessStatus = 0;
return STATUS_SUCCESS;
}
}
Ldr_TestToken(ClientToken, &hTokenReal, TRUE);
status = __sys_NtAccessCheck(SecurityDescriptor, hTokenReal ? hTokenReal : ClientToken, DesiredAccess, GenericMapping, RequiredPrivilegesBuffer, BufferLength, GrantedAccess, AccessStatus);
@ -1102,7 +1131,7 @@ _FX NTSTATUS Ldr_NtAccessCheck(PSECURITY_DESCRIPTOR SecurityDescriptor, HANDLE C
return status;
}
_FX NTSTATUS Ldr_NtAccessCheckByTypeResultList(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, HANDLE ClientToken, ACCESS_MASK DesiredAccess, POBJECT_TYPE_LIST ObjectTypeList, ULONG ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, PPRIVILEGE_SET PrivilegeSet, PULONG PrivilegeSetLength, PACCESS_MASK GrantedAccess, PNTSTATUS AccessStatus)
_FX NTSTATUS Ldr_NtAccessCheckByTypeResultList(PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, HANDLE ClientToken, ACCESS_MASK DesiredAccess, POBJECT_TYPE_LIST ObjectTypeList, ULONG ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, PPRIVILEGE_SET PrivilegeSet, PULONG PrivilegeSetLength, PACCESS_MASK GrantedAccess, PNTSTATUS AccessStatus)
{
NTSTATUS status = 0;
HANDLE hTokenReal = NULL;
@ -1117,7 +1146,7 @@ _FX NTSTATUS Ldr_NtAccessCheckByTypeResultList(PSECURITY_DESCRIPTOR SecurityDesc
return status;
}
BOOL Ldr_NtOpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, PHANDLE TokenHandle)
BOOL Ldr_NtOpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, PHANDLE TokenHandle)
{
BOOL rc;
@ -1360,16 +1389,7 @@ NTSTATUS Secure_RtlCheckTokenMembershipEx(
DWORD flags,
PUCHAR isMember)
{
static UCHAR AdministratorsSid[16] = {
1, // Revision
2, // SubAuthorityCount
0,0,0,0,0,5, // SECURITY_NT_AUTHORITY // IdentifierAuthority
0x20, 0, 0, 0, // SubAuthority 1 - SECURITY_BUILTIN_DOMAIN_RID
0x20, 2, 0, 0 // SubAuthority 2 - DOMAIN_ALIAS_RID_ADMINS
};
if (Secure_FakeAdmin && __sys_RtlEqualSid && __sys_RtlEqualSid(sidToCheck, AdministratorsSid)) {
if (Secure_FakeAdmin && RtlEqualSid(sidToCheck, AdministratorsSid)) {
if (isMember) *isMember = TRUE;
return STATUS_SUCCESS;
}

View File

@ -232,7 +232,7 @@ ifdef _WIN64
EXTERN Token_SepFilterToken : QWORD
Sbie_SepFilterTokenHandler_asm PROC
Sbie_SepFilterTokenHandler_asm PROC FRAME
mov qword ptr [rsp+20h],r9
mov qword ptr [rsp+18h],r8
@ -240,6 +240,8 @@ Sbie_SepFilterTokenHandler_asm PROC
mov qword ptr [rsp+8],rcx
sub rsp,78h
.allocstack 78h
.endprolog
mov dword ptr [rsp+60h],0
mov rax,qword ptr [rsp+0A0h] ; NewToken

View File

@ -426,7 +426,7 @@ _FX VOID KphParseDate(const WCHAR* date_str, LARGE_INTEGER* date)
}
// Example of __DATE__ string: "Jul 27 2012"
// 01234567890
// 0123456789A
#define BUILD_YEAR_CH0 (__DATE__[ 7])
#define BUILD_YEAR_CH1 (__DATE__[ 8])
@ -692,6 +692,11 @@ _FX NTSTATUS KphValidateCertificate(void)
, timeFiled.Hour, timeFiled.Minute, timeFiled.Second, timeFiled.Day, timeFiled.Month, timeFiled.Year);
}
if (!type && level) { // fix for some early hand crafted contributor certificates
type = level;
level = NULL;
}
if (type && _wcsicmp(type, L"CONTRIBUTOR") == 0) {
// forever - nothing to check here
}

View File

@ -610,15 +610,9 @@ BOOL Kmd_Stop_Service(
SC_HANDLE service;
SERVICE_STATUS service_status;
ULONG retries;
BOOLEAN is_driver;
if (_wcsicmp(Driver_Name, SBIEDRV) == 0) {
// stop the driver
if (! Kmd_Stop_SbieDrv())
return FALSE;
// fallback to stopping through SCM, otherwise the
// driver registry key does not always disappear
}
is_driver = _wcsicmp(Driver_Name, SBIEDRV) == 0;
// try to open the service for the driver
@ -639,18 +633,7 @@ BOOL Kmd_Stop_Service(
// stop the service if it's active
//
for (retries = 0; ; ++retries) {
if (retries) {
WCHAR Text[384];
wcscpy(Text, SbieDll_FormatMessage1(8102, Driver_Name));
wcscat(Text, L"\n\n");
wcscat(Text, SbieDll_FormatMessage0(8102 + retries));
MessageBox(NULL, Text, L"KmdUtil", MB_ICONEXCLAMATION | MB_OK);
}
for (retries = 0; retries <= 6; ++retries) {
if (! ControlService(
service,
@ -659,34 +642,53 @@ BOOL Kmd_Stop_Service(
if (GetLastError() == ERROR_SERVICE_NOT_ACTIVE)
return TRUE;
if ((GetLastError() == ERROR_SERVICE_REQUEST_TIMEOUT ||
GetLastError() == ERROR_PIPE_BUSY) && retries < 5) {
Sleep(2500);
continue;
}
if (!(GetLastError() == ERROR_SERVICE_REQUEST_TIMEOUT ||
GetLastError() == ERROR_PIPE_BUSY)){
Display_Error(L"ControlService Interrogate", 0);
return FALSE;
}
if (service_status.dwCurrentState != SERVICE_STOPPED) {
if (! ControlService(
service,
SERVICE_CONTROL_STOP, &service_status)) {
if ((GetLastError() == ERROR_SERVICE_REQUEST_TIMEOUT ||
GetLastError() == ERROR_PIPE_BUSY) && retries < 5) {
Sleep(2500);
continue;
}
Display_Error(L"ControlService Stop", 0);
Display_Error(L"ControlService Interrogate", 0);
return FALSE;
}
}
else if (service_status.dwCurrentState == SERVICE_STOPPED)
return TRUE;
return TRUE;
if (retries) {
if (retries <= 3)
Sleep(2500 * retries);
else {
WCHAR Text[384];
wcscpy(Text, SbieDll_FormatMessage1(8102, Driver_Name));
wcscat(Text, L"\n\n");
wcscat(Text, SbieDll_FormatMessage0(8102 + retries - 3));
MessageBox(NULL, Text, L"KmdUtil", MB_ICONEXCLAMATION | MB_OK);
}
}
if (is_driver) {
// stop the driver
if (! Kmd_Stop_SbieDrv())
continue;
// fallback to stopping through SCM, otherwise the
// driver registry key does not always disappear
}
if (! ControlService(
service,
SERVICE_CONTROL_STOP, &service_status)) {
if ((GetLastError() == ERROR_SERVICE_REQUEST_TIMEOUT ||
GetLastError() == ERROR_SERVICE_NOT_ACTIVE ||
GetLastError() == ERROR_PIPE_BUSY))
continue;
Display_Error(L"ControlService Stop", 0);
return FALSE;
}
Sleep(500);
}
return FALSE;

View File

@ -99,6 +99,9 @@ ALIGNED BOOLEAN Kmd_Stop_SbieDrv(void)
L"\\Registry\\Machine\\System\\CurrentControlSet"
L"\\Services\\" SBIEDRV);
rc = NtUnloadDriver(&uni);
SbieApi_Ioctl(NULL); // disconnect from driver
if (rc == 0 || rc == STATUS_OBJECT_NAME_NOT_FOUND)
return TRUE;

View File

@ -21,23 +21,22 @@ CSbieModel::~CSbieModel()
QList<QVariant> CSbieModel::MakeProcPath(const QString& BoxName, const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList)
{
QList<QVariant> Path = MakeProcPath(pProcess, ProcessList);
QList<QVariant> Path;
MakeProcPath(pProcess, ProcessList, Path);
Path.prepend(BoxName);
return Path;
}
QList<QVariant> CSbieModel::MakeProcPath(const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList)
void CSbieModel::MakeProcPath(const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList, QList<QVariant>& Path)
{
quint32 ParentID = pProcess->GetParendPID();
CBoxedProcessPtr pParent = ProcessList.value(ParentID);
QList<QVariant> Path;
if (!pParent.isNull() && ParentID != pProcess->GetProcessId())
if (!pParent.isNull() && ParentID != pProcess->GetProcessId() && !Path.contains(ParentID))
{
Path = MakeProcPath(pParent, ProcessList);
Path.append(ParentID);
Path.prepend(ParentID);
MakeProcPath(pParent, ProcessList, Path);
}
return Path;
}
bool CSbieModel::TestProcPath(const QList<QVariant>& Path, const QString& BoxName, const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList, int Index)

View File

@ -61,7 +61,7 @@ protected:
virtual STreeNode* MkNode(const QVariant& Id) { return new SSandBoxNode(Id); }
QList<QVariant> MakeProcPath(const QString& BoxName, const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList);
QList<QVariant> MakeProcPath(const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList);
void MakeProcPath(const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList, QList<QVariant>& Path);
bool TestProcPath(const QList<QVariant>& Path, const QString& BoxName, const CBoxedProcessPtr& pProcess, const QMap<quint32, CBoxedProcessPtr>& ProcessList, int Index = 0);
QString FindParent(const QVariant& Name, const QMap<QString, QStringList>& Groups);