Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/utils/ChangeLog9
-rw-r--r--winsup/utils/Makefile.in2
-rw-r--r--winsup/utils/ps.cc83
3 files changed, 72 insertions, 22 deletions
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index 493bc3c79..489a0e363 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,5 +1,14 @@
2011-12-22 Corinna Vinschen <corinna@vinschen.de>
+ * Makefile.in (ps.exe): Revert previous change.
+ * ps.cc: Include psapi.h again.
+ (main): In CW_GETPINFO_FULL case. Evaluate minimal process access mask
+ required per OS and use that in OpenProcess call. Use
+ GetModuleFileNameExW on Windows 2000 or if fetching the drive mapping
+ failed. Handle empty process name.
+
+2011-12-22 Corinna Vinschen <corinna@vinschen.de>
+
* Makefile.in (ps.exe): Drop -lpsapi from ALL_LDFLAGS.
* ps.cc: Don't include psapi.h.
(dosdevs): Drop.
diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in
index b84432c7f..bea7070c6 100644
--- a/winsup/utils/Makefile.in
+++ b/winsup/utils/Makefile.in
@@ -77,7 +77,7 @@ mount.exe: path-mount.o
cygcheck.exe: MINGW_LDFLAGS += -lntdll
cygpath.exe: ALL_LDFLAGS += -lcygwin -luserenv -lntdll
cygpath.exe: CXXFLAGS += -fno-threadsafe-statics
-ps.exe: ALL_LDFLAGS += -lcygwin -lntdll
+ps.exe: ALL_LDFLAGS += -lcygwin -lpsapi -lntdll
strace.exe: MINGW_LDFLAGS += -lntdll
ldd.exe: ALL_LDFLAGS += -lpsapi
diff --git a/winsup/utils/ps.cc b/winsup/utils/ps.cc
index e43e134d0..e026518c4 100644
--- a/winsup/utils/ps.cc
+++ b/winsup/utils/ps.cc
@@ -22,6 +22,7 @@ details. */
#include <limits.h>
#include <sys/cygwin.h>
#include <cygwin/version.h>
+#include <psapi.h>
#include <ddk/ntapi.h>
#include <ddk/winddk.h>
#include "loadlib.h"
@@ -150,6 +151,7 @@ main (int argc, char *argv[])
external_pinfo *p;
int aflag, lflag, fflag, sflag, uid, proc_id;
bool found_proc_id = true;
+ DWORD proc_access = PROCESS_QUERY_LIMITED_INFORMATION;
cygwin_getinfo_types query = CW_GETPINFO;
const char *dtitle = " PID TTY STIME COMMAND\n";
const char *dfmt = "%7d%4s%10s %s\n";
@@ -250,12 +252,33 @@ main (int argc, char *argv[])
AdjustTokenPrivileges (tok, FALSE, &priv, 0, NULL, NULL);
}
}
- /* Fetch an opaque drive mapping object from the Cygwin DLL.
- This is used to map NT device paths to Win32 paths. */
- drive_map = (void *) cygwin_internal (CW_ALLOC_DRIVE_MAP);
- /* Check old Cygwin version. */
- if (drive_map == (void *) -1)
- drive_map = NULL;
+
+ /* Check process query capabilities. */
+ OSVERSIONINFO version;
+ version.dwOSVersionInfoSize = sizeof version;
+ GetVersionEx (&version);
+ if (version.dwMajorVersion <= 5) /* pre-Vista */
+ {
+ proc_access = PROCESS_QUERY_INFORMATION;
+ if (version.dwMinorVersion < 1) /* Windows 2000 */
+ proc_access |= PROCESS_VM_READ;
+ else
+ {
+ }
+ }
+
+ /* Except on Windows 2000, fetch an opaque drive mapping object from the
+ Cygwin DLL. This is used to map NT device paths to Win32 paths. */
+ if (!(proc_access & PROCESS_VM_READ))
+ {
+ drive_map = (void *) cygwin_internal (CW_ALLOC_DRIVE_MAP);
+ /* Check old Cygwin version. */
+ if (drive_map == (void *) -1)
+ drive_map = NULL;
+ /* Allow fallback to GetModuleFileNameEx for post-W2K. */
+ if (!drive_map)
+ proc_access = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
+ }
}
for (int pid = 0;
@@ -298,29 +321,47 @@ main (int argc, char *argv[])
if (p->process_state & PID_EXITED || (p->exitcode & ~0xffff))
strcat (pname, " <defunct>");
}
- else if (query == CW_GETPINFO_FULL && drive_map)
+ else if (query == CW_GETPINFO_FULL)
{
HANDLE h;
NTSTATUS status;
wchar_t *win32path = NULL;
- h = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
- FALSE, p->dwProcessId);
+ h = OpenProcess (proc_access, FALSE, p->dwProcessId);
if (!h)
continue;
- status = NtQueryInformationProcess (h, ProcessImageFileName, uni,
- sizeof unicode_buf, NULL);
- if (NT_SUCCESS (status))
+ /* We use NtQueryInformationProcess in the first place, because
+ GetModuleFileNameEx does not work on 64 bit systems when trying
+ to fetch module names of 64 bit processes. */
+ if (!(proc_access & PROCESS_VM_READ)) /* Windows 2000 */
+ {
+ status = NtQueryInformationProcess (h, ProcessImageFileName, uni,
+ sizeof unicode_buf, 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 = L"System";
+ else
+ {
+ uni->Buffer[uni->Length / sizeof (WCHAR)] = L'\0';
+ win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP,
+ drive_map,
+ uni->Buffer);
+ }
+ }
+ }
+ else
{
- /* 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. */
- uni->Buffer[uni->Length / sizeof (WCHAR)] = L'\0';
- win32path = (wchar_t *) cygwin_internal (CW_MAP_DRIVE_MAP,
- drive_map, uni->Buffer);
+ if (GetModuleFileNameExW (h, NULL, (PWCHAR) unicode_buf,
+ NT_MAX_PATH))
+ win32path = (wchar_t *) unicode_buf;
}
if (win32path)
wcstombs (pname, win32path, sizeof pname);