OSDN Git Service

* pinfo.cc (EnumProcessesNT): New function. Eliminates dependence on psapi.h.
authorcgf <cgf>
Thu, 2 Nov 2000 05:25:56 +0000 (05:25 +0000)
committercgf <cgf>
Thu, 2 Nov 2000 05:25:56 +0000 (05:25 +0000)
(EnumProcesses9x): Rename from EnumProcessesW95.  Change arguments to be more
useful for cygwin.
(winpids::init): Accomodate argument changes.
(enum_init): Ditto.
* pinfo.h (winpids): Make pidlist dynamically extendable by storing it as a
pointer and remembering the size.
* ntdll.h: Add extra definitions needed for EnumProcessesNT.  Reformat via
'indent'.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/ntdll.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pinfo.h

index 0d4ef61..b76afbf 100644 (file)
@@ -1,3 +1,16 @@
+Thu Nov  2 00:10:23 2000  Christopher Faylor <cgf@cygnus.com>
+
+       * pinfo.cc (EnumProcessesNT): New function.  Eliminates dependence on
+       psapi.h.
+       (EnumProcesses9x): Rename from EnumProcessesW95.  Change arguments to
+       be more useful for cygwin.
+       (winpids::init): Accomodate argument changes.
+       (enum_init): Ditto.
+       * pinfo.h (winpids): Make pidlist dynamically extendable by storing it
+       as a pointer and remembering the size.
+       * ntdll.h: Add extra definitions needed for EnumProcessesNT.  Reformat
+       via 'indent'.
+
 Wed Nov  1 21:08:23 2000  Christopher Faylor <cgf@cygnus.com>
 
        * exceptions.cc (interruptible): Remove obsolete tests.
index a24ec40..6f9344a 100644 (file)
@@ -244,6 +244,7 @@ LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
 LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
 LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
 LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
+LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
 
 LoadDLLinit (user32)
 LoadDLLfunc (CharToOemBuffA, 12, user32)
index bdb4fe8..79a8c73 100644 (file)
@@ -8,17 +8,17 @@
    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
    details. */
 
-/*
- * The following both data structures aren't defined anywhere in the Microsoft
- * header files. Taken from the book "Windows NT/2000 Native API Reference"
- * by Gary Nebbett.
- */
-typedef enum _SYSTEM_INFORMATION_CLASS {
-  SystemBasicInformation = 0
-  /* Dropped each other since not used here. */
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
+
+typedef enum _SYSTEM_INFORMATION_CLASS
+{
+  SystemBasicInformation = 0,
+  SystemProcessesAndThreadsInformation = 5,
+  /* There are a lot more of these... */
 } SYSTEM_INFORMATION_CLASS;
 
-typedef struct _SYSTEM_BASIC_INFORMATION {
+typedef struct _SYSTEM_BASIC_INFORMATION
+{
   ULONG Unknown;
   ULONG MaximumIncrement;
   ULONG PhysicalPageSize;
@@ -32,19 +32,130 @@ typedef struct _SYSTEM_BASIC_INFORMATION {
   ULONG NumberProcessors;
 } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
 
-/*
- * Function declarations for ntdll.dll. They doesn't appear in any
- * Win32 header either.
- */
-extern "C" {
-NTSTATUS NTAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,ULONG,
-                                  PLARGE_INTEGER,PULONG,SECTION_INHERIT,
-                                  ULONG,ULONG);
-NTSTATUS NTAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,
-                                        PVOID,ULONG,PULONG);
-NTSTATUS NTAPI NtOpenSection(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
-NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE,PVOID);
-VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
-ULONG NTAPI RtlNtStatusToDosError(NTSTATUS);
-}
+typedef LONG KPRIORITY;
+typedef struct _VM_COUNTERS
+{
+  ULONG PeakVirtualSize;
+  ULONG VirtualSize;
+  ULONG PageFaultCount;
+  ULONG PeakWorkingSetSize;
+  ULONG WorkingSetSize;
+  ULONG QuotaPeakPagedPoolUsage;
+  ULONG QuotaPagedPoolUsage;
+  ULONG QuotaPeakNonPagedPoolUsage;
+  ULONG QuotaNonPagedPoolUsage;
+  ULONG PagefileUsage;
+  ULONG PeakPagefileUsage;
+} VM_COUNTERS, *PVM_COUNTERS;
+
+typedef struct _IO_COUNTERS
+{
+  LARGE_INTEGER ReadOperationCount;
+  LARGE_INTEGER WriteOperationCount;
+  LARGE_INTEGER OtherOperationCount;
+  LARGE_INTEGER ReadTransferCount;
+  LARGE_INTEGER WriteTransferCount;
+  LARGE_INTEGER OtherTransferCount;
+} IO_COUNTERS, *PIO_COUNTERS;
+
+typedef struct _CLIENT_ID
+{
+  HANDLE UniqueProcess;
+  HANDLE UniqueThread;
+} CLIENT_ID, *PCLIENT_ID;
+
+typedef enum
+{
+  StateInitialized,
+  StateReady,
+  StateRunning,
+  StateStandby,
+  StateTerminated,
+  StateWait,
+  StateTransition,
+  StateUnknown,
+} THREAD_STATE;
 
+typedef enum
+{
+  Executive,
+  FreePage,
+  PageIn,
+  PoolAllocation,
+  DelayExecution,
+  Suspended,
+  UserRequest,
+  WrExecutive,
+  WrFreePage,
+  WrPageIn,
+  WrPoolAllocation,
+  WrDelayExecution,
+  WrSuspended,
+  WrUserRequest,
+  WrEventPair,
+  WrQueue,
+  WrLpcReceive,
+  WrLpcReply,
+  WrVirtualMemory,
+  WrPageOut,
+  WrRendezvous,
+  Spare2,
+  Spare3,
+  Spare4,
+  Spare5,
+  Spare6,
+  WrKernel,
+  MaximumWaitReason
+} KWAIT_REASON;
+
+typedef struct _SYSTEM_THREADS
+{
+  LARGE_INTEGER KernelTime;
+  LARGE_INTEGER UserTime;
+  LARGE_INTEGER CreateTime;
+  ULONG WaitTime;
+  PVOID StartAddress;
+  CLIENT_ID ClientId;
+  KPRIORITY Priority;
+  KPRIORITY BasePriority;
+  ULONG ContextSwitchCount;
+  THREAD_STATE State;
+  KWAIT_REASON WaitReason;
+} SYSTEM_THREADS, *PSYSTEM_THREADS;
+
+typedef struct _SYSTEM_PROCESSES
+{
+  ULONG NextEntryDelta;
+  ULONG Threadcount;
+  ULONG Reserved1[6];
+  LARGE_INTEGER CreateTime;
+  LARGE_INTEGER UserTime;
+  LARGE_INTEGER KernelTime;
+  UNICODE_STRING ProcessName;
+  KPRIORITY BasePriority;
+  ULONG ProcessId;
+  ULONG InheritedFromProcessId;
+  ULONG HandleCount;
+  ULONG Reserved2[2];
+  VM_COUNTERS VmCounters;
+  IO_COUNTERS IoCounters;
+  SYSTEM_THREADS Threads[1];
+} SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
+
+/* Function declarations for ntdll.dll.  These don't appear in any
+   standard Win32 header.  */
+extern "C"
+{
+  NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
+                                    PLARGE_INTEGER, PULONG, SECTION_INHERIT,
+                                    ULONG, ULONG);
+  NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
+                                          PVOID, ULONG, PULONG);
+  NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
+  NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
+  VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
+  ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
+  NTSTATUS NTAPI ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS,
+                                          IN OUT PVOID, IN ULONG,
+                                          OUT PULONG);
+}
index 3b5f002..850a51b 100644 (file)
@@ -24,6 +24,8 @@ details. */
 #include "environ.h"
 #include "security.h"
 #include <assert.h>
+#include <ntdef.h>
+#include "ntdll.h"
 
 static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
 
@@ -279,9 +281,8 @@ cygwin_winpid_to_pid (int winpid)
 }
 
 #include <tlhelp32.h>
-#include <psapi.h>
 
-typedef BOOL (WINAPI * ENUMPROCESSES) (DWORD *, DWORD, DWORD *);
+typedef DWORD (WINAPI * ENUMPROCESSES) (DWORD* &, DWORD &);
 typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD, DWORD);
 typedef BOOL (WINAPI * PROCESSWALK) (HANDLE, LPPROCESSENTRY32);
 typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE);
@@ -289,65 +290,101 @@ typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE);
 static NO_COPY CREATESNAPSHOT myCreateToolhelp32Snapshot = NULL;
 static NO_COPY PROCESSWALK myProcess32First = NULL;
 static NO_COPY PROCESSWALK myProcess32Next  = NULL;
-static BOOL WINAPI enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded);
+static DWORD WINAPI enum_init (DWORD* &, DWORD&);
 
 static NO_COPY ENUMPROCESSES myEnumProcesses = enum_init;
 
-static BOOL WINAPI
-EnumProcessesW95 (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
+#define slop_pidlist 200
+#define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
+
+static DWORD WINAPI
+EnumProcessesNT (DWORD* &pidlist, DWORD &npidlist)
+{
+  static DWORD szprocs = 0;
+  static SYSTEM_PROCESSES *procs;
+
+  DWORD nelem = 0;
+  if (!szprocs)
+    procs = (SYSTEM_PROCESSES *) malloc (szprocs = 200 * sizeof (*procs));
+
+  NTSTATUS res;
+  for (;;)
+    {
+      res = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
+                                     procs, szprocs, NULL);
+      if (res == 0)
+       break;
+
+      if (res == STATUS_INFO_LENGTH_MISMATCH)
+       procs =  (SYSTEM_PROCESSES *)realloc (procs, szprocs += 200 * sizeof (*procs));
+      else
+       {
+         system_printf ("error %p reading system process information", res);
+         return 0;
+       }
+    }
+
+  SYSTEM_PROCESSES *px = procs;
+  for (;;)
+    {
+      if (nelem >= npidlist)
+       {
+         npidlist += slop_pidlist;
+         pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist));
+       }
+      pidlist[nelem++] = cygwin_pid (px->ProcessId);
+      if (!px->NextEntryDelta)
+       break;
+      px = (SYSTEM_PROCESSES *) ((char *) px + px->NextEntryDelta);
+    }
+
+  return nelem;
+}
+
+static DWORD WINAPI
+EnumProcesses9x (DWORD* &pidlist, DWORD &npidlist)
 {
-  HANDLE h;
+  DWORD nelem = 0;
 
-  *cbneeded = 0;
-  h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
+  HANDLE h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
   if (!h)
-    return 0;
+    {
+      system_printf ("Couldn't create process snapshot, %E");
+      return 0;
+    }
 
   PROCESSENTRY32 proc;
-  int i = 0;
   proc.dwSize = sizeof (proc);
+
   if (myProcess32First(h, &proc))
     do
-      lpidProcess[i++] = cygwin_pid (proc.th32ProcessID);
+      {
+       if (nelem >= npidlist)
+         {
+           npidlist += slop_pidlist;
+           pidlist = (DWORD *) realloc (pidlist, size_pidlist (npidlist));
+         }
+       pidlist[nelem++] = cygwin_pid (proc.th32ProcessID);
+      }
     while (myProcess32Next (h, &proc));
+
   CloseHandle (h);
-  if (i == 0)
-    return 0;
-  *cbneeded = i * sizeof (DWORD);
-  return 1;
+  return nelem;
 }
 
 void
 winpids::init ()
 {
-  DWORD n;
-  if (!myEnumProcesses (pidlist, sizeof (pidlist) / sizeof (pidlist[0]), &n))
-    npids = 0;
-  else
-    npids = n / sizeof (pidlist[0]);
-
+  npids = myEnumProcesses (pidlist, npidlist);
   pidlist[npids] = 0;
 }
 
-static BOOL WINAPI
-enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
+static DWORD WINAPI
+enum_init (DWORD* &pidlist, DWORD& npidlist)
 {
   HINSTANCE h;
   if (os_being_run == winNT)
-    {
-      h = LoadLibrary ("psapi.dll");
-      if (!h)
-       {
-         system_printf ("couldn't load psapi.dll, %E");
-         return 0;
-       }
-      myEnumProcesses = (ENUMPROCESSES) GetProcAddress (h, "EnumProcesses");
-      if (!myEnumProcesses)
-       {
-         system_printf ("couldn't locate EnumProcesses in psapi.dll, %E");
-         return 0;
-       }
-    }
+    myEnumProcesses = EnumProcessesNT;
   else
     {
       h = GetModuleHandle("kernel32.dll");
@@ -363,8 +400,8 @@ enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
          return 0;
        }
 
-      myEnumProcesses = EnumProcessesW95;
+      myEnumProcesses = EnumProcesses9x;
     }
 
-  return myEnumProcesses (lpidProcess, cb, cbneeded);
+  return myEnumProcesses (pidlist, npidlist);
 }
index e9d54cf..0620047 100644 (file)
@@ -186,12 +186,13 @@ public:
 
 class winpids
 {
-  DWORD pidlist[16384];
+  DWORD *pidlist;
+  DWORD npidlist;
 public:
   DWORD npids;
   void reset () { npids = 0; }
   winpids (int) { reset (); }
-  winpids () { init (); };
+  winpids (): pidlist (NULL), npidlist (0) { init (); };
   void init ();
   int operator [] (int i) const {return pidlist[i];}
 };