BreakoutProcess support
This commit is contained in:
parent
ade657bb14
commit
0da573a7bd
|
@ -958,7 +958,11 @@ _FX BOOL Proc_CreateProcessInternalW(
|
||||||
resume_thread = TRUE;
|
resume_thread = TRUE;
|
||||||
dwCreationFlags |= CREATE_SUSPENDED;
|
dwCreationFlags |= CREATE_SUSPENDED;
|
||||||
|
|
||||||
dwCreationFlags &= ~CREATE_BREAKAWAY_FROM_JOB;
|
// no longer required see comment in GuiServer::GetJobObjectForAssign
|
||||||
|
//extern BOOLEAN SysInfo_UseSbieJob;
|
||||||
|
//if (SysInfo_UseSbieJob) {
|
||||||
|
// dwCreationFlags &= ~CREATE_BREAKAWAY_FROM_JOB;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -58,10 +58,10 @@ static void Process_NotifyProcess(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void Process_NotifyProcessEx(
|
static void Process_NotifyProcessEx(
|
||||||
HANDLE ParentId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
|
PEPROCESS ParentId, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
|
||||||
|
|
||||||
static PROCESS *Process_Create(
|
static PROCESS *Process_Create(
|
||||||
HANDLE ProcessId, const BOX *box, const WCHAR *image_path,
|
HANDLE ProcessId, HANDLE StarterId, const BOX *box, const WCHAR *image_path,
|
||||||
KIRQL *out_irql);
|
KIRQL *out_irql);
|
||||||
|
|
||||||
static void Process_NotifyProcess_Delete(HANDLE ProcessId);
|
static void Process_NotifyProcess_Delete(HANDLE ProcessId);
|
||||||
|
@ -587,7 +587,7 @@ _FX void Process_CreateTerminated(HANDLE ProcessId, ULONG SessionId)
|
||||||
|
|
||||||
|
|
||||||
_FX PROCESS *Process_Create(
|
_FX PROCESS *Process_Create(
|
||||||
HANDLE ProcessId, const BOX *box, const WCHAR *image_path,
|
HANDLE ProcessId, HANDLE StarterId, const BOX *box, const WCHAR *image_path,
|
||||||
KIRQL *out_irql)
|
KIRQL *out_irql)
|
||||||
{
|
{
|
||||||
POOL *pool;
|
POOL *pool;
|
||||||
|
@ -620,6 +620,7 @@ _FX PROCESS *Process_Create(
|
||||||
memzero(proc, sizeof(PROCESS));
|
memzero(proc, sizeof(PROCESS));
|
||||||
|
|
||||||
proc->pid = ProcessId;
|
proc->pid = ProcessId;
|
||||||
|
proc->starter_id = StarterId; // the pid of teh process that called CreateProcess, usually the parent
|
||||||
proc->pool = pool;
|
proc->pool = pool;
|
||||||
|
|
||||||
proc->box = Box_Clone(pool, box);
|
proc->box = Box_Clone(pool, box);
|
||||||
|
@ -1164,6 +1165,29 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
ExReleaseResourceLite(Process_ListLock);
|
ExReleaseResourceLite(Process_ListLock);
|
||||||
KeLowerIrql(irql);
|
KeLowerIrql(irql);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if this process is set up as break out program,
|
||||||
|
// it must't be located in a sandboxed for this to work.
|
||||||
|
//
|
||||||
|
|
||||||
|
BOX* breakout_box = NULL;
|
||||||
|
|
||||||
|
if (box && Process_IsBreakoutProcess(box, ImagePath)) {
|
||||||
|
|
||||||
|
UNICODE_STRING image_uni;
|
||||||
|
RtlInitUnicodeString(&image_uni, ImagePath);
|
||||||
|
if (!Box_IsBoxedPath(box, file, &image_uni)) {
|
||||||
|
|
||||||
|
check_forced_program = TRUE; // the break out process of one mox may be the forced process of an otehr
|
||||||
|
breakout_box = box;
|
||||||
|
box = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// check forced processes
|
||||||
|
//
|
||||||
|
|
||||||
if (check_forced_program) {
|
if (check_forced_program) {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1171,7 +1195,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
// check if it might be a forced process
|
// check if it might be a forced process
|
||||||
//
|
//
|
||||||
|
|
||||||
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, FALSE);
|
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, FALSE, breakout_box ? breakout_box->sid : NULL);
|
||||||
|
|
||||||
if (box == (BOX *)-1) {
|
if (box == (BOX *)-1) {
|
||||||
|
|
||||||
|
@ -1185,7 +1209,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, TRUE);
|
box = Process_GetForcedStartBox(ProcessId, ParentId, ImagePath, TRUE, breakout_box ? breakout_box->sid : NULL);
|
||||||
|
|
||||||
if (box == (BOX *)-1) {
|
if (box == (BOX *)-1) {
|
||||||
|
|
||||||
|
@ -1202,6 +1226,24 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// if this is a break out process and no other box clamed it as forced,
|
||||||
|
// set bHostInject and threat it accordingly, we need this in order for
|
||||||
|
// the custom SetInformationProcess call from CreateProcessInternalW to succeed
|
||||||
|
//
|
||||||
|
|
||||||
|
if (breakout_box) {
|
||||||
|
if (!box) {
|
||||||
|
bHostInject = TRUE;
|
||||||
|
add_process_to_job = FALSE;
|
||||||
|
box = breakout_box;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Box_Free(breakout_box);
|
||||||
|
breakout_box = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// if parent is a sandboxed process but for some reason we don't
|
// if parent is a sandboxed process but for some reason we don't
|
||||||
// have a box at this point, then terminate the new process
|
// have a box at this point, then terminate the new process
|
||||||
|
@ -1244,7 +1286,7 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
|
|
||||||
if (box) {
|
if (box) {
|
||||||
|
|
||||||
PROCESS *new_proc = Process_Create(ProcessId, box, ImagePath, &irql);
|
PROCESS *new_proc = Process_Create(ProcessId, CallerId, box, ImagePath, &irql);
|
||||||
if (!new_proc) {
|
if (!new_proc) {
|
||||||
|
|
||||||
create_terminated = TRUE;
|
create_terminated = TRUE;
|
||||||
|
@ -1262,8 +1304,12 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
new_proc->rights_dropped = parent_had_rights_dropped;
|
new_proc->rights_dropped = parent_had_rights_dropped;
|
||||||
new_proc->forced_process = process_is_forced;
|
new_proc->forced_process = process_is_forced;
|
||||||
|
|
||||||
if (! bHostInject)
|
if (! bHostInject) {
|
||||||
{
|
|
||||||
|
//
|
||||||
|
// Notify the agent about the new process using a specialized silent message
|
||||||
|
//
|
||||||
|
|
||||||
WCHAR msg[48], *buf = msg;
|
WCHAR msg[48], *buf = msg;
|
||||||
RtlStringCbPrintfW(buf, sizeof(msg), L"%s%c%d", new_proc->box->name, L'\0', (ULONG)ParentId);
|
RtlStringCbPrintfW(buf, sizeof(msg), L"%s%c%d", new_proc->box->name, L'\0', (ULONG)ParentId);
|
||||||
buf += wcslen(buf) + 1;
|
buf += wcslen(buf) + 1;
|
||||||
|
@ -1272,8 +1318,11 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
if (! add_process_to_job)
|
if (! add_process_to_job)
|
||||||
new_proc->parent_was_sandboxed = TRUE;
|
new_proc->parent_was_sandboxed = TRUE;
|
||||||
|
|
||||||
|
add_process_to_job = TRUE; // we need this because of JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK used in GuiServer::GetJobObjectForAssign
|
||||||
|
|
||||||
//
|
//
|
||||||
// don't put the process into a job if OpenWinClass=*
|
// don't put the process into a job if OpenWinClass=*
|
||||||
|
// don't put the process into a job if NoSecurityIsolation=y
|
||||||
//
|
//
|
||||||
|
|
||||||
if (new_proc->open_all_win_classes || new_proc->bAppCompartment || Conf_Get_Boolean(new_proc->box->name, L"NoAddProcessToJob", 0, FALSE)) {
|
if (new_proc->open_all_win_classes || new_proc->bAppCompartment || Conf_Get_Boolean(new_proc->box->name, L"NoAddProcessToJob", 0, FALSE)) {
|
||||||
|
@ -1291,7 +1340,6 @@ _FX BOOLEAN Process_NotifyProcess_Create(
|
||||||
new_proc->can_use_jobs = Conf_Get_Boolean(new_proc->box->name, L"AllowBoxedJobs", 0, FALSE);
|
new_proc->can_use_jobs = Conf_Get_Boolean(new_proc->box->name, L"AllowBoxedJobs", 0, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// on Windows Vista, a forced process may start inside a
|
// on Windows Vista, a forced process may start inside a
|
||||||
// Program Compatibility Assistant (PCA) job, if its parent
|
// Program Compatibility Assistant (PCA) job, if its parent
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct _PROCESS {
|
||||||
// process id
|
// process id
|
||||||
|
|
||||||
HANDLE pid;
|
HANDLE pid;
|
||||||
|
HANDLE starter_id;
|
||||||
|
|
||||||
// process pool. created on process creation. it is freed in its
|
// process pool. created on process creation. it is freed in its
|
||||||
// entirety when the process terminates
|
// entirety when the process terminates
|
||||||
|
@ -242,6 +243,10 @@ BOOLEAN Process_NotifyProcess_Create(
|
||||||
BOOLEAN Process_IsSameBox(PROCESS *proc, PROCESS *proc2, ULONG_PTR proc2_pid);
|
BOOLEAN Process_IsSameBox(PROCESS *proc, PROCESS *proc2, ULONG_PTR proc2_pid);
|
||||||
|
|
||||||
|
|
||||||
|
// Process_IsStarter returns TRUE if proc2 was started by proc1
|
||||||
|
|
||||||
|
BOOLEAN Process_IsStarter(PROCESS* proc1, PROCESS* proc2);
|
||||||
|
|
||||||
// Process_MatchImage: given an image name pattern 'pat_str', which
|
// Process_MatchImage: given an image name pattern 'pat_str', which
|
||||||
// may contain wild cards, tests the image name 'test_str' against
|
// may contain wild cards, tests the image name 'test_str' against
|
||||||
// the pattern. If 'pat_len' is specified, only the first 'pat_len'
|
// the pattern. If 'pat_len' is specified, only the first 'pat_len'
|
||||||
|
@ -382,9 +387,11 @@ NTSTATUS Process_GetSidStringAndSessionId(
|
||||||
// Get a box for a forced sandboxed process
|
// Get a box for a forced sandboxed process
|
||||||
|
|
||||||
BOX *Process_GetForcedStartBox(
|
BOX *Process_GetForcedStartBox(
|
||||||
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject);
|
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject, const WCHAR *pSidString);
|
||||||
|
|
||||||
|
|
||||||
|
BOOLEAN Process_IsBreakoutProcess(BOX *box, const WCHAR *ImagePath);
|
||||||
|
|
||||||
// Manipulation of the List of Disabled Forced Processes: (Process_List2)
|
// Manipulation of the List of Disabled Forced Processes: (Process_List2)
|
||||||
// Add ProcessId to list if ParentId is already listed
|
// Add ProcessId to list if ParentId is already listed
|
||||||
// Hold Process_ListLock before calling, if ParentId != PROCESS_TERMINATED
|
// Hold Process_ListLock before calling, if ParentId != PROCESS_TERMINATED
|
||||||
|
|
|
@ -129,13 +129,14 @@ static void Process_CheckAlertProcess(
|
||||||
static BOX *Process_CheckHostInjectProcess(
|
static BOX *Process_CheckHostInjectProcess(
|
||||||
LIST *boxes, const WCHAR *name);
|
LIST *boxes, const WCHAR *name);
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Process_GetForcedStartBox
|
// Process_GetForcedStartBox
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
_FX BOX *Process_GetForcedStartBox(
|
_FX BOX *Process_GetForcedStartBox(
|
||||||
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject)
|
HANDLE ProcessId, HANDLE ParentId, const WCHAR *ImagePath, BOOLEAN bHostInject, const WCHAR *pSidString)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG SessionId;
|
ULONG SessionId;
|
||||||
|
@ -165,13 +166,16 @@ _FX BOX *Process_GetForcedStartBox(
|
||||||
|
|
||||||
ProcessObject = Process_OpenAndQuery(ProcessId, &SidString, &SessionId);
|
ProcessObject = Process_OpenAndQuery(ProcessId, &SidString, &SessionId);
|
||||||
|
|
||||||
|
if (! pSidString)
|
||||||
|
pSidString = SidString.Buffer;
|
||||||
|
|
||||||
if (! ProcessObject)
|
if (! ProcessObject)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ( !bHostInject && (
|
if ( !bHostInject && (
|
||||||
(_wcsicmp(SidString.Buffer, Driver_S_1_5_18) == 0 ||
|
(_wcsicmp(pSidString, Driver_S_1_5_18) == 0 || // System
|
||||||
_wcsicmp(SidString.Buffer, Driver_S_1_5_19) == 0 ||
|
_wcsicmp(pSidString, Driver_S_1_5_19) == 0 || // Local Service
|
||||||
_wcsicmp(SidString.Buffer, Driver_S_1_5_20) == 0)
|
_wcsicmp(pSidString, Driver_S_1_5_20) == 0) // Network Service
|
||||||
&& (! Process_IsDcomLaunchParent(ParentId))) ){
|
&& (! Process_IsDcomLaunchParent(ParentId))) ){
|
||||||
|
|
||||||
status = STATUS_SERVER_SID_MISMATCH; // random status code
|
status = STATUS_SERVER_SID_MISMATCH; // random status code
|
||||||
|
@ -222,7 +226,7 @@ _FX BOX *Process_GetForcedStartBox(
|
||||||
|
|
||||||
alert = 0;
|
alert = 0;
|
||||||
|
|
||||||
Process_CreateForceData(&boxes, SidString.Buffer, SessionId);
|
Process_CreateForceData(&boxes, pSidString, SessionId);
|
||||||
|
|
||||||
//
|
//
|
||||||
// check if process can be forced
|
// check if process can be forced
|
||||||
|
@ -832,6 +836,153 @@ _FX BOOLEAN Process_IsImmersiveProcess(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Process_AddForceFolders
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX void Process_AddForceFolders(
|
||||||
|
LIST* Folders, const WCHAR* Setting, FORCE_BOX *box, const WCHAR *section)
|
||||||
|
{
|
||||||
|
ULONG index2;
|
||||||
|
const WCHAR *value;
|
||||||
|
FORCE_FOLDER *folder;
|
||||||
|
|
||||||
|
index2 = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
WCHAR *expnd, *buf;
|
||||||
|
ULONG buf_len;
|
||||||
|
|
||||||
|
value = Conf_Get(section, Setting, index2);
|
||||||
|
if (! value)
|
||||||
|
break;
|
||||||
|
++index2;
|
||||||
|
|
||||||
|
expnd = Conf_Expand(box->box->expand_args, value, Setting);
|
||||||
|
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
if (expnd) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// remove duplicate backslashes and translate reparse points
|
||||||
|
//
|
||||||
|
|
||||||
|
WCHAR *tmp1, *tmp2;
|
||||||
|
buf_len = (wcslen(expnd) + 1) * sizeof(WCHAR);
|
||||||
|
tmp1 = Mem_Alloc(Driver_Pool, buf_len);
|
||||||
|
|
||||||
|
if (tmp1) {
|
||||||
|
|
||||||
|
WCHAR *src_ptr = expnd;
|
||||||
|
WCHAR *dst_ptr = tmp1;
|
||||||
|
while (*src_ptr) {
|
||||||
|
if (src_ptr[0] == L'\\' && src_ptr[1] == L'\\') {
|
||||||
|
++src_ptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*dst_ptr = *src_ptr;
|
||||||
|
++src_ptr;
|
||||||
|
++dst_ptr;
|
||||||
|
}
|
||||||
|
*dst_ptr = L'\0';
|
||||||
|
|
||||||
|
tmp2 = File_TranslateReparsePoints(tmp1, Driver_Pool);
|
||||||
|
if (tmp2) {
|
||||||
|
|
||||||
|
Mem_Free(tmp1, buf_len);
|
||||||
|
buf = tmp2;
|
||||||
|
buf_len = (wcslen(buf) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
} else
|
||||||
|
buf = tmp1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem_FreeString(expnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! buf)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
folder = Mem_Alloc(Driver_Pool, sizeof(FORCE_FOLDER));
|
||||||
|
if (! folder) {
|
||||||
|
Mem_Free(buf, buf_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wcschr(buf, L'*')) {
|
||||||
|
|
||||||
|
folder->pat =
|
||||||
|
Pattern_Create(box->box->expand_args->pool, buf, TRUE, 0);
|
||||||
|
|
||||||
|
Mem_Free(buf, buf_len);
|
||||||
|
|
||||||
|
if (! folder->pat) {
|
||||||
|
Mem_Free(folder, sizeof(FORCE_FOLDER));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
folder->buf_len = 0;
|
||||||
|
folder->len = 0;
|
||||||
|
folder->buf = NULL;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ULONG len = wcslen(buf);
|
||||||
|
while (len && buf[len - 1] == L'\\')
|
||||||
|
--len;
|
||||||
|
|
||||||
|
folder->buf_len = buf_len;
|
||||||
|
folder->len = len;
|
||||||
|
folder->buf = buf;
|
||||||
|
|
||||||
|
folder->pat = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
List_Insert_After(Folders, NULL, folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Process_AddForceProcesses
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX void Process_AddForceProcesses(
|
||||||
|
LIST* Processes, const WCHAR* Setting, const WCHAR *section)
|
||||||
|
{
|
||||||
|
ULONG index2;
|
||||||
|
const WCHAR *value;
|
||||||
|
FORCE_PROCESS *process;
|
||||||
|
|
||||||
|
index2 = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
value = Conf_Get(section, Setting, index2);
|
||||||
|
if (! value)
|
||||||
|
break;
|
||||||
|
++index2;
|
||||||
|
|
||||||
|
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
|
||||||
|
if (! process)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Ideally, RtlStringCchCopy() would be used here - Build issues
|
||||||
|
RtlZeroMemory(process->value, sizeof(process->value));
|
||||||
|
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
|
||||||
|
{
|
||||||
|
wcscpy(process->value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
List_Insert_After(Processes, NULL, process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Process_CreateForceData
|
// Process_CreateForceData
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -840,12 +991,9 @@ _FX BOOLEAN Process_IsImmersiveProcess(
|
||||||
_FX void Process_CreateForceData(
|
_FX void Process_CreateForceData(
|
||||||
LIST *boxes, const WCHAR *SidString, ULONG SessionId)
|
LIST *boxes, const WCHAR *SidString, ULONG SessionId)
|
||||||
{
|
{
|
||||||
ULONG index1, index2;
|
ULONG index1;
|
||||||
const WCHAR *section;
|
const WCHAR *section;
|
||||||
const WCHAR *value;
|
|
||||||
FORCE_BOX *box;
|
FORCE_BOX *box;
|
||||||
FORCE_FOLDER *folder;
|
|
||||||
FORCE_PROCESS *process;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan list of boxes and create FORCE_BOX elements
|
// scan list of boxes and create FORCE_BOX elements
|
||||||
|
@ -894,291 +1042,86 @@ _FX void Process_CreateForceData(
|
||||||
// scan list of ForceFolder settings for the box
|
// scan list of ForceFolder settings for the box
|
||||||
//
|
//
|
||||||
|
|
||||||
index2 = 0;
|
Process_AddForceFolders(&box->ForceFolder, L"ForceFolder", box, section);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
static const WCHAR *_ForceFolder = L"ForceFolder";
|
|
||||||
WCHAR *expnd, *buf;
|
|
||||||
ULONG buf_len;
|
|
||||||
|
|
||||||
value = Conf_Get(section, _ForceFolder, index2);
|
|
||||||
if (! value)
|
|
||||||
break;
|
|
||||||
++index2;
|
|
||||||
|
|
||||||
expnd = Conf_Expand(box->box->expand_args, value, _ForceFolder);
|
|
||||||
|
|
||||||
buf = NULL;
|
|
||||||
|
|
||||||
if (expnd) {
|
|
||||||
|
|
||||||
//
|
|
||||||
// remove duplicate backslashes and translate reparse points
|
|
||||||
//
|
|
||||||
|
|
||||||
WCHAR *tmp1, *tmp2;
|
|
||||||
buf_len = (wcslen(expnd) + 1) * sizeof(WCHAR);
|
|
||||||
tmp1 = Mem_Alloc(Driver_Pool, buf_len);
|
|
||||||
|
|
||||||
if (tmp1) {
|
|
||||||
|
|
||||||
WCHAR *src_ptr = expnd;
|
|
||||||
WCHAR *dst_ptr = tmp1;
|
|
||||||
while (*src_ptr) {
|
|
||||||
if (src_ptr[0] == L'\\' && src_ptr[1] == L'\\') {
|
|
||||||
++src_ptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*dst_ptr = *src_ptr;
|
|
||||||
++src_ptr;
|
|
||||||
++dst_ptr;
|
|
||||||
}
|
|
||||||
*dst_ptr = L'\0';
|
|
||||||
|
|
||||||
tmp2 = File_TranslateReparsePoints(tmp1, Driver_Pool);
|
|
||||||
if (tmp2) {
|
|
||||||
|
|
||||||
Mem_Free(tmp1, buf_len);
|
|
||||||
buf = tmp2;
|
|
||||||
buf_len = (wcslen(buf) + 1) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
} else
|
|
||||||
buf = tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem_FreeString(expnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! buf)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
folder = Mem_Alloc(Driver_Pool, sizeof(FORCE_FOLDER));
|
|
||||||
if (! folder) {
|
|
||||||
Mem_Free(buf, buf_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wcschr(buf, L'*')) {
|
|
||||||
|
|
||||||
folder->pat =
|
|
||||||
Pattern_Create(box->box->expand_args->pool, buf, TRUE, 0);
|
|
||||||
|
|
||||||
Mem_Free(buf, buf_len);
|
|
||||||
|
|
||||||
if (! folder->pat) {
|
|
||||||
Mem_Free(folder, sizeof(FORCE_FOLDER));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
folder->buf_len = 0;
|
|
||||||
folder->len = 0;
|
|
||||||
folder->buf = NULL;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
ULONG len = wcslen(buf);
|
|
||||||
while (len && buf[len - 1] == L'\\')
|
|
||||||
--len;
|
|
||||||
|
|
||||||
folder->buf_len = buf_len;
|
|
||||||
folder->len = len;
|
|
||||||
folder->buf = buf;
|
|
||||||
|
|
||||||
folder->pat = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
List_Insert_After(&box->ForceFolder, NULL, folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan list of ForceProcess settings for the box
|
// scan list of ForceProcess settings for the box
|
||||||
//
|
//
|
||||||
|
|
||||||
index2 = 0;
|
Process_AddForceProcesses(&box->ForceProcess, L"ForceProcess", section);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
value = Conf_Get(section, L"ForceProcess", index2);
|
|
||||||
if (! value)
|
|
||||||
break;
|
|
||||||
++index2;
|
|
||||||
|
|
||||||
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
|
|
||||||
if (! process)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Ideally, RtlStringCchCopy() would be used here - Build issues
|
|
||||||
RtlZeroMemory(process->value, sizeof(process->value));
|
|
||||||
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
|
|
||||||
{
|
|
||||||
wcscpy(process->value, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
List_Insert_After(&box->ForceProcess, NULL, process);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan list of AlertFolder settings for the box
|
// scan list of AlertFolder settings for the box
|
||||||
//
|
//
|
||||||
|
|
||||||
index2 = 0;
|
Process_AddForceFolders(&box->AlertFolder, L"AlertFolder", box, section);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
static const WCHAR *_AlertFolder = L"AlertFolder";
|
|
||||||
WCHAR *expnd, *buf;
|
|
||||||
ULONG buf_len;
|
|
||||||
|
|
||||||
value = Conf_Get(section, _AlertFolder, index2);
|
|
||||||
if (! value)
|
|
||||||
break;
|
|
||||||
++index2;
|
|
||||||
|
|
||||||
expnd = Conf_Expand(box->box->expand_args, value, _AlertFolder);
|
|
||||||
|
|
||||||
buf = NULL;
|
|
||||||
|
|
||||||
if (expnd) {
|
|
||||||
|
|
||||||
//
|
|
||||||
// remove duplicate backslashes and translate reparse points
|
|
||||||
//
|
|
||||||
|
|
||||||
WCHAR *tmp1, *tmp2;
|
|
||||||
buf_len = (wcslen(expnd) + 1) * sizeof(WCHAR);
|
|
||||||
tmp1 = Mem_Alloc(Driver_Pool, buf_len);
|
|
||||||
|
|
||||||
if (tmp1) {
|
|
||||||
|
|
||||||
WCHAR *src_ptr = expnd;
|
|
||||||
WCHAR *dst_ptr = tmp1;
|
|
||||||
while (*src_ptr) {
|
|
||||||
if (src_ptr[0] == L'\\' && src_ptr[1] == L'\\') {
|
|
||||||
++src_ptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*dst_ptr = *src_ptr;
|
|
||||||
++src_ptr;
|
|
||||||
++dst_ptr;
|
|
||||||
}
|
|
||||||
*dst_ptr = L'\0';
|
|
||||||
|
|
||||||
tmp2 = File_TranslateReparsePoints(tmp1, Driver_Pool);
|
|
||||||
if (tmp2) {
|
|
||||||
|
|
||||||
Mem_Free(tmp1, buf_len);
|
|
||||||
buf = tmp2;
|
|
||||||
buf_len = (wcslen(buf) + 1) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
} else
|
|
||||||
buf = tmp1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mem_FreeString(expnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! buf)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
folder = Mem_Alloc(Driver_Pool, sizeof(FORCE_FOLDER));
|
|
||||||
if (! folder) {
|
|
||||||
Mem_Free(buf, buf_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wcschr(buf, L'*')) {
|
|
||||||
|
|
||||||
folder->pat =
|
|
||||||
Pattern_Create(box->box->expand_args->pool, buf, TRUE, 0);
|
|
||||||
|
|
||||||
Mem_Free(buf, buf_len);
|
|
||||||
|
|
||||||
if (! folder->pat) {
|
|
||||||
Mem_Free(folder, sizeof(FORCE_FOLDER));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
folder->buf_len = 0;
|
|
||||||
folder->len = 0;
|
|
||||||
folder->buf = NULL;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
ULONG len = wcslen(buf);
|
|
||||||
while (len && buf[len - 1] == L'\\')
|
|
||||||
--len;
|
|
||||||
|
|
||||||
folder->buf_len = buf_len;
|
|
||||||
folder->len = len;
|
|
||||||
folder->buf = buf;
|
|
||||||
|
|
||||||
folder->pat = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
List_Insert_After(&box->AlertFolder, NULL, folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan list of AlertProcess settings for the box
|
// scan list of AlertProcess settings for the box
|
||||||
//
|
//
|
||||||
|
|
||||||
index2 = 0;
|
Process_AddForceProcesses(&box->AlertProcess, L"AlertProcess", section);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
value = Conf_Get(section, L"AlertProcess", index2);
|
|
||||||
if (! value)
|
|
||||||
break;
|
|
||||||
++index2;
|
|
||||||
|
|
||||||
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
|
|
||||||
if (! process)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Ideally, RtlStringCchCopy() would be used here - Build issues
|
|
||||||
RtlZeroMemory(process->value, sizeof(process->value));
|
|
||||||
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
|
|
||||||
{
|
|
||||||
wcscpy(process->value, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
List_Insert_After(&box->AlertProcess, NULL, process);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// scan list of HostInjectProcess settings for the box
|
// scan list of HostInjectProcess settings for the box
|
||||||
//
|
//
|
||||||
|
|
||||||
index2 = 0;
|
Process_AddForceProcesses(&box->HostInjectProcess, L"HostInjectProcess", section);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
value = Conf_Get(section, L"HostInjectProcess", index2);
|
|
||||||
if (! value)
|
|
||||||
break;
|
|
||||||
++index2;
|
|
||||||
|
|
||||||
process = Mem_Alloc(Driver_Pool, sizeof(FORCE_PROCESS));
|
|
||||||
if (! process)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Ideally, RtlStringCchCopy() would be used here - Build issues
|
|
||||||
RtlZeroMemory(process->value, sizeof(process->value));
|
|
||||||
if (wcslen(value) < MAX_FORCE_PROCESS_VALUE_LEN)
|
|
||||||
{
|
|
||||||
wcscpy(process->value, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
List_Insert_After(&box->HostInjectProcess, NULL, process);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Conf_AdjustUseCount(FALSE);
|
Conf_AdjustUseCount(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Process_DeleteForceDataFolders
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX void Process_DeleteForceDataFolders(LIST* Folders)
|
||||||
|
{
|
||||||
|
FORCE_FOLDER *folder;
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
folder = List_Head(Folders);
|
||||||
|
if (!folder)
|
||||||
|
break;
|
||||||
|
|
||||||
|
List_Remove(Folders, folder);
|
||||||
|
|
||||||
|
if (folder->pat)
|
||||||
|
Pattern_Free(folder->pat);
|
||||||
|
else
|
||||||
|
Mem_Free(folder->buf, folder->buf_len);
|
||||||
|
|
||||||
|
Mem_Free(folder, sizeof(FORCE_FOLDER));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Process_DeleteForceDataProcesses
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX void Process_DeleteForceDataProcesses(LIST* Folders)
|
||||||
|
{
|
||||||
|
FORCE_PROCESS *process;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
process = List_Head(Folders);
|
||||||
|
if (! process)
|
||||||
|
break;
|
||||||
|
|
||||||
|
List_Remove(Folders, process);
|
||||||
|
|
||||||
|
Mem_Free(process, sizeof(FORCE_PROCESS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Process_DeleteForceData
|
// Process_DeleteForceData
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -1187,8 +1130,6 @@ _FX void Process_CreateForceData(
|
||||||
_FX void Process_DeleteForceData(LIST *boxes)
|
_FX void Process_DeleteForceData(LIST *boxes)
|
||||||
{
|
{
|
||||||
FORCE_BOX *box;
|
FORCE_BOX *box;
|
||||||
FORCE_FOLDER *folder;
|
|
||||||
FORCE_PROCESS *process;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
|
@ -1198,70 +1139,11 @@ _FX void Process_DeleteForceData(LIST *boxes)
|
||||||
|
|
||||||
List_Remove(boxes, box);
|
List_Remove(boxes, box);
|
||||||
|
|
||||||
while (1) {
|
Process_DeleteForceDataFolders(&box->ForceFolder);
|
||||||
|
Process_DeleteForceDataProcesses(&box->ForceProcess);
|
||||||
folder = List_Head(&box->ForceFolder);
|
Process_DeleteForceDataFolders(&box->AlertFolder);
|
||||||
if (! folder)
|
Process_DeleteForceDataProcesses(&box->AlertProcess);
|
||||||
break;
|
Process_DeleteForceDataProcesses(&box->HostInjectProcess);
|
||||||
|
|
||||||
List_Remove(&box->ForceFolder, folder);
|
|
||||||
|
|
||||||
if (folder->pat)
|
|
||||||
Pattern_Free(folder->pat);
|
|
||||||
else
|
|
||||||
Mem_Free(folder->buf, folder->buf_len);
|
|
||||||
|
|
||||||
Mem_Free(folder, sizeof(FORCE_FOLDER));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
process = List_Head(&box->ForceProcess);
|
|
||||||
if (! process)
|
|
||||||
break;
|
|
||||||
|
|
||||||
List_Remove(&box->ForceProcess, process);
|
|
||||||
|
|
||||||
Mem_Free(process, sizeof(FORCE_PROCESS));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
folder = List_Head(&box->AlertFolder);
|
|
||||||
if (!folder)
|
|
||||||
break;
|
|
||||||
|
|
||||||
List_Remove(&box->AlertFolder, folder);
|
|
||||||
|
|
||||||
if (folder->pat)
|
|
||||||
Pattern_Free(folder->pat);
|
|
||||||
else
|
|
||||||
Mem_Free(folder->buf, folder->buf_len);
|
|
||||||
|
|
||||||
Mem_Free(folder, sizeof(FORCE_FOLDER));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
process = List_Head(&box->AlertProcess);
|
|
||||||
if (! process)
|
|
||||||
break;
|
|
||||||
|
|
||||||
List_Remove(&box->AlertProcess, process);
|
|
||||||
|
|
||||||
Mem_Free(process, sizeof(FORCE_PROCESS));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
process = List_Head(&box->HostInjectProcess);
|
|
||||||
if (! process)
|
|
||||||
break;
|
|
||||||
|
|
||||||
List_Remove(&box->HostInjectProcess, process);
|
|
||||||
|
|
||||||
Mem_Free(process, sizeof(FORCE_PROCESS));
|
|
||||||
}
|
|
||||||
|
|
||||||
Box_Free(box->box);
|
Box_Free(box->box);
|
||||||
|
|
||||||
|
@ -1627,6 +1509,73 @@ _FX BOX *Process_CheckHostInjectProcess(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Process_DfpInsert
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX BOOLEAN Process_IsBreakoutProcess(
|
||||||
|
BOX *box, const WCHAR *ImagePath)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
LIST BreakoutProcess;
|
||||||
|
WCHAR *ImagePath2 = L"";
|
||||||
|
ULONG ImagePath2_len;
|
||||||
|
const WCHAR *ImageName = L"";
|
||||||
|
BOOLEAN IsBreakout = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get adjusted image path and image name
|
||||||
|
//
|
||||||
|
|
||||||
|
status = Process_TranslateDosToNt(
|
||||||
|
ImagePath, &ImagePath2, &ImagePath2_len);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(status)) {
|
||||||
|
|
||||||
|
ImageName = wcsrchr(ImagePath2, L'\\');
|
||||||
|
if (ImageName && ImageName[1])
|
||||||
|
++ImageName;
|
||||||
|
else
|
||||||
|
status = STATUS_OBJECT_PATH_SYNTAX_BAD; // random
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(status)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List_Init(&BreakoutProcess);
|
||||||
|
|
||||||
|
Conf_AdjustUseCount(TRUE);
|
||||||
|
|
||||||
|
Process_AddForceProcesses(&BreakoutProcess, L"BreakoutProcess", box->name);
|
||||||
|
|
||||||
|
Conf_AdjustUseCount(FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
FORCE_PROCESS *process = List_Head(&BreakoutProcess);
|
||||||
|
while (process) {
|
||||||
|
|
||||||
|
const WCHAR *value = process->value;
|
||||||
|
if (Process_MatchImage(box, value, 0, ImageName, 1)) {
|
||||||
|
|
||||||
|
IsBreakout = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
process = List_Next(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
Process_DeleteForceDataProcesses(&BreakoutProcess);
|
||||||
|
|
||||||
|
Mem_Free(ImagePath2, ImagePath2_len);
|
||||||
|
|
||||||
|
return IsBreakout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Process_DfpInsert
|
// Process_DfpInsert
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -113,6 +113,24 @@ _FX BOOLEAN Process_IsSameBox(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Process_IsStarter
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
_FX BOOLEAN Process_IsStarter(
|
||||||
|
PROCESS* proc1, PROCESS* proc2)
|
||||||
|
{
|
||||||
|
if (proc1->create_time > proc2->create_time)
|
||||||
|
return FALSE; // reused pid? the new process can not be older than the on that started it
|
||||||
|
|
||||||
|
if (proc1->box->session_id != proc2->box->session_id)
|
||||||
|
return FALSE; // SID must be same
|
||||||
|
|
||||||
|
return proc1->pid == proc2->starter_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Process_MatchImage
|
// Process_MatchImage
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
|
@ -376,7 +376,7 @@ _FX PROCESS *Thread_FindAndInitProcess(
|
||||||
PROCESS *proc2 = Process_Find(PsGetProcessId(ProcessObject2), out_irql);
|
PROCESS *proc2 = Process_Find(PsGetProcessId(ProcessObject2), out_irql);
|
||||||
if (proc2) {
|
if (proc2) {
|
||||||
|
|
||||||
if (! Process_IsSameBox(proc1, proc2, 0))
|
if (! Process_IsSameBox(proc1, proc2, 0) && ! Process_IsStarter(proc1, proc2))
|
||||||
proc2 = NULL;
|
proc2 = NULL;
|
||||||
|
|
||||||
else if (! proc2->threads_lock) {
|
else if (! proc2->threads_lock) {
|
||||||
|
|
|
@ -1031,16 +1031,6 @@ HANDLE GuiServer::GetJobObjectForAssign(const WCHAR *boxname)
|
||||||
hJobObject = CreateJobObject(&sa, jobname);
|
hJobObject = CreateJobObject(&sa, jobname);
|
||||||
if (hJobObject) {
|
if (hJobObject) {
|
||||||
|
|
||||||
//
|
|
||||||
// set UI restrictions on the job object
|
|
||||||
//
|
|
||||||
|
|
||||||
JOBOBJECT_BASIC_UI_RESTRICTIONS info;
|
|
||||||
info.UIRestrictionsClass = JOB_OBJECT_UILIMIT_EXITWINDOWS
|
|
||||||
| JOB_OBJECT_UILIMIT_HANDLES
|
|
||||||
| JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS
|
|
||||||
| JOB_OBJECT_UILIMIT_READCLIPBOARD;
|
|
||||||
|
|
||||||
BOOL ok = FALSE; // set TRUE to skip UIRestrictions
|
BOOL ok = FALSE; // set TRUE to skip UIRestrictions
|
||||||
|
|
||||||
// OriginalToken BEGIN
|
// OriginalToken BEGIN
|
||||||
|
@ -1053,6 +1043,17 @@ HANDLE GuiServer::GetJobObjectForAssign(const WCHAR *boxname)
|
||||||
// UnrestrictedToken END
|
// UnrestrictedToken END
|
||||||
|
|
||||||
if (! ok) {
|
if (! ok) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// set UI restrictions on the job object
|
||||||
|
//
|
||||||
|
|
||||||
|
JOBOBJECT_BASIC_UI_RESTRICTIONS info;
|
||||||
|
info.UIRestrictionsClass = JOB_OBJECT_UILIMIT_EXITWINDOWS
|
||||||
|
| JOB_OBJECT_UILIMIT_HANDLES
|
||||||
|
| JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS
|
||||||
|
| JOB_OBJECT_UILIMIT_READCLIPBOARD;
|
||||||
|
|
||||||
ok = SetInformationJobObject(
|
ok = SetInformationJobObject(
|
||||||
hJobObject, JobObjectBasicUIRestrictions,
|
hJobObject, JobObjectBasicUIRestrictions,
|
||||||
&info, sizeof(info));
|
&info, sizeof(info));
|
||||||
|
@ -1067,6 +1068,21 @@ HANDLE GuiServer::GetJobObjectForAssign(const WCHAR *boxname)
|
||||||
ok = UserHandleGrantAccess(
|
ok = UserHandleGrantAccess(
|
||||||
GetDesktopWindow(), hJobObject, TRUE);
|
GetDesktopWindow(), hJobObject, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// we want to allow sandboxed processes to use jobs of thair own
|
||||||
|
// with windows 8 we can have nested, a boxed process may want to use BREAKAWAY
|
||||||
|
// hence we no longer prevent breaking away from our job,
|
||||||
|
// instead we re assign the job on each initialization, like it was done for the initial one
|
||||||
|
//
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobELInfo = {0};
|
||||||
|
jobELInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_BREAKAWAY_OK
|
||||||
|
| JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
|
||||||
|
|
||||||
|
ok = SetInformationJobObject(hJobObject, JobObjectExtendedLimitInformation, &jobELInfo, sizeof(jobELInfo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (! ok) {
|
if (! ok) {
|
||||||
// this should not happen
|
// this should not happen
|
||||||
|
|
Loading…
Reference in New Issue