* 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'.
This commit is contained in:
Christopher Faylor 2000-11-02 05:25:56 +00:00
parent e2fa502354
commit 6d87f7d7c4
5 changed files with 229 additions and 66 deletions

View 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> Wed Nov 1 21:08:23 2000 Christopher Faylor <cgf@cygnus.com>
* exceptions.cc (interruptible): Remove obsolete tests. * exceptions.cc (interruptible): Remove obsolete tests.

View File

@ -244,6 +244,7 @@ LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1) LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1) LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1) LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
LoadDLLinit (user32) LoadDLLinit (user32)
LoadDLLfunc (CharToOemBuffA, 12, user32) LoadDLLfunc (CharToOemBuffA, 12, user32)

View File

@ -8,17 +8,17 @@
Cygwin license. Please consult the file "CYGWIN_LICENSE" for Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */ details. */
/* #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
* The following both data structures aren't defined anywhere in the Microsoft
* header files. Taken from the book "Windows NT/2000 Native API Reference" typedef enum _SYSTEM_INFORMATION_CLASS
* by Gary Nebbett. {
*/ SystemBasicInformation = 0,
typedef enum _SYSTEM_INFORMATION_CLASS { SystemProcessesAndThreadsInformation = 5,
SystemBasicInformation = 0 /* There are a lot more of these... */
/* Dropped each other since not used here. */
} SYSTEM_INFORMATION_CLASS; } SYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_BASIC_INFORMATION { typedef struct _SYSTEM_BASIC_INFORMATION
{
ULONG Unknown; ULONG Unknown;
ULONG MaximumIncrement; ULONG MaximumIncrement;
ULONG PhysicalPageSize; ULONG PhysicalPageSize;
@ -32,19 +32,130 @@ typedef struct _SYSTEM_BASIC_INFORMATION {
ULONG NumberProcessors; ULONG NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
/* typedef LONG KPRIORITY;
* Function declarations for ntdll.dll. They doesn't appear in any typedef struct _VM_COUNTERS
* Win32 header either. {
*/ ULONG PeakVirtualSize;
extern "C" { ULONG VirtualSize;
NTSTATUS NTAPI NtMapViewOfSection(HANDLE,HANDLE,PVOID*,ULONG,ULONG, ULONG PageFaultCount;
PLARGE_INTEGER,PULONG,SECTION_INHERIT, ULONG PeakWorkingSetSize;
ULONG,ULONG); ULONG WorkingSetSize;
NTSTATUS NTAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS, ULONG QuotaPeakPagedPoolUsage;
PVOID,ULONG,PULONG); ULONG QuotaPagedPoolUsage;
NTSTATUS NTAPI NtOpenSection(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES); ULONG QuotaPeakNonPagedPoolUsage;
NTSTATUS NTAPI NtUnmapViewOfSection(HANDLE,PVOID); ULONG QuotaNonPagedPoolUsage;
VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR); ULONG PagefileUsage;
ULONG NTAPI RtlNtStatusToDosError(NTSTATUS); 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);
}

View File

@ -24,6 +24,8 @@ details. */
#include "environ.h" #include "environ.h"
#include "security.h" #include "security.h"
#include <assert.h> #include <assert.h>
#include <ntdef.h>
#include "ntdll.h"
static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0}; static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
@ -279,9 +281,8 @@ cygwin_winpid_to_pid (int winpid)
} }
#include <tlhelp32.h> #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 HANDLE (WINAPI * CREATESNAPSHOT) (DWORD, DWORD);
typedef BOOL (WINAPI * PROCESSWALK) (HANDLE, LPPROCESSENTRY32); typedef BOOL (WINAPI * PROCESSWALK) (HANDLE, LPPROCESSENTRY32);
typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE); typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE);
@ -289,65 +290,101 @@ typedef BOOL (WINAPI * CLOSESNAPSHOT) (HANDLE);
static NO_COPY CREATESNAPSHOT myCreateToolhelp32Snapshot = NULL; static NO_COPY CREATESNAPSHOT myCreateToolhelp32Snapshot = NULL;
static NO_COPY PROCESSWALK myProcess32First = NULL; static NO_COPY PROCESSWALK myProcess32First = NULL;
static NO_COPY PROCESSWALK myProcess32Next = 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 NO_COPY ENUMPROCESSES myEnumProcesses = enum_init;
static BOOL WINAPI #define slop_pidlist 200
EnumProcessesW95 (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded) #define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
{
HANDLE h;
*cbneeded = 0; static DWORD WINAPI
h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 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)
{
DWORD nelem = 0;
HANDLE h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
if (!h) if (!h)
return 0; {
system_printf ("Couldn't create process snapshot, %E");
return 0;
}
PROCESSENTRY32 proc; PROCESSENTRY32 proc;
int i = 0;
proc.dwSize = sizeof (proc); proc.dwSize = sizeof (proc);
if (myProcess32First(h, &proc)) if (myProcess32First(h, &proc))
do 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)); while (myProcess32Next (h, &proc));
CloseHandle (h); CloseHandle (h);
if (i == 0) return nelem;
return 0;
*cbneeded = i * sizeof (DWORD);
return 1;
} }
void void
winpids::init () winpids::init ()
{ {
DWORD n; npids = myEnumProcesses (pidlist, npidlist);
if (!myEnumProcesses (pidlist, sizeof (pidlist) / sizeof (pidlist[0]), &n))
npids = 0;
else
npids = n / sizeof (pidlist[0]);
pidlist[npids] = 0; pidlist[npids] = 0;
} }
static BOOL WINAPI static DWORD WINAPI
enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded) enum_init (DWORD* &pidlist, DWORD& npidlist)
{ {
HINSTANCE h; HINSTANCE h;
if (os_being_run == winNT) if (os_being_run == winNT)
{ myEnumProcesses = EnumProcessesNT;
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;
}
}
else else
{ {
h = GetModuleHandle("kernel32.dll"); h = GetModuleHandle("kernel32.dll");
@ -363,8 +400,8 @@ enum_init (DWORD *lpidProcess, DWORD cb, DWORD *cbneeded)
return 0; return 0;
} }
myEnumProcesses = EnumProcessesW95; myEnumProcesses = EnumProcesses9x;
} }
return myEnumProcesses (lpidProcess, cb, cbneeded); return myEnumProcesses (pidlist, npidlist);
} }

View File

@ -186,12 +186,13 @@ public:
class winpids class winpids
{ {
DWORD pidlist[16384]; DWORD *pidlist;
DWORD npidlist;
public: public:
DWORD npids; DWORD npids;
void reset () { npids = 0; } void reset () { npids = 0; }
winpids (int) { reset (); } winpids (int) { reset (); }
winpids () { init (); }; winpids (): pidlist (NULL), npidlist (0) { init (); };
void init (); void init ();
int operator [] (int i) const {return pidlist[i];} int operator [] (int i) const {return pidlist[i];}
}; };