[PATCH] ntdll: Partially implement JobObjectBasicAccountingInformation.
Derek Lesho
dlesho at codeweavers.com
Mon Feb 24 13:32:38 CST 2020
Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
v2:
- Fix a typo breaking the patch.
---
dlls/kernel32/tests/process.c | 9 +++++++++
dlls/ntdll/sync.c | 20 +++++++++++++++++---
server/process.c | 14 ++++++++++++++
server/protocol.def | 8 ++++++++
4 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 323f8092d7..421d030e63 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2543,6 +2543,7 @@ static void test_QueryInformationJobObject(void)
PJOBOBJECT_BASIC_PROCESS_ID_LIST pid_list = (JOBOBJECT_BASIC_PROCESS_ID_LIST *)buf;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION ext_limit_info;
JOBOBJECT_BASIC_LIMIT_INFORMATION *basic_limit_info = &ext_limit_info.BasicLimitInformation;
+ JOBOBJECT_BASIC_ACCOUNTING_INFORMATION basic_accounting_info;
DWORD dwret, ret_len;
PROCESS_INFORMATION pi[2];
HANDLE job;
@@ -2647,6 +2648,14 @@ static void test_QueryInformationJobObject(void)
ok(ret_len == sizeof(ext_limit_info), "QueryInformationJobObject returned ret_len=%u\n", ret_len);
expect_eq_d(0, basic_limit_info->LimitFlags);
+ /* test JobObjectBasicAccountingInformation */
+ ret = pQueryInformationJobObject(job, JobObjectBasicAccountingInformation, &basic_accounting_info,
+ sizeof(basic_accounting_info), &ret_len);
+ ok(ret, "QueryInformationJobObject error %u\n", GetLastError());
+ ok(ret_len == sizeof(basic_accounting_info), "QueryInformationJobObject returned ret_len=%u\n", ret_len);
+ expect_eq_d(3, basic_accounting_info.TotalProcesses);
+ expect_eq_d(2, basic_accounting_info.ActiveProcesses);
+
TerminateProcess(pi[0].hProcess, 0);
CloseHandle(pi[0].hProcess);
CloseHandle(pi[0].hThread);
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 2b5b6ce44a..69d6e60888 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -694,7 +694,9 @@ NTSTATUS WINAPI NtTerminateJobObject( HANDLE handle, NTSTATUS status )
NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS class, PVOID info,
ULONG len, PULONG ret_len )
{
- FIXME( "stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
+ NTSTATUS ret;
+
+ TRACE( "semi-stub: %p %u %p %u %p\n", handle, class, info, len, ret_len );
if (class >= MaxJobObjectInfoClass)
return STATUS_INVALID_PARAMETER;
@@ -708,9 +710,21 @@ NTSTATUS WINAPI NtQueryInformationJobObject( HANDLE handle, JOBOBJECTINFOCLASS c
return STATUS_INFO_LENGTH_MISMATCH;
accounting = (JOBOBJECT_BASIC_ACCOUNTING_INFORMATION *)info;
- memset(accounting, 0, sizeof(*accounting));
+
+ SERVER_START_REQ(get_job_info)
+ {
+ req->handle = wine_server_obj_handle( handle );
+ if ((ret = wine_server_call( req )) == STATUS_SUCCESS)
+ {
+ memset(accounting, 0, sizeof(*accounting));
+ accounting->TotalProcesses = reply->total_processes;
+ accounting->ActiveProcesses = reply->active_processes;
+ }
+ }
+ SERVER_END_REQ;
+
if (ret_len) *ret_len = sizeof(*accounting);
- return STATUS_SUCCESS;
+ return ret;
}
case JobObjectBasicProcessIdList:
diff --git a/server/process.c b/server/process.c
index 73984f363f..8a1edfeac9 100644
--- a/server/process.c
+++ b/server/process.c
@@ -156,6 +156,7 @@ struct job
struct object obj; /* object header */
struct list process_list; /* list of all processes */
int num_processes; /* count of running processes */
+ int assign_counter; /* Number of processes which have been assigned */
unsigned int limit_flags; /* limit flags */
int terminating; /* job is terminating */
int signaled; /* job is signaled */
@@ -198,6 +199,7 @@ static struct job *create_job_object( struct object *root, const struct unicode_
/* initialize it if it didn't already exist */
list_init( &job->process_list );
job->num_processes = 0;
+ job->assign_counter = 0;
job->limit_flags = 0;
job->terminating = 0;
job->signaled = 0;
@@ -240,6 +242,7 @@ static void add_job_process( struct job *job, struct process *process )
process->job = (struct job *)grab_object( job );
list_add_tail( &job->process_list, &process->job_entry );
job->num_processes++;
+ job->assign_counter++;
add_job_completion( job, JOB_OBJECT_MSG_NEW_PROCESS, get_process_id(process) );
}
@@ -1715,6 +1718,17 @@ DECL_HANDLER(process_in_job)
release_object( process );
}
+/* retrieve information about a job */
+DECL_HANDLER(get_job_info)
+{
+ struct job *job = get_job_obj( current->process, req->handle, JOB_OBJECT_QUERY );
+
+ reply->total_processes = job->assign_counter;
+ reply->active_processes = job->num_processes;
+
+ release_object( job );
+}
+
/* terminate all processes associated with the job */
DECL_HANDLER(terminate_job)
{
diff --git a/server/protocol.def b/server/protocol.def
index 6c44b2b43f..3956a2815d 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3938,6 +3938,14 @@ struct handle_info
client_ptr_t key; /* key to send with completion messages */
@END
+/* Retrieve information about a job */
+ at REQ(get_job_info)
+ obj_handle_t handle;
+ at REPLY
+ unsigned int total_processes;
+ unsigned int active_processes;
+ at END
+
/* Terminate all processes associated with the job */
@REQ(terminate_job)
--
2.25.1
More information about the wine-devel
mailing list