[PATCH v2 2/3] ntdll: Return thread times in NtQuerySystemInformation(SystemProcessInformation).

Zebediah Figura z.figura12 at gmail.com
Sun Jun 28 20:43:18 CDT 2020


From: Michael Müller <michael at fds-team.de>

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
This patch lets Process Hacker display accurate values.

 dlls/ntdll/unix/system.c       | 40 +++++++++++++++++++++-------------
 dlls/ntdll/unix/thread.c       |  4 ++--
 dlls/ntdll/unix/unix_private.h |  2 ++
 server/protocol.def            |  1 +
 server/snapshot.c              |  1 +
 5 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 5e2e763445..fd86ab874a 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -2101,6 +2101,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
         len = 0;
         while (ret == STATUS_SUCCESS)
         {
+            int unix_pid = -1;
             SERVER_START_REQ( next_process )
             {
                 req->handle = wine_server_obj_handle( handle );
@@ -2108,6 +2109,8 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
                 wine_server_set_reply( req, procname, sizeof(procname) - sizeof(WCHAR) );
                 if (!(ret = wine_server_call( req )))
                 {
+                    unix_pid = reply->unix_pid;
+
                     /* Make sure procname is 0 terminated */
                     procname[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0;
 
@@ -2156,31 +2159,38 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
                 i = j = 0;
                 while (ret == STATUS_SUCCESS)
                 {
+                    int unix_tid, pid, tid, base_pri, delta_pri;
                     SERVER_START_REQ( next_thread )
                     {
                         req->handle = wine_server_obj_handle( handle );
                         req->reset = (j == 0);
                         if (!(ret = wine_server_call( req )))
                         {
+                            unix_tid = reply->unix_tid;
+                            pid = reply->pid;
+                            tid = reply->tid;
+                            base_pri = reply->base_pri;
+                            delta_pri = reply->delta_pri;
                             j++;
-                            if (UlongToHandle(reply->pid) == spi->UniqueProcessId)
-                            {
-                                /* ftKernelTime, ftUserTime, ftCreateTime;
-                                 * dwTickCount, dwStartAddress
-                                 */
-
-                                memset(&spi->ti[i], 0, sizeof(spi->ti));
-
-                                spi->ti[i].CreateTime.QuadPart = 0xdeadbeef;
-                                spi->ti[i].ClientId.UniqueProcess = UlongToHandle(reply->pid);
-                                spi->ti[i].ClientId.UniqueThread  = UlongToHandle(reply->tid);
-                                spi->ti[i].dwCurrentPriority = reply->base_pri + reply->delta_pri;
-                                spi->ti[i].dwBasePriority = reply->base_pri;
-                                i++;
-                            }
                         }
                     }
                     SERVER_END_REQ;
+
+                    if (!ret)
+                    {
+                        if (UlongToHandle(pid) == spi->UniqueProcessId)
+                        {
+                            memset(&spi->ti[i], 0, sizeof(spi->ti));
+
+                            spi->ti[i].CreateTime.QuadPart = 0xdeadbeef;
+                            spi->ti[i].ClientId.UniqueProcess = UlongToHandle(pid);
+                            spi->ti[i].ClientId.UniqueThread  = UlongToHandle(tid);
+                            spi->ti[i].dwCurrentPriority = base_pri + delta_pri;
+                            spi->ti[i].dwBasePriority = base_pri;
+                            get_thread_times(unix_pid, unix_tid, &spi->ti[i].KernelTime, &spi->ti[i].UserTime);
+                            i++;
+                        }
+                    }
                 }
                 if (ret == STATUS_NO_MORE_FILES) ret = STATUS_SUCCESS;
 
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 54483e1f99..3655adf2db 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -824,7 +824,7 @@ static void wow64_context_to_server( context_t *to, const WOW64_CONTEXT *from )
 #endif /* __x86_64__ */
 
 #ifdef linux
-static BOOL get_thread_times(int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time, LARGE_INTEGER *user_time)
+BOOL get_thread_times(int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time, LARGE_INTEGER *user_time)
 {
     unsigned long clocks_per_sec = sysconf( _SC_CLK_TCK );
     unsigned long usr, sys;
@@ -869,7 +869,7 @@ static BOOL get_thread_times(int unix_pid, int unix_tid, LARGE_INTEGER *kernel_t
     return FALSE;
 }
 #else
-static BOOL get_thread_times(int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time, LARGE_INTEGER *user_time)
+BOOL get_thread_times(int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time, LARGE_INTEGER *user_time)
 {
     static int once;
     if (!once++) FIXME("not implemented on this platform\n");
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index ee6caaec8f..fe63606ed8 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -209,6 +209,8 @@ extern void virtual_fill_image_information( const pe_image_info_t *pe_info,
                                             SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;
 
 extern NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_len ) DECLSPEC_HIDDEN;
+extern BOOL get_thread_times( int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time,
+                              LARGE_INTEGER *user_time ) DECLSPEC_HIDDEN;
 extern void signal_init_threading(void) DECLSPEC_HIDDEN;
 extern NTSTATUS signal_alloc_thread( TEB *teb ) DECLSPEC_HIDDEN;
 extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
diff --git a/server/protocol.def b/server/protocol.def
index 54668a8cdc..a625384e36 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1914,6 +1914,7 @@ enum char_info_mode
     thread_id_t  tid;           /* thread id */
     int          base_pri;      /* base priority */
     int          delta_pri;     /* delta priority */
+    int          unix_tid;      /* thread native pid */
 @END
 
 
diff --git a/server/snapshot.c b/server/snapshot.c
index a0f2ea17a3..bdceaef530 100644
--- a/server/snapshot.c
+++ b/server/snapshot.c
@@ -150,6 +150,7 @@ static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_r
     reply->tid       = get_thread_id( ptr->thread );
     reply->base_pri  = ptr->priority;
     reply->delta_pri = 0;  /* FIXME */
+    reply->unix_tid  = ptr->thread->unix_tid;
     return 1;
 }
 
-- 
2.27.0




More information about the wine-devel mailing list