public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin] Cygwin: ps: show *all* processes in ps -W output
@ 2019-03-12 19:57 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2019-03-12 19:57 UTC (permalink / raw)
  To: cygwin-cvs

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=37a046181e92cd358adabd154b630bf76fe0bf2c

commit 37a046181e92cd358adabd154b630bf76fe0bf2c
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Tue Mar 12 20:55:24 2019 +0100

    Cygwin: ps: show *all* processes in ps -W output
    
    There's a long-standing bug in ps -W.  It only shows processes which ps
    can open with PROCESS_QUERY_LIMITED_INFORMATION permissions.  However,
    that fails for a lot of system processes. Due to that, output is
    basically restricted to processes in the same session, as well as Cygwin
    processes... which isn't *quite* what ps -W was supposed to do.
    
    Basically we only need to open the process to fetch the image name.  If
    that fails, utilize the undocumented SystemProcessIdInformation info
    class introduced with Windows Vista, which allows to fetch the image
    name by specifying the PID.  Restructure the code a bit.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/utils/ps.cc | 83 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 51 insertions(+), 32 deletions(-)

diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc
index ad46ab7..c655d74 100644
--- a/winsup/utils/ps.cc
+++ b/winsup/utils/ps.cc
@@ -26,7 +26,7 @@ details. */
 
 /* Maximum possible path length under NT.  There's no official define
    for that value.  Note that PATH_MAX is only 4K. */
-#define NT_MAX_PATH 32768
+#define NT_MAX_PATH 32767
 
 static char *prog_name;
 
@@ -140,7 +140,13 @@ print_version ()
 	  strrchr (__DATE__, ' ') + 1);
 }
 
-char unicode_buf[sizeof (UNICODE_STRING) + NT_MAX_PATH];
+struct
+{
+  SYSTEM_PROCESS_ID_INFORMATION spii;
+  WCHAR buf[NT_MAX_PATH + 1];
+} ucbuf;
+
+char pname[NT_MAX_PATH + sizeof (" <defunct>")  + 1];
 
 int
 main (int argc, char *argv[])
@@ -158,7 +164,6 @@ main (int argc, char *argv[])
   const char *ltitle = "      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND\n";
   const char *lfmt   = "%c %7d %7d %7d %10u %4s %8u %8s %s\n";
   char ch;
-  PUNICODE_STRING uni = (PUNICODE_STRING) unicode_buf;
   void *drive_map = NULL;
 
   aflag = lflag = fflag = sflag = 0;
@@ -288,7 +293,6 @@ main (int argc, char *argv[])
 
       /* Maximum possible path length under NT.  There's no official define
 	 for that value. */
-      char pname[NT_MAX_PATH + sizeof (" <defunct>")];
       if (p->ppid)
 	{
 	  char *s;
@@ -308,45 +312,60 @@ main (int argc, char *argv[])
 
 	  h = OpenProcess (proc_access, FALSE, p->dwProcessId);
 	  if (!h)
-	    continue;
+	    {
+	      ucbuf.spii.ProcessId = (PVOID) (ULONG_PTR) p->dwProcessId;
+	      ucbuf.spii.ImageName.Length = 0;
+	      ucbuf.spii.ImageName.MaximumLength = NT_MAX_PATH * sizeof (WCHAR);
+	      ucbuf.spii.ImageName.Buffer = ucbuf.buf;
+	      status = NtQuerySystemInformation (SystemProcessIdInformation,
+						 &ucbuf.spii, sizeof ucbuf.spii, NULL);
+	      if (NT_SUCCESS (status))
+		{
+		  if (ucbuf.spii.ImageName.Length)
+		    ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length
+					  / sizeof (WCHAR)] = L'\0';
+		  win32path = ucbuf.spii.ImageName.Buffer;
+		}
+	    }
 	  /* We use NtQueryInformationProcess in the first place, because
 	     GetModuleFileNameEx does not work under WOW64 when trying
 	     to fetch module names of 64 bit processes. */
-	  if (!(proc_access & PROCESS_VM_READ))
+	  else if (!(proc_access & PROCESS_VM_READ))
 	    {
-	      status = NtQueryInformationProcess (h, ProcessImageFileName, uni,
-						  sizeof unicode_buf, NULL);
+	      status = NtQueryInformationProcess (h, ProcessImageFileName,
+						  &ucbuf.spii.ImageName,
+						  sizeof ucbuf - sizeof (PVOID),
+						  NULL);
 	      if (NT_SUCCESS (status))
 		{
-		  /* NtQueryInformationProcess returns a native NT device path.
-		     Call CW_MAP_DRIVE_MAP to convert the path to an ordinary
-		     Win32 path.  The returned pointer is a pointer into the
-		     incoming buffer given as third argument.  It's expected
-		     to be big enough, which we made sure by defining
-		     unicode_buf to have enough space for a maximum sized
-		     UNICODE_STRING. */
-		  if (uni->Length == 0)	/* System process */
-		    win32path = (wchar_t *) L"System";
-		  else
-		    {
-		      uni->Buffer[uni->Length / sizeof (WCHAR)] = L'\0';
-		      win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP,
-							       drive_map,
-							       uni->Buffer);
-		    }
+		  if (ucbuf.spii.ImageName.Length)
+		    ucbuf.spii.ImageName.Buffer[ucbuf.spii.ImageName.Length / sizeof (WCHAR)] = L'\0';
+		  win32path = ucbuf.spii.ImageName.Buffer;
 		}
 	    }
-	  else if (GetModuleFileNameExW (h, NULL, (PWCHAR) unicode_buf,
-					 NT_MAX_PATH))
-	    win32path = (wchar_t *) unicode_buf;
+	  else if (GetModuleFileNameExW (h, NULL, ucbuf.buf,
+					 NT_MAX_PATH + 1))
+	    win32path = ucbuf.buf;
 	  if (win32path)
-	    wcstombs (pname, win32path, sizeof pname);
+	    {
+	      /* Call CW_MAP_DRIVE_MAP to convert native NT device paths to
+	         an ordinary Win32 path.  The returned pointer is a pointer
+		 into the incoming buffer given as third argument.  It's
+		 expected to be big enough. */
+	      if (win32path[0] == L'\\')
+		win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP,
+							 drive_map, win32path);
+	      wcstombs (pname, win32path, sizeof pname);
+	    }
 	  else
-	    strcpy (pname, "*** unknown ***");
+	    strcpy (pname, p->dwProcessId == 4 ? "System" : "*** unknown ***");
 	  FILETIME ct, et, kt, ut;
-	  if (GetProcessTimes (h, &ct, &et, &kt, &ut))
-	    p->start_time = to_time_t (&ct);
-	  CloseHandle (h);
+	  if (h)
+	    {
+	      if (GetProcessTimes (h, &ct, &et, &kt, &ut))
+		p->start_time = to_time_t (&ct);
+	      CloseHandle (h);
+	    }
 	}
 
       char uname[128];


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-03-12 19:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-12 19:57 [newlib-cygwin] Cygwin: ps: show *all* processes in ps -W output Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).