Commit 2fe70331 authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

ntdll: Implement JobObjectBasicProcessIdList for NtQueryInformationJobObject.

parent bf5f7a7b
...@@ -2700,15 +2700,11 @@ static void test_QueryInformationJobObject(void) ...@@ -2700,15 +2700,11 @@ static void test_QueryInformationJobObject(void)
pid_list->NumberOfProcessIdsInList = 42; pid_list->NumberOfProcessIdsInList = 42;
ret = QueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, ret = QueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list,
FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[1]), &ret_len); FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[1]), &ret_len);
todo_wine
ok(!ret, "QueryInformationJobObject expected failure\n"); ok(!ret, "QueryInformationJobObject expected failure\n");
todo_wine
expect_eq_d(ERROR_MORE_DATA, GetLastError()); expect_eq_d(ERROR_MORE_DATA, GetLastError());
if (ret) if (ret)
{ {
todo_wine
expect_eq_d(42, pid_list->NumberOfAssignedProcesses); expect_eq_d(42, pid_list->NumberOfAssignedProcesses);
todo_wine
expect_eq_d(42, pid_list->NumberOfProcessIdsInList); expect_eq_d(42, pid_list->NumberOfProcessIdsInList);
} }
...@@ -2723,17 +2719,12 @@ static void test_QueryInformationJobObject(void) ...@@ -2723,17 +2719,12 @@ static void test_QueryInformationJobObject(void)
{ {
ULONG_PTR *list = pid_list->ProcessIdList; ULONG_PTR *list = pid_list->ProcessIdList;
todo_wine
ok(ret_len == FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[2]), ok(ret_len == FIELD_OFFSET(JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[2]),
"QueryInformationJobObject returned ret_len=%u\n", ret_len); "QueryInformationJobObject returned ret_len=%u\n", ret_len);
todo_wine
expect_eq_d(2, pid_list->NumberOfAssignedProcesses); expect_eq_d(2, pid_list->NumberOfAssignedProcesses);
todo_wine
expect_eq_d(2, pid_list->NumberOfProcessIdsInList); expect_eq_d(2, pid_list->NumberOfProcessIdsInList);
todo_wine
expect_eq_d(pi[0].dwProcessId, list[0]); expect_eq_d(pi[0].dwProcessId, list[0]);
todo_wine
expect_eq_d(pi[1].dwProcessId, list[1]); expect_eq_d(pi[1].dwProcessId, list[1]);
} }
} }
......
...@@ -791,11 +791,40 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c ...@@ -791,11 +791,40 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c
case JobObjectBasicProcessIdList: case JobObjectBasicProcessIdList:
{ {
JOBOBJECT_BASIC_PROCESS_ID_LIST *process = info; JOBOBJECT_BASIC_PROCESS_ID_LIST *process = info;
DWORD count, i;
if (len < sizeof(*process)) return STATUS_INFO_LENGTH_MISMATCH; if (len < sizeof(*process)) return STATUS_INFO_LENGTH_MISMATCH;
memset( process, 0, sizeof(*process) );
if (ret_len) *ret_len = sizeof(*process); count = len - offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList );
return STATUS_SUCCESS; count /= sizeof(process->ProcessIdList[0]);
SERVER_START_REQ( get_job_info )
{
req->handle = wine_server_user_handle(handle);
wine_server_set_reply(req, process->ProcessIdList, count * sizeof(process_id_t));
if (!(ret = wine_server_call(req)))
{
process->NumberOfAssignedProcesses = reply->active_processes;
process->NumberOfProcessIdsInList = min(count, reply->active_processes);
}
}
SERVER_END_REQ;
if (ret != STATUS_SUCCESS) return ret;
if (sizeof(process_id_t) < sizeof(process->ProcessIdList[0]))
{
/* start from the end to not overwrite */
for (i = process->NumberOfProcessIdsInList; i--;)
{
ULONG_PTR id = ((process_id_t *)process->ProcessIdList)[i];
process->ProcessIdList[i] = id;
}
}
if (ret_len)
*ret_len = offsetof( JOBOBJECT_BASIC_PROCESS_ID_LIST, ProcessIdList[process->NumberOfProcessIdsInList] );
return count < process->NumberOfAssignedProcesses ? STATUS_MORE_ENTRIES : STATUS_SUCCESS;
} }
case JobObjectExtendedLimitInformation: case JobObjectExtendedLimitInformation:
{ {
......
...@@ -5357,6 +5357,7 @@ struct get_job_info_reply ...@@ -5357,6 +5357,7 @@ struct get_job_info_reply
struct reply_header __header; struct reply_header __header;
int total_processes; int total_processes;
int active_processes; int active_processes;
/* VARARG(pids,uints); */
}; };
...@@ -6256,7 +6257,7 @@ union generic_reply ...@@ -6256,7 +6257,7 @@ union generic_reply
/* ### protocol_version begin ### */ /* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 730 #define SERVER_PROTOCOL_VERSION 731
/* ### protocol_version end ### */ /* ### protocol_version end ### */
......
...@@ -286,6 +286,24 @@ static int process_in_job( struct job *job, struct process *process ) ...@@ -286,6 +286,24 @@ static int process_in_job( struct job *job, struct process *process )
return process->job == job; return process->job == job;
} }
static process_id_t *get_job_pids( struct job *job, process_id_t *pids, process_id_t *end )
{
struct process *process;
struct job *j;
LIST_FOR_EACH_ENTRY( j, &job->child_job_list, struct job, parent_job_entry )
pids = get_job_pids( j, pids, end );
LIST_FOR_EACH_ENTRY( process, &job->process_list, struct process, job_entry )
{
if (pids == end) break;
if (process->end_time) continue; /* skip processes that ended */
*pids++ = process->id;
}
return pids;
}
static void add_job_process( struct job *job, struct process *process ) static void add_job_process( struct job *job, struct process *process )
{ {
struct job *j, *common_parent; struct job *j, *common_parent;
...@@ -1745,11 +1763,18 @@ DECL_HANDLER(process_in_job) ...@@ -1745,11 +1763,18 @@ DECL_HANDLER(process_in_job)
DECL_HANDLER(get_job_info) DECL_HANDLER(get_job_info)
{ {
struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_QUERY ); struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_QUERY );
process_id_t *pids;
data_size_t len;
if (!job) return; if (!job) return;
reply->total_processes = job->total_processes; reply->total_processes = job->total_processes;
reply->active_processes = job->num_processes; reply->active_processes = job->num_processes;
len = min( get_reply_max_size(), reply->active_processes * sizeof(*pids) );
if (len && ((pids = set_reply_data_size( len ))))
get_job_pids( job, pids, pids + len / sizeof(*pids) );
release_object( job ); release_object( job );
} }
......
...@@ -3696,6 +3696,7 @@ struct handle_info ...@@ -3696,6 +3696,7 @@ struct handle_info
@REPLY @REPLY
int total_processes; /* total count of processes */ int total_processes; /* total count of processes */
int active_processes; /* count of running processes */ int active_processes; /* count of running processes */
VARARG(pids,uints); /* list of active pids */
@END @END
......
...@@ -4525,6 +4525,7 @@ static void dump_get_job_info_reply( const struct get_job_info_reply *req ) ...@@ -4525,6 +4525,7 @@ static void dump_get_job_info_reply( const struct get_job_info_reply *req )
{ {
fprintf( stderr, " total_processes=%d", req->total_processes ); fprintf( stderr, " total_processes=%d", req->total_processes );
fprintf( stderr, ", active_processes=%d", req->active_processes ); fprintf( stderr, ", active_processes=%d", req->active_processes );
dump_varargs_uints( ", pids=", cur_size );
} }
static void dump_terminate_job_request( const struct terminate_job_request *req ) static void dump_terminate_job_request( const struct terminate_job_request *req )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment