From d2f9bcfc14a960a4b365406a8610f9ab96f78e9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 9 Mar 2017 22:56:45 +0100
Subject: [PATCH] ntdll: Fill process virtual memory counters in
 NtQuerySystemInformation.

FIXME: fill_VM_COUNTERS now uses a different method ... which one is better?
---
 dlls/ntdll/nt.c         |  3 +++
 dlls/ntdll/ntdll_misc.h |  1 +
 dlls/ntdll/process.c    |  2 +-
 dlls/ntdll/thread.c     | 36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 3c2838f365e..5092b97d252 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -2510,8 +2510,11 @@ NTSTATUS WINAPI NtQuerySystemInformation(
                             /* spi->ti will be set later on */
 
                             if (reply->unix_pid != -1)
+                            {
                                 read_process_time(reply->unix_pid, -1, clk_tck,
                                                   &spi->KernelTime, &spi->UserTime);
+                                read_process_memory_stats(reply->unix_pid, &spi->vmCounters);
+                            }
                             unix_pid = reply->unix_pid;
                         }
                         len += procstructlen;
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 40bf66f1d24..5ec14a399cc 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -263,6 +263,7 @@ void     WINAPI LdrInitializeThunk(CONTEXT*,void**,ULONG_PTR,ULONG_PTR);
 /* process / thread time */
 extern BOOL read_process_time(int unix_pid, int unix_tid, unsigned long clk_tck,
                               LARGE_INTEGER *kernel, LARGE_INTEGER *user) DECLSPEC_HIDDEN;
+extern BOOL read_process_memory_stats(int unix_pid, VM_COUNTERS *pvmi) DECLSPEC_HIDDEN;
 
 /* string functions */
 int __cdecl NTDLL_tolower( int c );
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 34051c2ef93..94e8df8d8d1 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -203,7 +203,7 @@ static void fill_VM_COUNTERS(VM_COUNTERS* pvmi)
 
 static void fill_VM_COUNTERS(VM_COUNTERS* pvmi)
 {
-    /* FIXME : real data */
+    read_process_memory_stats(getpid(), pvmi);
 }
 
 #endif
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 4279ae77099..0f90291e222 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -195,6 +195,42 @@ BOOL read_process_time(int unix_pid, int unix_tid, unsigned long clk_tck,
     return FALSE;
 }
 
+BOOL read_process_memory_stats(int unix_pid, VM_COUNTERS *pvmi)
+{
+    BOOL ret = FALSE;
+#ifdef __linux__
+    unsigned long size, resident, shared, trs, drs, lrs, dt;
+    char buf[512];
+    FILE *fp;
+
+    sprintf( buf, "/proc/%u/statm", unix_pid );
+    if ((fp = fopen( buf, "r" )))
+    {
+        if (fscanf( fp, "%lu %lu %lu %lu %lu %lu %lu",
+            &size, &resident, &shared, &trs, &drs, &lrs, &dt ) == 7)
+        {
+            pvmi->VirtualSize = size * page_size;
+            pvmi->WorkingSetSize = resident * page_size;
+            pvmi->PrivatePageCount = size - shared;
+
+            /* these values are not available through /proc/pid/statm */
+            pvmi->PeakVirtualSize = pvmi->VirtualSize;
+            pvmi->PageFaultCount = 0;
+            pvmi->PeakWorkingSetSize = pvmi->WorkingSetSize;
+            pvmi->QuotaPagedPoolUsage = pvmi->VirtualSize;
+            pvmi->QuotaPeakPagedPoolUsage = pvmi->QuotaPagedPoolUsage;
+            pvmi->QuotaPeakNonPagedPoolUsage = 0;
+            pvmi->QuotaNonPagedPoolUsage = 0;
+            pvmi->PagefileUsage = 0;
+            pvmi->PeakPagefileUsage = 0;
+
+            ret = TRUE;
+        }
+        fclose( fp );
+    }
+#endif
+    return ret;
+}
 
 /***********************************************************************
  *           thread_init
-- 
2.20.1

