* 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:
		| @@ -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. | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
| @@ -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];} | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user