* 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>
* exceptions.cc (interruptible): Remove obsolete tests.

View 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)

View 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);
}

View 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)
{
HANDLE h;
#define slop_pidlist 200
#define size_pidlist(i) (sizeof (pidlist[0]) * ((i) + 1))
*cbneeded = 0;
h = myCreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
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)
{
DWORD nelem = 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);
}

View 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];}
};