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:
authorCorinna Vinschen <corinna@vinschen.de>2011-12-22 17:48:05 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-12-22 17:48:05 +0400
commit185ad82d2dd9bb352cacdeb6cfab7a4f9dfae826 (patch)
tree6826b6686f11ec7a80963fc2720f43c115314a87 /winsup
parenta6ae9400a7b73c98822a14ade728aa559ae646af (diff)
Don't leave Windows 2000 behind.
* 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.
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);