Fixes a regression introduced by 21f5597de417575d476a00b567d972a89903b4b6
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- v2: - don't allow even if the job had the processes in the past (the test is updated to reflect that).
dlls/kernel32/tests/process.c | 60 +++++++++++++++++++++++++++++++++++ server/process.c | 5 +++ 2 files changed, 65 insertions(+)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 9b91b6f0998..10786c52e9e 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -4502,6 +4502,7 @@ done:
static void test_nested_jobs(void) { + BOOL ret, already_in_job = TRUE, create_succeeded = FALSE; PROCESS_INFORMATION info[2]; char buffer[MAX_PATH + 26]; STARTUPINFOA si = {0}; @@ -4514,6 +4515,65 @@ static void test_nested_jobs(void) return; }
+ job1 = pCreateJobObjectW(NULL, NULL); + ok(!!job1, "CreateJobObjectW failed, error %u.\n", GetLastError()); + job2 = pCreateJobObjectW(NULL, NULL); + ok(!!job2, "CreateJobObjectW failed, error %u.\n", GetLastError()); + + create_succeeded = TRUE; + sprintf(buffer, ""%s" process wait", selfname); + for (i = 0; i < 2; ++i) + { + ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &info[i]); + if (!ret && GetLastError() == ERROR_ACCESS_DENIED) + { + create_succeeded = FALSE; + break; + } + ok(ret, "CreateProcessA error %u\n", GetLastError()); + } + + if (create_succeeded) + { + ret = pIsProcessInJob(info[0].hProcess, NULL, &already_in_job); + ok(ret, "IsProcessInJob error %u\n", GetLastError()); + + if (!already_in_job) + { + ret = pAssignProcessToJobObject(job2, info[1].hProcess); + ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); + + ret = pAssignProcessToJobObject(job1, info[0].hProcess); + ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); + + ret = pAssignProcessToJobObject(job2, info[0].hProcess); + ok(!ret, "AssignProcessToJobObject succeeded\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "Got unexpected error %u.\n", GetLastError()); + + TerminateProcess(info[1].hProcess, 0); + wait_child_process(info[1].hProcess); + CloseHandle(info[1].hProcess); + CloseHandle(info[1].hThread); + + ret = pAssignProcessToJobObject(job2, info[0].hProcess); + ok(!ret, "AssignProcessToJobObject succeeded\n"); + ok(GetLastError() == ERROR_ACCESS_DENIED, "Got unexpected error %u.\n", GetLastError()); + } + + TerminateProcess(info[0].hProcess, 0); + wait_child_process(info[0].hProcess); + CloseHandle(info[0].hProcess); + CloseHandle(info[0].hThread); + } + + if (already_in_job) + { + win_skip("Test process is already in job, can't test parenting non-empty job.\n"); + } + + CloseHandle(job1); + CloseHandle(job2); + job1 = pCreateJobObjectW(NULL, L"test_nested_jobs_0"); ok(!!job1, "CreateJobObjectW failed, error %u.\n", GetLastError()); job2 = pCreateJobObjectW(NULL, L"test_nested_jobs_1"); diff --git a/server/process.c b/server/process.c index e8bbe0d3106..2887bb9d566 100644 --- a/server/process.c +++ b/server/process.c @@ -312,6 +312,11 @@ static void add_job_process( struct job *job, struct process *process ) } else { + if (job->total_processes) + { + set_error( STATUS_ACCESS_DENIED ); + return; + } /* transfer reference. */ job->parent = process->job; list_add_tail( &job->parent->child_job_list, &job->parent_job_entry );