From e9dde4758fd5ca0bdad00ac96f25c86476dd8148 Mon Sep 17 00:00:00 2001 From: cgf Date: Thu, 2 Nov 2000 05:25:56 +0000 Subject: [PATCH] * 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'. --- winsup/cygwin/ChangeLog | 13 ++++ winsup/cygwin/autoload.cc | 1 + winsup/cygwin/ntdll.h | 159 +++++++++++++++++++++++++++++++++++++++------- winsup/cygwin/pinfo.cc | 115 +++++++++++++++++++++------------ winsup/cygwin/pinfo.h | 5 +- 5 files changed, 228 insertions(+), 65 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 0d4ef611d1..b76afbfc8e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +Thu Nov 2 00:10:23 2000 Christopher Faylor + + * 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 * exceptions.cc (interruptible): Remove obsolete tests. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index a24ec40d3e..6f9344a437 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -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) diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index bdb4fe8bac..79a8c732c2 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -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); +} diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 3b5f002e4a..850a51b85c 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -24,6 +24,8 @@ details. */ #include "environ.h" #include "security.h" #include +#include +#include "ntdll.h" static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0}; @@ -279,9 +281,8 @@ cygwin_winpid_to_pid (int winpid) } #include -#include -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); } diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h index e9d54cf657..0620047ab2 100644 --- a/winsup/cygwin/pinfo.h +++ b/winsup/cygwin/pinfo.h @@ -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];} }; -- 2.11.0