From: Corinna Vinschen Date: Mon, 11 May 2009 14:01:17 +0000 (+0000) Subject: * Makefile.in: Link ps.exe agains ntdll.dll. X-Git-Tag: sid-snapshot-20090601~44 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=46777e0a3d3dce21aac5609fa0406a7c85ae0403;p=newlib-cygwin.git * Makefile.in: Link ps.exe agains ntdll.dll. * ps.cc (main): Enable SE_DEBUG_NAME privilege if Windows processes have to be enumerated. Workaround EnumProcessModules problem when running under WOW64 and use NtQueryInformationProcess to fetch process image name. --- diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog index a40070def..cb29eee31 100644 --- a/winsup/utils/ChangeLog +++ b/winsup/utils/ChangeLog @@ -1,3 +1,11 @@ +2009-05-11 Corinna Vinschen + + * Makefile.in: Link ps.exe agains ntdll.dll. + * ps.cc (main): Enable SE_DEBUG_NAME privilege if Windows processes + have to be enumerated. Workaround EnumProcessModules problem when + running under WOW64 and use NtQueryInformationProcess to fetch + process image name. + 2009-05-06 Corinna Vinschen * mkpasswd.c (current_user): Don't use HOMEDRIVE/HOMEPATH to generate diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in index f52b6186d..103942778 100644 --- a/winsup/utils/Makefile.in +++ b/winsup/utils/Makefile.in @@ -72,6 +72,7 @@ cygcheck.exe: bloda.o path.o dump_setup.o # Provide any necessary per-target variable overrides. cygcheck.exe: MINGW_LDFLAGS += -lntdll cygpath.exe: ALL_LDFLAGS += -lntdll +ps.exe: ALL_LDFLAGS += -lntdll ldd.exe: ALL_LDFLAGS += -lpsapi diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc index 2ad2a39a5..bd7879bf6 100644 --- a/winsup/utils/ps.cc +++ b/winsup/utils/ps.cc @@ -1,7 +1,7 @@ /* ps.cc Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2008 Red Hat, Inc. + 2008, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -10,6 +10,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include +#include #include #include #include @@ -20,6 +21,8 @@ details. */ #include #include #include +#include +#include /* Maximum possible path length under NT. There's no official define for that value. Note that PATH_MAX is only 4K. */ @@ -248,6 +251,8 @@ Compiled on %s\n\ ", prog_name, len, v, __DATE__); } +char dosdevs[32000]; + int main (int argc, char *argv[]) { @@ -261,6 +266,7 @@ 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 %4u %8s %s\n"; char ch; + PUNICODE_STRING uni = NULL; aflag = lflag = fflag = sflag = 0; uid = getuid (); @@ -336,6 +342,26 @@ main (int argc, char *argv[]) if (query == CW_GETPINFO_FULL && !init_win ()) query = CW_GETPINFO; + if (query == CW_GETPINFO_FULL) + { + /* Enable debug privilege to allow to enumerate all processes, + not only processes in current session. */ + HANDLE tok; + if (OpenProcessToken (GetCurrentProcess (), + TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, + &tok)) + { + TOKEN_PRIVILEGES priv; + + priv.PrivilegeCount = 1; + if (LookupPrivilegeValue (NULL, SE_DEBUG_NAME, + &priv.Privileges[0].Luid)) + { + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges (tok, FALSE, &priv, 0, NULL, NULL); + } + } + } for (int pid = 0; (p = (external_pinfo *) cygwin_internal (query, pid | CW_NEXTPID)); @@ -390,7 +416,53 @@ main (int argc, char *argv[]) DWORD n = p->dwProcessId; if (!myEnumProcessModules (h, hm, sizeof (hm), &n)) n = 0; - if (!n || !myGetModuleFileNameEx (h, hm[0], pname, PATH_MAX)) + /* This occurs when trying to enum modules of a 64 bit process. + GetModuleFileNameEx with a NULL module will return the same error. + Only NtQueryInformationProcess allows to fetch the process image + name in that case. */ + if (!n && GetLastError () == ERROR_PARTIAL_COPY) + { + NTSTATUS status; + char pbuf[PATH_MAX]; + char dev[256]; + size_t len = sizeof (UNICODE_STRING) + PATH_MAX * sizeof (WCHAR); + + if (!uni) + { + uni = (PUNICODE_STRING) alloca (len); + QueryDosDevice (NULL, dosdevs, 32000); + } + status = NtQueryInformationProcess (h, ProcessImageFileName, uni, + len, NULL); + if (NT_SUCCESS (status) + && (len = wcsnrtombs (pbuf, (const wchar_t **) &uni->Buffer, + uni->Length / sizeof (WCHAR), PATH_MAX, + NULL)) > 0) + { + pbuf[len] = '\0'; + if (!strncmp (pbuf, "\\Device\\Mup\\", 12)) + { + strcpy (pname, "\\\\"); + strcpy (pname + 2, pbuf + 12); + } + else + { + strcpy (pname, pbuf); + for (char *d = dosdevs; *d; d = strchr (d, '\0') + 1) + if (QueryDosDevice (d, dev, 256) + && strlen (d) < 3 + && !strncmp (dev, pbuf, strlen (dev))) + { + strcpy (pname, d); + strcat (pname, pbuf + strlen (dev)); + break; + } + } + } + else + strcpy (pname, "*** unknown ***"); + } + else if (!n || !myGetModuleFileNameEx (h, hm[0], pname, PATH_MAX)) strcpy (pname, "*** unknown ***"); FILETIME ct, et, kt, ut; if (GetProcessTimes (h, &ct, &et, &kt, &ut))