]> sourceware.org Git - newlib-cygwin.git/commitdiff
* autoload.cc: Add dynamic load statements for 'ZwQueryInformationProcess' and
authorChristopher Faylor <me@cgf.cx>
Sun, 12 May 2002 01:37:48 +0000 (01:37 +0000)
committerChristopher Faylor <me@cgf.cx>
Sun, 12 May 2002 01:37:48 +0000 (01:37 +0000)
'ZwQueryVirtualMemory'.
* fhandler.h: Change type of bufalloc and filesize members of fhandler_virtual
from int to size_t.  Change type of position member from __off32_t to
__off64_t.  Add new fileid member to fhandler_virtual class.  Make seekdir take
an __off64_t argument.  Make lseek take an __off64_t argument.  Add
fill_filebuf method to fhandler_virtual.  Add fill_filebuf method to
fhandler_proc.  Add fill_filebuf method to fhandler_registry.  Add fill_filebuf
method to fhandler_process.  Add saved_pid and saved_p members to
fhandler_process.
* fhandler_proc.cc (proc_listing_array): Add 'loadavg', 'meminfo', and 'stat'.
(proc_fhandlers array): Ditto.
(fhandler_proc::open): Use fill_filebuf to flesh out the file contents.
(fhandler_proc::fill_filebuf): New method.
(fhandler_proc::format_proc_meminfo): Ditto.
(fhandler_proc::format_proc_stat): Ditto.
(fhandler_proc::format_proc_uptime): Ditto.
* fhandler_process.cc (process_listing): Add 'stat' and 'statm'.
(fhandler_process::fstat): Find the _pinfo structure for the process named in
the filename.  Return ENOENT if the process is no longer around.  Set the gid
and uid fields of the stat structure.
(fhandler_process::open): Store pid and pointer to _pinfo structure in
saved_pid and saved_p respectively.  Use fill_filebuf to flesh out file
contents.
(fhandler_proc::fill_filebuf): New method.
(format_process_stat): New function.
(format_process_status): Ditto.
(format_process_statm): Ditto.
(get_process_state): Ditto.
(get_mem_values): Ditto.
* fhandler_registry.cc (fhandler_registry::seekdir): Change argument type from
__off32_t to __off64_t.
(fhandler_registry::fill_filebuf): New method.
* fhandler_virtual.cc (fhandler_virtual::seekdir): Change argument type from
__off32_t to __off64_t.
(fhandler_virtual::lseek): Ditto.
(fhandler_virtual::fill_filebuf): New method.
(fhandler_virtual::fhandler_virtual): Initialise fileid to -1.
* wincap.cc: Set flag has_process_io_counters appropriately.
* wincap.h: Add flag has_process_io_counters.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_proc.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/fhandler_registry.cc
winsup/cygwin/fhandler_virtual.cc
winsup/cygwin/ntdll.h
winsup/cygwin/wincap.cc
winsup/cygwin/wincap.h

index 7584ed169da5a82b60817bc185ade6f15a7385e9..1bbffbde86b23680abf7d98099b96b3a2f51b3a9 100644 (file)
@@ -1,4 +1,47 @@
-2002-05-09  Christopher Faylor  <cgf@redhat.com>
+2002-05-10  Christopher January <chris@atomice.net>
+
+       * autoload.cc: Add dynamic load statements for
+       'ZwQueryInformationProcess' and 'ZwQueryVirtualMemory'.
+       * fhandler.h: Change type of bufalloc and filesize members of
+       fhandler_virtual from int to size_t.  Change type of position member
+       from __off32_t to __off64_t.  Add new fileid member to fhandler_virtual
+       class.  Make seekdir take an __off64_t argument.  Make lseek take an
+       __off64_t argument.  Add fill_filebuf method to fhandler_virtual.  Add
+       fill_filebuf method to fhandler_proc.  Add fill_filebuf method to
+       fhandler_registry.  Add fill_filebuf method to fhandler_process.  Add
+       saved_pid and saved_p members to fhandler_process.
+       * fhandler_proc.cc (proc_listing_array): Add 'loadavg', 'meminfo', and 'stat'.
+       (proc_fhandlers array): Ditto.
+       (fhandler_proc::open): Use fill_filebuf to flesh out the file contents.
+       (fhandler_proc::fill_filebuf): New method.
+       (fhandler_proc::format_proc_meminfo): Ditto.
+       (fhandler_proc::format_proc_stat): Ditto.
+       (fhandler_proc::format_proc_uptime): Ditto.
+       * fhandler_process.cc (process_listing): Add 'stat' and 'statm'.
+       (fhandler_process::fstat): Find the _pinfo structure for the process
+       named in the filename.  Return ENOENT if the process is no longer
+       around.  Set the gid and uid fields of the stat structure.
+       (fhandler_process::open): Store pid and pointer to _pinfo structure in
+       saved_pid and saved_p respectively.  Use fill_filebuf to flesh out file
+       contents.
+       (fhandler_proc::fill_filebuf): New method.
+       (format_process_stat): New function.
+       (format_process_status): Ditto.
+       (format_process_statm): Ditto.
+       (get_process_state): Ditto.
+       (get_mem_values): Ditto.
+       * fhandler_registry.cc (fhandler_registry::seekdir): Change argument
+       type from __off32_t to __off64_t.
+       (fhandler_registry::fill_filebuf): New method.
+       * fhandler_virtual.cc (fhandler_virtual::seekdir): Change argument type
+       from __off32_t to __off64_t.
+       (fhandler_virtual::lseek): Ditto.
+       (fhandler_virtual::fill_filebuf): New method.
+       (fhandler_virtual::fhandler_virtual): Initialise fileid to -1.
+       * wincap.cc: Set flag has_process_io_counters appropriately.
+       * wincap.h: Add flag has_process_io_counters.
+
+2002-05-09 Christopher Faylor <cgf@redhat.com>
 
        * syscalls.cc (_write): Change error to EBADF if attempt to write to a
        non-writable fd.
index 3a82e38734df0e44b2be5f39394a7c756ee6883e..6592ef2c04ee7ea8a75142412e5b1d63f8a312df 100644 (file)
@@ -381,6 +381,8 @@ LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
 LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
 LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
 LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
+LoadDLLfuncEx (ZwQueryInformationProcess, 20, ntdll, 1)
+LoadDLLfuncEx (ZwQueryVirtualMemory, 24, ntdll, 1)
 
 LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)
 
index aa0b6ccee56d44650fef26b7191812882da4dc91..1a4807320ee4edc0249cab89c36fe5f2fdc99674 100644 (file)
@@ -1043,8 +1043,9 @@ class fhandler_virtual : public fhandler_base
 {
  protected:
   char *filebuf;
-  int bufalloc, filesize;
-  __off32_t position;
+  size_t bufalloc, filesize;
+  __off64_t position;
+  int fileid; // unique within each class
  public:
 
   fhandler_virtual (DWORD devtype);
@@ -1053,16 +1054,17 @@ class fhandler_virtual : public fhandler_base
   virtual int exists(const char *path);
   DIR *opendir (path_conv& pc);
   __off64_t telldir (DIR *);
-  void seekdir (DIR *, __off32_t);
+  void seekdir (DIR *, __off64_t);
   void rewinddir (DIR *);
   int closedir (DIR *);
   int write (const void *ptr, size_t len);
   int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
-  __off64_t lseek (__off32_t, int);
+  __off64_t lseek (__off64_t, int);
   int dup (fhandler_base * child);
   int open (path_conv *, int flags, mode_t mode = 0);
   int close (void);
   int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
+  virtual void fill_filebuf ();
 };
 
 class fhandler_proc: public fhandler_virtual
@@ -1076,6 +1078,7 @@ class fhandler_proc: public fhandler_virtual
 
   int open (path_conv *real_path, int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+  void fill_filebuf ();
 };
 
 class fhandler_registry: public fhandler_proc
@@ -1085,23 +1088,29 @@ class fhandler_registry: public fhandler_proc
   int exists(const char *path);
   struct dirent *readdir (DIR *);
   __off64_t telldir (DIR *);
-  void seekdir (DIR *, __off32_t);
+  void seekdir (DIR *, __off64_t);
   void rewinddir (DIR *);
   int closedir (DIR *);
 
   int open (path_conv *real_path, int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
   HKEY open_key(const char *name, REGSAM access = KEY_READ, bool isValue = false);
+  void fill_filebuf ();
 };
 
+struct _pinfo;
 class fhandler_process: public fhandler_proc
 {
+ private:
+  pid_t saved_pid;
+  _pinfo *saved_p;
  public:
   fhandler_process ();
   int exists(const char *path);
   struct dirent *readdir (DIR *);
   int open (path_conv *real_path, int flags, mode_t mode = 0);
   int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+  void fill_filebuf ();
 };
 
 typedef union
index 3d4946998f157165387efde29f5cc712095b80d8..60e95780d3bf609cf500616695114b96e65c305e 100644 (file)
@@ -14,6 +14,7 @@ details. */
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/cygwin.h>
+#include <ntdef.h>
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
@@ -24,20 +25,27 @@ details. */
 #include "cygheap.h"
 #include <assert.h>
 #include <sys/utsname.h>
+#include "ntdll.h"
 
 #define _COMPILING_NEWLIB
 #include <dirent.h>
 
 /* offsets in proc_listing */
-static const int PROC_REGISTRY = 2;     // /proc/registry
-static const int PROC_VERSION  = 3;     // /proc/version
-static const int PROC_UPTIME   = 4;     // /proc/uptime
+static const int PROC_LOADAVG  = 2;     // /proc/loadavg
+static const int PROC_MEMINFO  = 3;     // /proc/meminfo
+static const int PROC_REGISTRY = 4;     // /proc/registry
+static const int PROC_STAT     = 5;     // /proc/stat
+static const int PROC_VERSION  = 6;     // /proc/version
+static const int PROC_UPTIME   = 7;     // /proc/uptime
 
 /* names of objects in /proc */
 static const char *proc_listing[] = {
   ".",
   "..",
+  "loadavg",
+  "meminfo",
   "registry",
+  "stat",
   "version",
   "uptime",
   NULL
@@ -48,11 +56,14 @@ static const int PROC_LINK_COUNT = (sizeof(proc_listing) / sizeof(const char *))
 /* FH_PROC in the table below means the file/directory is handles by
  * fhandler_proc.
  */
-static const DWORD proc_fhandlers[] = {
+static const DWORD proc_fhandlers[PROC_LINK_COUNT] = {
+  FH_PROC,
+  FH_PROC,
   FH_PROC,
   FH_PROC,
   FH_REGISTRY,
   FH_PROC,
+  FH_PROC,
   FH_PROC
 };
 
@@ -60,6 +71,10 @@ static const DWORD proc_fhandlers[] = {
 const char proc[] = "/proc";
 const int proc_len = sizeof (proc) - 1;
 
+static off_t format_proc_meminfo (char *destbuf, size_t maxsize);
+static off_t format_proc_stat (char *destbuf, size_t maxsize);
+static off_t format_proc_uptime (char *destbuf, size_t maxsize);
+
 /* auxillary function that returns the fhandler associated with the given path
  * this is where it would be nice to have pattern matching in C - polymorphism
  * just doesn't cut it
@@ -291,44 +306,214 @@ fhandler_proc::open (path_conv *pc, int flags, mode_t mode)
       res = 0;
       goto out;
     }
-  switch (proc_file_no)
+
+  fileid = proc_file_no;
+  fill_filebuf ();
+
+  if (flags & O_APPEND)
+    position = filesize;
+  else
+    position = 0;
+
+success:
+  res = 1;
+  set_open_status ();
+  set_flags (flags);
+out:
+  syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
+  return res;
+}
+
+void
+fhandler_proc::fill_filebuf ()
+{
+  switch (fileid)
     {
     case PROC_VERSION:
       {
+        if (!filebuf)
+          {
         struct utsname uts_name;
         uname (&uts_name);
-        filesize = bufalloc = strlen (uts_name.sysname) + 1 +
-          strlen (uts_name.release) + 1 + strlen (uts_name.version) + 2;
+            bufalloc = strlen (uts_name.sysname) + 1 + strlen (uts_name.release) +
+                      1 + strlen (uts_name.version) + 2;
         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
-        __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
+            filesize = __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
                          uts_name.release, uts_name.version);
+          }
         break;
       }
     case PROC_UPTIME:
       {
-        /* GetTickCount() wraps after 49 days - on WinNT/2000/XP, should use
-         * perfomance counters but I don't know Redhat's policy on
-         * NT only dependancies.
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 80);
+        filesize = format_proc_uptime (filebuf, bufalloc);
+        break;
+      }
+    case PROC_STAT:
+      {
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+        filesize = format_proc_stat (filebuf, bufalloc);
+        break;
+      }
+    case PROC_LOADAVG:
+      {
+        /*
+         * not really supported - Windows doesn't keep track of these values
+         * Windows 95/98/me does have the KERNEL/CPUUsage performance counter
+         * which is similar.
          */
-        DWORD ticks = GetTickCount ();
-        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
-        __small_sprintf (filebuf, "%d.%02d\n", ticks / 1000,
-                         (ticks / 10) % 100);
-        filesize = strlen (filebuf);
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 16);
+        filesize = __small_sprintf (filebuf, "%u.%02u %u.%02u %u.%02u\n",
+                                    0, 0, 0, 0, 0, 0);
+        break;
+      }
+    case PROC_MEMINFO:
+      {
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+        filesize = format_proc_meminfo (filebuf, bufalloc);
         break;
       }
     }
+}
 
-  if (flags & O_APPEND)
-    position = filesize;
+static
+off_t
+format_proc_meminfo (char *destbuf, size_t maxsize)
+{
+  unsigned long mem_total = 0UL, mem_free = 0UL, swap_total = 0UL,
+                swap_free = 0UL;
+  MEMORYSTATUS memory_status;
+  GlobalMemoryStatus (&memory_status);
+  mem_total = memory_status.dwTotalPhys;
+  mem_free = memory_status.dwAvailPhys;
+  swap_total = memory_status.dwTotalPageFile;
+  swap_free = memory_status.dwAvailPageFile;
+  return __small_sprintf (destbuf, "         total:      used:      free:\n"
+                                   "Mem:  %10lu %10lu %10lu\n"
+                                   "Swap: %10lu %10lu %10lu\n"
+                                   "MemTotal:     %10lu kB\n"
+                                   "MemFree:      %10lu kB\n"
+                                   "MemShared:             0 kB\n"
+                                   "HighTotal:             0 kB\n"
+                                   "HighFree:              0 kB\n"
+                                   "LowTotal:     %10lu kB\n"
+                                   "LowFree:      %10lu kB\n"
+                                   "SwapTotal:    %10lu kB\n"
+                                   "SwapFree:     %10lu kB\n",
+                                   mem_total, mem_total - mem_free, mem_free,
+                                   swap_total, swap_total - swap_free, swap_free,
+                                   mem_total >> 10, mem_free >> 10,
+                                   mem_total >> 10, mem_free >> 10,
+                                   swap_total >> 10, swap_free >> 10);
+}
+
+static
+off_t
+format_proc_uptime (char *destbuf, size_t maxsize)
+{
+  unsigned long long uptime = 0ULL, idle_time = 0ULL;
+  SYSTEM_PROCESSOR_TIMES spt;
+
+  NTSTATUS ret = ZwQuerySystemInformation (SystemProcessorTimes, (PVOID) &spt,
+                                          sizeof spt, NULL);
+  if (!ret && GetLastError () == ERROR_PROC_NOT_FOUND)
+    uptime = GetTickCount() / 10;
+  else if (ret != STATUS_SUCCESS)
+    {
+      __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+      debug_printf("NtQuerySystemInformation: ret = %d, "
+                  "Dos(ret) = %d",
+                  ret, RtlNtStatusToDosError (ret));
+      return 0;
+    }
   else
-    position = 0;
+    {
+      idle_time = spt.IdleTime.QuadPart / 100000ULL;
+      uptime = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
+                spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
+                spt.DpcTime.QuadPart) / 100000ULL;
+    }
 
-success:
-  res = 1;
-  set_open_status ();
-  set_flags (flags);
-out:
-  syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
-  return res;
+  return __small_sprintf (destbuf, "%U.%02u %U.%02u\n",
+                          uptime / 100, long (uptime % 100),
+                          idle_time / 100, long (idle_time % 100));
+}
+
+static
+off_t
+format_proc_stat (char *destbuf, size_t maxsize)
+{
+  unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
+  unsigned long pages_in = 0UL, pages_out = 0UL, interrupt_count = 0UL,
+                context_switches = 0UL, swap_in = 0UL, swap_out = 0UL;
+  time_t boot_time = 0;
+
+  if (wincap.is_winnt ())
+    {
+      NTSTATUS ret;
+      SYSTEM_PROCESSOR_TIMES spt;
+      SYSTEM_PERFORMANCE_INFORMATION spi;
+      SYSTEM_TIME_OF_DAY_INFORMATION stodi;
+      ret = ZwQuerySystemInformation (SystemProcessorTimes,
+                                      (PVOID) &spt,
+                                      sizeof spt, NULL);
+      if (ret == STATUS_SUCCESS)
+        ret = ZwQuerySystemInformation (SystemPerformanceInformation,
+                                        (PVOID) &spi,
+                                        sizeof spi, NULL);
+      if (ret == STATUS_SUCCESS)
+        ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
+                                        (PVOID) &stodi,
+                                        sizeof stodi, NULL);
+      if (ret != STATUS_SUCCESS)
+        {
+          __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+          debug_printf("NtQuerySystemInformation: ret = %d, "
+                       "Dos(ret) = %d",
+                       ret, RtlNtStatusToDosError (ret));
+          return 0;
+        }
+      kernel_time = (spt.KernelTime.QuadPart + spt.InterruptTime.QuadPart + spt.DpcTime.QuadPart) / 100000ULL;
+      user_time = spt.UserTime.QuadPart / 100000ULL;
+      idle_time = spt.IdleTime.QuadPart / 100000ULL;
+      interrupt_count = spt.InterruptCount;
+      pages_in = spi.PagesRead;
+      pages_out = spi.PagefilePagesWritten + spi.MappedFilePagesWritten;
+      /*
+       * Note: there is no distinction made in this structure between pages
+       * read from the page file and pages read from mapped files, but there
+       * is such a distinction made when it comes to writing. Goodness knows
+       * why. The value of swap_in, then, will obviously be wrong but its our
+       * best guess.
+       */
+      swap_in = spi.PagesRead;
+      swap_out = spi.PagefilePagesWritten;
+      context_switches = spi.ContextSwitches;
+      boot_time = to_time_t ((FILETIME *) &stodi.BootTime.QuadPart);
+    }
+  /*
+   * else
+   *   {
+   * There are only two relevant performance counters on Windows 95/98/me,
+   * VMM/cPageIns and VMM/cPageOuts. The extra effort needed to read these
+   * counters is by no means worth it.
+   *   }
+   */
+  return __small_sprintf (destbuf, "cpu %U %U %U %U\n"
+                                   "page %u %u\n"
+                                   "swap %u %u\n"
+                                   "intr %u\n"
+                                   "ctxt %u\n"
+                                   "btime %u\n",
+                          user_time, 0ULL,
+                          kernel_time, idle_time,
+                          pages_in, pages_out,
+                          swap_in, swap_out,
+                          interrupt_count,
+                          context_switches,
+                          boot_time);
 }
index 7f68d4a2fe4fe9493a4e1936dd11355dc37c1002..f374d4d9892e39f2095d94893a3bf121da8560c6 100644 (file)
@@ -14,6 +14,7 @@ details. */
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/cygwin.h>
+#include <ntdef.h>
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
@@ -23,6 +24,7 @@ details. */
 #include "shared_info.h"
 #include "dtable.h"
 #include "cygheap.h"
+#include "ntdll.h"
 #include <assert.h>
 
 #define _COMPILING_NEWLIB
@@ -38,6 +40,8 @@ static const int PROCESS_GID = 8;
 static const int PROCESS_PGID = 9;
 static const int PROCESS_SID = 10;
 static const int PROCESS_CTTY = 11;
+static const int PROCESS_STAT = 12;
+static const int PROCESS_STATM = 13;
 
 static const char *process_listing[] = {
   ".",
@@ -52,11 +56,20 @@ static const char *process_listing[] = {
   "pgid",
   "sid",
   "ctty",
+  "stat",
+  "statm",
   NULL
 };
 
 static const int PROCESS_LINK_COUNT = (sizeof(process_listing) / sizeof(const char *)) - 1;
 
+static off_t format_process_stat (_pinfo *p, char *destbuf, size_t maxsize);
+static off_t format_process_status (_pinfo *p, char *destbuf, size_t maxsize);
+static off_t format_process_statm (_pinfo *p, char *destbuf, size_t maxsize);
+static int get_process_state (DWORD dwProcessId);
+static bool get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
+                           unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare);
+
 /* Returns 0 if path doesn't exist, >0 if path is a directory,
  * <0 if path is a file.
  */
@@ -84,8 +97,26 @@ fhandler_process::fhandler_process ():
 int
 fhandler_process::fstat (struct __stat64 *buf, path_conv *pc)
 {
-  int file_type = exists (get_name ());
+  const char *path = get_name ();
+  int file_type = exists (path);
   (void) fhandler_base::fstat (buf, pc);
+  path += proc_len + 1;
+  int pid = atoi (path);
+  winpids pids;
+  _pinfo *p;
+  for (unsigned i = 0; i < pids.npids; i++)
+    {
+      p = pids[i];
+
+      if (!proc_exists (p))
+        continue;
+
+      if (p->pid == pid)
+        goto found;
+    }
+  set_errno(ENOENT);
+  return -1;
+found:
   buf->st_mode &= ~_IFMT & NO_W;
 
   switch (file_type)
@@ -97,12 +128,18 @@ fhandler_process::fstat (struct __stat64 *buf, path_conv *pc)
       buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
       return 0;
     case 2:
+      buf->st_ctime = buf->st_mtime = p->start_time;
+      buf->st_atime = time(NULL);
+      buf->st_uid = p->uid;
+      buf->st_gid = p->gid;
       buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
       buf->st_nlink = PROCESS_LINK_COUNT;
       return 0;
     default:
     case -1:
-      buf->st_mode |= S_IFREG;
+      buf->st_uid = p->uid;
+      buf->st_gid = p->gid;
+      buf->st_mode |= S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
       return 0;
     }
 }
@@ -198,7 +235,36 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
   res = 0;
   goto out;
 found:
-  switch (process_file_no)
+  fileid = process_file_no;
+  saved_pid = pid;
+  saved_p = p;
+  fill_filebuf ();
+
+  if (flags & O_APPEND)
+    position = filesize;
+  else
+    position = 0;
+
+success:
+  res = 1;
+  set_open_status ();
+  set_flags (flags);
+out:
+  syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
+  return res;
+}
+
+void
+fhandler_process::fill_filebuf ()
+{
+  // has this process gone away?
+  if (!proc_exists (saved_p) || saved_p->pid != saved_pid)
+    {
+      if (filebuf)
+        cfree(filebuf);
+      filesize = 0; bufalloc = (size_t) -1;
+    }
+  switch (fileid)
     {
     case PROCESS_UID:
     case PROCESS_GID:
@@ -207,25 +273,31 @@ found:
     case PROCESS_CTTY:
     case PROCESS_PPID:
       {
+        if (!filebuf)
         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
         int num;
-        switch (process_file_no)
+        switch (fileid)
           {
           case PROCESS_PPID:
-            num = p->ppid;
+            num = saved_p->ppid;
             break;
           case PROCESS_UID:
-            num = p->uid;
+            num = saved_p->uid;
             break;
           case PROCESS_PGID:
-            num = p->pgid;
+            num = saved_p->pgid;
             break;
           case PROCESS_SID:
-            num = p->sid;
+            num = saved_p->sid;
+            break;
+          case PROCESS_GID:
+            num = saved_p->gid;
             break;
-         default:
           case PROCESS_CTTY:
-            num = p->ctty;
+            num = saved_p->ctty;
+            break;
+          default: // what's this here for?
+            num = 0;
             break;
           }
         __small_sprintf (filebuf, "%d\n", num);
@@ -234,12 +306,13 @@ found:
       }
     case PROCESS_EXENAME:
       {
+        if (!filebuf)
         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
-        if (p->process_state & (PID_ZOMBIE | PID_EXITED))
+        if (saved_p->process_state & (PID_ZOMBIE | PID_EXITED))
           strcpy (filebuf, "<defunct>");
         else
           {
-            mount_table->conv_to_posix_path (p->progname, filebuf, 1);
+            mount_table->conv_to_posix_path (saved_p->progname, filebuf, 1);
             int len = strlen (filebuf);
             if (len > 4)
               {
@@ -253,47 +326,428 @@ found:
       }
     case PROCESS_WINPID:
       {
+        if (!filebuf)
         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
-        __small_sprintf (filebuf, "%d\n", p->dwProcessId);
+        __small_sprintf (filebuf, "%d\n", saved_p->dwProcessId);
         filesize = strlen (filebuf);
         break;
       }
     case PROCESS_WINEXENAME:
       {
-        int len = strlen (p->progname);
+        int len = strlen (saved_p->progname);
+        if (!filebuf)
         filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
-        strcpy (filebuf, p->progname);
+        strcpy (filebuf, saved_p->progname);
         filebuf[len] = '\n';
         filesize = len + 1;
         break;
       }
     case PROCESS_STATUS:
       {
-        filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 3);
-        filebuf[0] = ' ';
-        filebuf[1] = '\n';
-        filebuf[2] = 0;
-        if (p->process_state & PID_STOPPED)
-          filebuf[0] = 'S';
-        else if (p->process_state & PID_TTYIN)
-          filebuf[0] = 'I';
-        else if (p->process_state & PID_TTYOU)
-          filebuf[0] = 'O';
-        filesize = 2;
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+        filesize = format_process_status (saved_p, filebuf, bufalloc);
+        break;
+      }
+    case PROCESS_STAT:
+      {
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+        filesize = format_process_stat (saved_p, filebuf, bufalloc);
         break;
       }
+    case PROCESS_STATM:
+      {
+        if (!filebuf)
+          filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
+        filesize = format_process_statm (saved_p, filebuf, bufalloc);
+        break;
+    }
     }
+}
 
-  if (flags & O_APPEND)
-    position = filesize;
+static
+off_t
+format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
+{
+  char cmd[MAX_PATH];
+  int state = 'R';
+  unsigned long fault_count = 0UL,
+                utime = 0UL, stime = 0UL,
+                start_time = 0UL,
+                vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
+  int priority = 0;
+  if (p->process_state & (PID_ZOMBIE | PID_EXITED))
+    strcpy (cmd, "<defunct");
   else
-    position = 0;
+    {
+      strcpy(cmd, p->progname);
+      char *last_slash = strrchr (cmd, '\\');
+      if (last_slash != NULL)
+        strcpy (cmd, last_slash + 1);
+      int len = strlen (cmd);
+      if (len > 4)
+        {
+          char *s = cmd + len - 4;
+          if (strcasecmp (s, ".exe") == 0)
+            *s = 0;
+         }
+    }
+  /*
+   * Note: under Windows, a _process_ is always running - it's only _threads_
+   * that get suspended. Therefore the default state is R (runnable).
+   */
+  if (p->process_state & PID_ZOMBIE)
+    state = 'Z';
+  else if (p->process_state & PID_STOPPED)
+    state = 'T';
+  else if (wincap.is_winnt ())
+    state = get_process_state (p->dwProcessId);
+ if (wincap.is_winnt ())
+    {
+      NTSTATUS ret;
+      HANDLE hProcess;
+      VM_COUNTERS vmc;
+      KERNEL_USER_TIMES put;
+      PROCESS_BASIC_INFORMATION pbi;
+      QUOTA_LIMITS ql;
+      SYSTEM_TIME_OF_DAY_INFORMATION stodi;
+      SYSTEM_PROCESSOR_TIMES spt;
+      hProcess = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
+                              FALSE, p->dwProcessId);
+      if (hProcess != NULL)
+        {
+          ret = ZwQueryInformationProcess (hProcess,
+                                           ProcessVmCounters,
+                                           (PVOID) &vmc,
+                                           sizeof vmc, NULL);
+          if (ret == STATUS_SUCCESS)
+            ret = ZwQueryInformationProcess (hProcess,
+                                             ProcessTimes,
+                                             (PVOID) &put,
+                                             sizeof put, NULL);
+          if (ret == STATUS_SUCCESS)
+            ret = ZwQueryInformationProcess (hProcess,
+                                             ProcessBasicInformation,
+                                             (PVOID) &pbi,
+                                             sizeof pbi, NULL);
+          if (ret == STATUS_SUCCESS)
+            ret = ZwQueryInformationProcess (hProcess,
+                                             ProcessQuotaLimits,
+                                             (PVOID) &ql,
+                                             sizeof ql, NULL);
+          CloseHandle (hProcess);
+        }
+      else
+        {
+          DWORD error = GetLastError ();
+          __seterrno_from_win_error (error);
+          debug_printf("OpenProcess: ret = %d",
+                        error);
+          return 0;
+        }
+      if (ret == STATUS_SUCCESS)
+        ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
+                                        (PVOID) &stodi,
+                                        sizeof stodi, NULL);
+      if (ret == STATUS_SUCCESS)
+        ret = ZwQuerySystemInformation (SystemProcessorTimes,
+                                        (PVOID) &spt,
+                                        sizeof spt, NULL);
+      if (ret != STATUS_SUCCESS)
+        {
+          __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+          debug_printf("NtQueryInformationProcess: ret = %d, "
+                       "Dos(ret) = %d",
+                       ret, RtlNtStatusToDosError (ret));
+          return 0;
+        }
+       fault_count = vmc.PageFaultCount;
+       utime = put.UserTime.QuadPart / 100000ULL;
+       stime = put.KernelTime.QuadPart / 100000ULL;
+       if (stodi.CurrentTime.QuadPart > put.CreateTime.QuadPart)
+         start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
+                       spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
+                       spt.DpcTime.QuadPart - stodi.CurrentTime.QuadPart +
+                       put.CreateTime.QuadPart) / 100000ULL;
+       else
+         /*
+          * sometimes stodi.CurrentTime is a bit behind
+          * Note: some older versions of procps are broken and can't cope
+          * with process start times > time(NULL).
+          */
+         start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
+                       spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
+                       spt.DpcTime.QuadPart) / 100000ULL;
+       priority = pbi.BasePriority;
+       unsigned page_size = getpagesize();
+       vmsize = vmc.VirtualSize;
+       vmrss = vmc.WorkingSetSize / page_size;
+       vmmaxrss = ql.MaximumWorkingSetSize / page_size;
+    }
+  else
+    {
+      start_time = (GetTickCount() / 1000 - time(NULL) + p->start_time) * 100;
+    }
+  return __small_sprintf (destbuf, "%d (%s) %c "
+                                   "%d %d %d %d %d "
+                                   "%lu %lu %lu %lu %lu %lu %lu "
+                                   "%ld %ld %ld %ld %ld %ld "
+                                   "%lu %lu "
+                                   "%ld "
+                                   "%lu",
+                          p->pid, cmd,
+                          state,
+                          p->ppid, p->pgid, p->sid, p->ctty, -1,
+                          0, fault_count, fault_count, 0, 0, utime, stime,
+                          utime, stime, priority, 0, 0, 0,
+                          start_time, vmsize,
+                          vmrss, vmmaxrss
+                          );
+}
 
-success:
-  res = 1;
-  set_open_status ();
-  set_flags (flags);
+static
+off_t
+format_process_status (_pinfo *p, char *destbuf, size_t maxsize)
+{
+  char cmd[MAX_PATH];
+  int state = 'R';
+  const char *state_str = "unknown";
+  unsigned long vmsize = 0UL, vmrss = 0UL, vmdata = 0UL, vmlib = 0UL, vmtext = 0UL,
+                vmshare = 0UL;
+  if (p->process_state & (PID_ZOMBIE | PID_EXITED))
+    strcpy (cmd, "<defunct>");
+  else
+    {
+      strcpy(cmd, p->progname);
+      char *last_slash = strrchr (cmd, '\\');
+      if (last_slash != NULL)
+        strcpy (cmd, last_slash + 1);
+      int len = strlen (cmd);
+      if (len > 4)
+        {
+          char *s = cmd + len - 4;
+          if (strcasecmp (s, ".exe") == 0)
+            *s = 0;
+         }
+    }
+  /*
+   * Note: under Windows, a _process_ is always running - it's only _threads_
+   * that get suspended. Therefore the default state is R (runnable).
+   */
+  if (p->process_state & PID_ZOMBIE)
+    state = 'Z';
+  else if (p->process_state & PID_STOPPED)
+    state = 'T';
+  else if (wincap.is_winnt ())
+    state = get_process_state (p->dwProcessId);
+  switch (state)
+    {
+    case 'O':
+      state_str = "running";
+      break;
+    case 'D':
+    case 'S':
+      state_str = "sleeping";
+      break;
+    case 'R':
+      state_str = "runnable";
+      break;
+    case 'Z':
+      state_str = "zombie";
+      break;
+    case 'T':
+      state_str = "stopped";
+      break;
+    }
+  if (wincap.is_winnt ())
+    {
+      if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
+        return 0;
+      unsigned page_size = getpagesize();
+      vmsize *= page_size; vmrss *= page_size; vmdata *= page_size;
+      vmtext *= page_size; vmlib *= page_size;
+    }
+  return __small_sprintf (destbuf, "Name:   %s\n"
+                                   "State:  %c (%s)\n"
+                                   "Tgid:   %d\n"
+                                   "Pid:    %d\n"
+                                   "PPid:   %d\n"
+                                   "Uid:    %d %d %d %d\n"
+                                   "Gid:    %d %d %d %d\n"
+                                   "VmSize: %8d kB\n"
+                                   "VmLck:  %8d kB\n"
+                                   "VmRSS:  %8d kB\n"
+                                   "VmData: %8d kB\n"
+                                   "VmStk:  %8d kB\n"
+                                   "VmExe:  %8d kB\n"
+                                   "VmLib:  %8d kB\n"
+                                   "SigPnd: %016x\n"
+                                   "SigBlk: %016x\n"
+                                   "SigIgn: %016x\n",
+                          cmd,
+                          state, state_str,
+                          p->pgid,
+                          p->pid,
+                          p->ppid,
+                          p->uid, cygheap->user.real_uid, cygheap->user.real_uid, p->uid,
+                          p->gid, cygheap->user.real_gid, cygheap->user.real_gid, p->gid,
+                          vmsize >> 10, 0, vmrss >> 10, vmdata >> 10, 0, vmtext >> 10, vmlib >> 10,
+                          0, 0, p->getsigmask ()
+                          );
+}
+
+static
+off_t
+format_process_statm (_pinfo *p, char *destbuf, size_t maxsize)
+{
+  unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL, vmlib = 0UL,
+                vmshare = 0UL;
+  if (wincap.is_winnt ())
+    {
+      if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
+        return 0;
+    }
+  return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld",
+                          vmsize, vmrss, vmshare, vmtext, vmlib, vmdata, 0
+                          );
+}
+
+static
+int
+get_process_state (DWORD dwProcessId)
+{
+  /*
+   * This isn't really heavy magic - just go through the processes'
+   * threads one by one and return a value accordingly
+   * Errors are silently ignored.
+   */
+  NTSTATUS ret;
+  SYSTEM_PROCESSES *sp;
+  ULONG n = 0x1000;
+  PULONG p = new ULONG[n];
+  int state =' ';
+  while (STATUS_INFO_LENGTH_MISMATCH ==
+         (ret = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
+                                         (PVOID) p,
+                                         n * sizeof *p, NULL)))
+    delete [] p, p = new ULONG[n *= 2];
+  if (ret != STATUS_SUCCESS)
+    {
+      debug_printf("NtQuerySystemInformation: ret = %d, "
+                   "Dos(ret) = %d",
+                   ret, RtlNtStatusToDosError (ret));
+      goto out;
+    }
+  state = 'Z';
+  sp = (SYSTEM_PROCESSES *) p;
+  for (;;)
+    {
+      if (sp->ProcessId == dwProcessId)
+        {
+          SYSTEM_THREADS *st;
+          if (wincap.has_process_io_counters ())
+            /*
+             * Windows 2000 and XP have an extra member in SYSTEM_PROCESSES
+             * which means the offset of the first SYSTEM_THREADS entry is
+             * different on these operating systems compared to NT 4.
+             */
+            st = &sp->Threads[0];
+          else
+            /*
+             * 136 is the offset of the first SYSTEM_THREADS entry on
+             * Windows NT 4.
+             */
+            st = (SYSTEM_THREADS *) ((char *) sp + 136);
+          state = 'S';
+          for (unsigned i = 0; i < sp->ThreadCount; i++)
+            {
+              if (st->State == StateRunning ||
+                  st->State == StateReady)
+                {
+                  state = 'R';
+                  goto out;
+                }
+              st++;
+            }
+          break;
+        }
+      if (!sp->NextEntryDelta)
+         break;
+      sp = (SYSTEM_PROCESSES *) ((char *) sp + sp->NextEntryDelta);
+    }
 out:
-  syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
+  delete [] p;
+  return state;
+}
+
+static
+bool
+get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
+               unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare)
+{
+  bool res = true;
+  NTSTATUS ret;
+  HANDLE hProcess;
+  VM_COUNTERS vmc;
+  MEMORY_WORKING_SET_LIST *mwsl;
+  ULONG n = 0x1000, length;
+  PULONG p = new ULONG[n];
+  unsigned page_size = getpagesize();
+  hProcess = OpenProcess (PROCESS_QUERY_INFORMATION,
+                          FALSE, dwProcessId);
+  if (hProcess == NULL)
+    {
+      DWORD error = GetLastError();
+      __seterrno_from_win_error (error);
+      debug_printf("OpenProcess: ret = %d",
+                    error);
+      return false;
+    }
+  while ((ret = ZwQueryVirtualMemory (hProcess, 0,
+                                      MemoryWorkingSetList,
+                                      (PVOID) p,
+                                      n * sizeof *p, &length)),
+         (ret == STATUS_SUCCESS || ret == STATUS_INFO_LENGTH_MISMATCH) &&
+         length >= n * sizeof *p)
+    delete [] p, p = new ULONG[n *= 2];
+  if (ret != STATUS_SUCCESS)
+    {
+      debug_printf("NtQueryVirtualMemory: ret = %d, "
+                   "Dos(ret) = %d",
+                   ret, RtlNtStatusToDosError (ret));
+      res = false;
+      goto out;
+    }
+  mwsl = (MEMORY_WORKING_SET_LIST *) p;
+  for (unsigned long i = 0; i < mwsl->NumberOfPages; i++)
+    {
+      ++*vmrss;
+      unsigned flags = mwsl->WorkingSetList[i] & 0x0FFF;
+      if (flags & (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE) == (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE))
+          ++*vmlib;
+      else if (flags & WSLE_PAGE_SHAREABLE)
+          ++*vmshare;
+      else if (flags & WSLE_PAGE_EXECUTE)
+          ++*vmtext;
+      else
+          ++*vmdata;
+    }
+  ret = ZwQueryInformationProcess (hProcess,
+                                   ProcessVmCounters,
+                                   (PVOID) &vmc,
+                                   sizeof vmc, NULL);
+  if (ret != STATUS_SUCCESS)
+    {
+      debug_printf("NtQueryInformationProcess: ret = %d, "
+                   "Dos(ret) = %d",
+                   ret, RtlNtStatusToDosError (ret));
+      res = false;
+      goto out;
+    }
+  *vmsize = vmc.VirtualSize / page_size;
+out:
+  delete [] p;
+  CloseHandle (hProcess);
   return res;
 }
index e0938e738de2ca8f408bd583624fbf00f0c56bf5..4fc5024776f9aae78bd91b69127734dada86ca14 100644 (file)
@@ -292,7 +292,7 @@ fhandler_registry::telldir (DIR * dir)
 }
 
 void
-fhandler_registry::seekdir (DIR * dir, __off32_t loc)
+fhandler_registry::seekdir (DIR * dir, __off64_t loc)
 {
   /* Unfortunately cannot simply set __d_position due to transition from sub-keys to
    * values.
@@ -490,6 +490,11 @@ out:
   return res;
 }
 
+void
+fhandler_registry::fill_filebuf ()
+{
+}
+
 /* Auxillary member function to open registry keys.  */
 HKEY
 fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)
index fa774f091a7d418cc485a1ee6df9ada2d0122604..29b7cebeb587c0099de54d5bf04eca1af46ad212 100644 (file)
@@ -27,7 +27,8 @@ details. */
 #include <dirent.h>
 
 fhandler_virtual::fhandler_virtual (DWORD devtype):
-  fhandler_base (devtype), filebuf (NULL), bufalloc (-1)
+  fhandler_base (devtype), filebuf (NULL), bufalloc ((size_t) -1),
+  fileid (-1)
 {
 }
 
@@ -89,7 +90,7 @@ __off64_t fhandler_virtual::telldir (DIR * dir)
 }
 
 void
-fhandler_virtual::seekdir (DIR * dir, __off32_t loc)
+fhandler_virtual::seekdir (DIR * dir, __off64_t loc)
 {
   dir->__d_position = loc;
   return;
@@ -109,8 +110,13 @@ fhandler_virtual::closedir (DIR * dir)
 }
 
 __off64_t
-fhandler_virtual::lseek (__off32_t offset, int whence)
+fhandler_virtual::lseek (__off64_t offset, int whence)
 {
+  /*
+   * On Linux, when you lseek within a /proc file,
+   * the contents of the file are updated.
+   */
+  fill_filebuf ();
   switch (whence)
     {
     case SEEK_SET:
@@ -124,7 +130,7 @@ fhandler_virtual::lseek (__off32_t offset, int whence)
       break;
     default:
       set_errno (EINVAL);
-      return (__off32_t) -1;
+      return (__off64_t) -1;
     }
   return position;
 }
@@ -214,3 +220,8 @@ fhandler_virtual::exists (const char *path)
 {
   return 0;
 }
+
+void
+fhandler_virtual::fill_filebuf ()
+{
+}
index e1ec33bc1146401f2d39d2a31600b4c210c2c73a..f2a96aae5d72e03b95b7f1df0ffaedac82af68ad 100644 (file)
 
 #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
 #define FILE_SYNCHRONOUS_IO_NONALERT 32
+#define PDI_MODULES 0x01
+#define PDI_HEAPS 0x04
+#define LDRP_IMAGE_DLL 0x00000004
+#define WSLE_PAGE_READONLY 0x001
+#define WSLE_PAGE_EXECUTE 0x002
+#define WSLE_PAGE_EXECUTE_READ 0x003
+#define WSLE_PAGE_READWRITE 0x004
+#define WSLE_PAGE_WRITECOPY 0x005
+#define WSLE_PAGE_EXECUTE_READWRITE 0x006
+#define WSLE_PAGE_EXECUTE_WRITECOPY 0x007
+#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
+#define WSLE_PAGE_SHAREABLE 0x100
+
+typedef ULONG KAFFINITY;
 
 typedef enum _SYSTEM_INFORMATION_CLASS
 {
   SystemBasicInformation = 0,
+  SystemPerformanceInformation = 2,
+  SystemTimeOfDayInformation = 3,
   SystemProcessesAndThreadsInformation = 5,
+  SystemProcessorTimes = 8,
   /* There are a lot more of these... */
 } SYSTEM_INFORMATION_CLASS;
 
@@ -30,9 +47,19 @@ typedef struct _SYSTEM_BASIC_INFORMATION
   ULONG LowestUserAddress;
   ULONG HighestUserAddress;
   ULONG ActiveProcessors;
-  ULONG NumberProcessors;
+  UCHAR NumberProcessors;
 } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
 
+typedef struct _SYSTEM_PROCESSOR_TIMES
+{
+  LARGE_INTEGER IdleTime;
+  LARGE_INTEGER KernelTime;
+  LARGE_INTEGER UserTime;
+  LARGE_INTEGER DpcTime;
+  LARGE_INTEGER InterruptTime;
+  ULONG InterruptCount;
+} SYSTEM_PROCESSOR_TIMES, *PSYSTEM_PROCESSOR_TIMES;
+
 typedef LONG KPRIORITY;
 typedef struct _VM_COUNTERS
 {
@@ -112,12 +139,13 @@ typedef struct _SYSTEM_THREADS
   ULONG ContextSwitchCount;
   THREAD_STATE State;
   KWAIT_REASON WaitReason;
+  DWORD Reserved;
 } SYSTEM_THREADS, *PSYSTEM_THREADS;
 
 typedef struct _SYSTEM_PROCESSES
 {
   ULONG NextEntryDelta;
-  ULONG Threadcount;
+  ULONG ThreadCount;
   ULONG Reserved1[6];
   LARGE_INTEGER CreateTime;
   LARGE_INTEGER UserTime;
@@ -139,6 +167,180 @@ typedef struct _IO_STATUS_BLOCK
   ULONG Information;
 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
 
+typedef struct _SYSTEM_PERFORMANCE_INFORMATION
+{
+  LARGE_INTEGER IdleTime;
+  LARGE_INTEGER ReadTransferCount;
+  LARGE_INTEGER WriteTransferCount;
+  LARGE_INTEGER OtherTransferCount;
+  ULONG ReadOperationCount;
+  ULONG WriteOperationCount;
+  ULONG OtherOperationCount;
+  ULONG AvailablePages;
+  ULONG TotalCommittedPages;
+  ULONG TotalCommitLimit;
+  ULONG PeakCommitment;
+  ULONG PageFaults;
+  ULONG WriteCopyFaults;
+  ULONG TransitionFaults;
+  ULONG Reserved1;
+  ULONG DemandZeroFaults;
+  ULONG PagesRead;
+  ULONG PageReadIos;
+  ULONG Reserved2[2];
+  ULONG PagefilePagesWritten;
+  ULONG PagefilePageWriteIos;
+  ULONG MappedFilePagesWritten;
+  ULONG MappedFilePageWriteIos;
+  ULONG PagedPoolUsage;
+  ULONG NonPagedPoolUsage;
+  ULONG PagedPoolAllocs;
+  ULONG PagedPoolFrees;
+  ULONG NonPagedPoolAllocs;
+  ULONG NonPagedPoolFrees;
+  ULONG TotalFreeSystemPtes;
+  ULONG SystemCodePage;
+  ULONG TotalSystemDriverPages;
+  ULONG TotalSystemCodePages;
+  ULONG SmallNonPagedLookasideListAllocateHits;
+  ULONG SmallPagedLookasideListAllocateHits;
+  ULONG Reserved3;
+  ULONG MmSystemCachePage;
+  ULONG PagedPoolPage;
+  ULONG SystemDriverPage;
+  ULONG FastReadNoWait;
+  ULONG FastReadWait;
+  ULONG FastReadResourceMiss;
+  ULONG FastReadNotPossible;
+  ULONG FastMdlReadNoWait;
+  ULONG FastMdlReadWait;
+  ULONG FastMdlReadResourceMiss;
+  ULONG FastMdlReadNotPossible;
+  ULONG MapDataNoWait;
+  ULONG MapDataWait;
+  ULONG MapDataNoWaitMiss;
+  ULONG MapDataWaitMiss;
+  ULONG PinMappedDataCount;
+  ULONG PinReadNoWait;
+  ULONG PinReadWait;
+  ULONG PinReadNoWaitMiss;
+  ULONG PinReadWaitMiss;
+  ULONG CopyReadNoWait;
+  ULONG CopyReadWait;
+  ULONG CopyReadNoWaitMiss;
+  ULONG CopyReadWaitMiss;
+  ULONG MdlReadNoWait;
+  ULONG MdlReadWait;
+  ULONG MdlReadNoWaitMiss;
+  ULONG MdlReadWaitMiss;
+  ULONG ReadAheadIos;
+  ULONG LazyWriteIos;
+  ULONG LazyWritePages;
+  ULONG DataFlushes;
+  ULONG DataPages;
+  ULONG ContextSwitches;
+  ULONG FirstLevelTbFills;
+  ULONG SecondLevelTbFills;
+  ULONG SystemCalls;
+} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
+
+typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
+{
+  LARGE_INTEGER BootTime;
+  LARGE_INTEGER CurrentTime;
+  LARGE_INTEGER TimeZoneBias;
+  ULONG CurrentTimeZoneId;
+} SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
+
+typedef enum _PROCESSINFOCLASS
+{
+  ProcessBasicInformation = 0,
+  ProcessQuotaLimits = 1,
+  ProcessVmCounters = 3,
+  ProcessTimes =4,
+} PROCESSINFOCLASS;
+
+typedef struct _DEBUG_BUFFER
+{
+  HANDLE SectionHandle;
+  PVOID SectionBase;
+  PVOID RemoteSectionBase;
+  ULONG SectionBaseDelta;
+  HANDLE EventPairHandle;
+  ULONG Unknown[2];
+  HANDLE RemoteThreadHandle;
+  ULONG InfoClassMask;
+  ULONG SizeOfInfo;
+  ULONG AllocatedSize;
+  ULONG SectionSize;
+  PVOID ModuleInformation;
+  PVOID BackTraceInformation;
+  PVOID HeapInformation;
+  PVOID LockInformation;
+  PVOID Reserved[9];
+} DEBUG_BUFFER, *PDEBUG_BUFFER;
+
+typedef struct _DEBUG_HEAP_INFORMATION
+{
+  ULONG Base;
+  ULONG Flags;
+  USHORT Granularity;
+  USHORT Unknown;
+  ULONG Allocated;
+  ULONG Committed;
+  ULONG TagCount;
+  ULONG BlockCount;
+  ULONG Reserved[7];
+  PVOID Tags;
+  PVOID Blocks;
+} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
+
+typedef struct _DEBUG_MODULE_INFORMATION
+{
+  ULONG Reserved[2];
+  ULONG Base;
+  ULONG Size;
+  ULONG Flags;
+  USHORT Index;
+  USHORT Unknown;
+  USHORT LoadCount;
+  USHORT ModuleNameOffset;
+  CHAR ImageName[256];
+} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;
+
+typedef struct _KERNEL_USER_TIMES
+{
+  LARGE_INTEGER CreateTime;
+  LARGE_INTEGER ExitTime;
+  LARGE_INTEGER KernelTime;
+  LARGE_INTEGER UserTime;
+} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
+
+typedef void *PPEB;
+
+typedef struct _PROCESS_BASIC_INFORMATION
+{
+  NTSTATUS ExitStatus;
+  PPEB PebBaseAddress;
+  KAFFINITY AffinityMask;
+  KPRIORITY BasePriority;
+  ULONG UniqueProcessId;
+  ULONG InheritedFromUniqueProcessId;
+} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
+
+typedef enum _MEMORY_INFORMATION_CLASS
+{
+  MemoryBasicInformation,
+  MemoryWorkingSetList,
+  MemorySectionName,
+  MemoryBaiscVlmInformation
+} MEMORY_INFORMATION_CLASS;
+
+typedef struct _MEMORY_WORKING_SET_LIST {
+  ULONG NumberOfPages;
+  ULONG WorkingSetList[1];
+} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;
+
 /* Function declarations for ntdll.dll.  These don't appear in any
    standard Win32 header.  */
 extern "C"
@@ -162,4 +364,8 @@ extern "C"
   NTSTATUS NTAPI ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS,
                                           IN OUT PVOID, IN ULONG,
                                           OUT PULONG);
+  NTSTATUS NTAPI ZwQueryInformationProcess (IN HANDLE, IN PROCESSINFOCLASS,
+                                            OUT PVOID, IN ULONG, OUT PULONG);
+  NTSTATUS NTAPI ZwQueryVirtualMemory (IN HANDLE, IN PVOID, IN MEMORY_INFORMATION_CLASS,
+                                       OUT PVOID, IN ULONG, OUT PULONG);
 }
index 09e95fba0ca5bd74745cb1db1c08d8bec14b705e..1b3fd4b17fa489e68e7e44e16ec25e7f5abf56e7 100644 (file)
@@ -46,6 +46,7 @@ static NO_COPY wincaps wincap_unknown = {
   has_raw_devices:false,
   has_valid_processorlevel:false,
   has_64bit_file_access:false,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_95 = {
@@ -83,6 +84,7 @@ static NO_COPY wincaps wincap_95 = {
   has_raw_devices:false,
   has_valid_processorlevel:false,
   has_64bit_file_access:false,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_95osr2 = {
@@ -120,6 +122,7 @@ static NO_COPY wincaps wincap_95osr2 = {
   has_raw_devices:false,
   has_valid_processorlevel:false,
   has_64bit_file_access:false,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_98 = {
@@ -157,6 +160,7 @@ static NO_COPY wincaps wincap_98 = {
   has_raw_devices:false,
   has_valid_processorlevel:true,
   has_64bit_file_access:false,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_98se = {
@@ -194,6 +198,7 @@ static NO_COPY wincaps wincap_98se = {
   has_raw_devices:false,
   has_valid_processorlevel:true,
   has_64bit_file_access:false,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_me = {
@@ -231,6 +236,7 @@ static NO_COPY wincaps wincap_me = {
   has_raw_devices:false,
   has_valid_processorlevel:true,
   has_64bit_file_access:false,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_nt3 = {
@@ -268,6 +274,7 @@ static NO_COPY wincaps wincap_nt3 = {
   has_raw_devices:true,
   has_valid_processorlevel:true,
   has_64bit_file_access:true,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_nt4 = {
@@ -305,6 +312,7 @@ static NO_COPY wincaps wincap_nt4 = {
   has_raw_devices:true,
   has_valid_processorlevel:true,
   has_64bit_file_access:true,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_nt4sp4 = {
@@ -342,6 +350,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
   has_raw_devices:true,
   has_valid_processorlevel:true,
   has_64bit_file_access:true,
+  has_process_io_counters:false,
 };
 
 static NO_COPY wincaps wincap_2000 = {
@@ -379,6 +388,7 @@ static NO_COPY wincaps wincap_2000 = {
   has_raw_devices:true,
   has_valid_processorlevel:true,
   has_64bit_file_access:true,
+  has_process_io_counters:true,
 };
 
 static NO_COPY wincaps wincap_xp = {
@@ -416,6 +426,7 @@ static NO_COPY wincaps wincap_xp = {
   has_raw_devices:true,
   has_valid_processorlevel:true,
   has_64bit_file_access:true,
+  has_process_io_counters:true,
 };
 
 wincapc NO_COPY wincap;
index 088907ad249d321bf11f37d193523d12c39d0b85..c33c3cf4b2f42cf1ccd02d7ea94c2a81a6ba285f 100644 (file)
@@ -47,6 +47,7 @@ struct wincaps
   unsigned has_raw_devices                             : 1;
   unsigned has_valid_processorlevel                    : 1;
   unsigned has_64bit_file_access                       : 1;
+  unsigned has_process_io_counters                      : 1;
 };
 
 class wincapc
@@ -99,6 +100,7 @@ public:
   bool  IMPLEMENT (has_raw_devices)
   bool  IMPLEMENT (has_valid_processorlevel)
   bool  IMPLEMENT (has_64bit_file_access)
+  bool  IMPLEMENT (has_process_io_counters)
 
 #undef IMPLEMENT
 };
This page took 0.064106 seconds and 5 git commands to generate.