[PATCH] ntdll: Partially implement JobObjectBasicAccountingInformation.
Derek Lesho
dlesho at codeweavers.com
Mon May 18 08:20:37 CDT 2020
Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
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 3281804233..8454e64265 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2513,6 +2513,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 ret_len;
PROCESS_INFORMATION pi[2];
char buffer[50];
@@ -2620,6 +2621,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 ad967d20e0..22af41cf0f 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -704,7 +704,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;
@@ -718,9 +720,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 6722addb09..263b37555b 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 total_processes; /* 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->total_processes = 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->total_processes++;
add_job_completion( job, JOB_OBJECT_MSG_NEW_PROCESS, get_process_id(process) );
}
@@ -1728,6 +1731,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->total_processes;
+ 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 2fb8e2ec80..e6bcd6f456 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3934,6 +3934,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.26.2
More information about the wine-devel
mailing list