Use QueryFullProcessImageName() if available.

A 32-bit process running on 64-bit Windows can't read the image name of
a 64-bit process, so printing the process tree will fail.  However, on
Windows Vista or later we have QueryFullProcessImageName() which is able
to retrieve the path.
master
Iain Patterson 9 years ago
parent b013e3bce4
commit 94d25a5dcf

@ -878,6 +878,9 @@ processes started by a given service:
nssm processes <servicename> nssm processes <servicename>
Note that if 32-bit NSSM is run on a 64-bit system running an older version of
Windows than Vista it will not be able to query the paths of 64-bit processes.
Exporting service configuration Exporting service configuration
------------------------------- -------------------------------

@ -59,14 +59,19 @@ int get_imports() {
if (error != ERROR_PROC_NOT_FOUND) return 2; if (error != ERROR_PROC_NOT_FOUND) return 2;
} }
imports.QueryFullProcessImageName = (QueryFullProcessImageName_ptr) get_import(imports.kernel32, QUERYFULLPROCESSIMAGENAME_EXPORT, &error);
if (! imports.QueryFullProcessImageName) {
if (error != ERROR_PROC_NOT_FOUND) return 3;
}
imports.SleepConditionVariableCS = (SleepConditionVariableCS_ptr) get_import(imports.kernel32, "SleepConditionVariableCS", &error); imports.SleepConditionVariableCS = (SleepConditionVariableCS_ptr) get_import(imports.kernel32, "SleepConditionVariableCS", &error);
if (! imports.SleepConditionVariableCS) { if (! imports.SleepConditionVariableCS) {
if (error != ERROR_PROC_NOT_FOUND) return 3; if (error != ERROR_PROC_NOT_FOUND) return 4;
} }
imports.WakeConditionVariable = (WakeConditionVariable_ptr) get_import(imports.kernel32, "WakeConditionVariable", &error); imports.WakeConditionVariable = (WakeConditionVariable_ptr) get_import(imports.kernel32, "WakeConditionVariable", &error);
if (! imports.WakeConditionVariable) { if (! imports.WakeConditionVariable) {
if (error != ERROR_PROC_NOT_FOUND) return 4; if (error != ERROR_PROC_NOT_FOUND) return 5;
} }
} }
else if (error != ERROR_MOD_NOT_FOUND) return 1; else if (error != ERROR_MOD_NOT_FOUND) return 1;
@ -75,14 +80,14 @@ int get_imports() {
if (imports.advapi32) { if (imports.advapi32) {
imports.CreateWellKnownSid = (CreateWellKnownSid_ptr) get_import(imports.advapi32, "CreateWellKnownSid", &error); imports.CreateWellKnownSid = (CreateWellKnownSid_ptr) get_import(imports.advapi32, "CreateWellKnownSid", &error);
if (! imports.CreateWellKnownSid) { if (! imports.CreateWellKnownSid) {
if (error != ERROR_PROC_NOT_FOUND) return 6; if (error != ERROR_PROC_NOT_FOUND) return 7;
} }
imports.IsWellKnownSid = (IsWellKnownSid_ptr) get_import(imports.advapi32, "IsWellKnownSid", &error); imports.IsWellKnownSid = (IsWellKnownSid_ptr) get_import(imports.advapi32, "IsWellKnownSid", &error);
if (! imports.IsWellKnownSid) { if (! imports.IsWellKnownSid) {
if (error != ERROR_PROC_NOT_FOUND) return 7; if (error != ERROR_PROC_NOT_FOUND) return 8;
} }
} }
else if (error != ERROR_MOD_NOT_FOUND) return 5; else if (error != ERROR_MOD_NOT_FOUND) return 6;
return 0; return 0;
} }

@ -1,8 +1,16 @@
#ifndef IMPORTS_H #ifndef IMPORTS_H
#define IMPORTS_H #define IMPORTS_H
/* Some functions don't have decorated versions. */
#ifdef UNICODE
#define QUERYFULLPROCESSIMAGENAME_EXPORT "QueryFullProcessImageNameW"
#else
#define QUERYFULLPROCESSIMAGENAME_EXPORT "QueryFullProcessImageNameA"
#endif
typedef BOOL (WINAPI *AttachConsole_ptr)(DWORD); typedef BOOL (WINAPI *AttachConsole_ptr)(DWORD);
typedef BOOL (WINAPI *SleepConditionVariableCS_ptr)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD); typedef BOOL (WINAPI *SleepConditionVariableCS_ptr)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD);
typedef BOOL (WINAPI *QueryFullProcessImageName_ptr)(HANDLE, unsigned long, LPTSTR, unsigned long *);
typedef void (WINAPI *WakeConditionVariable_ptr)(PCONDITION_VARIABLE); typedef void (WINAPI *WakeConditionVariable_ptr)(PCONDITION_VARIABLE);
typedef BOOL (WINAPI *CreateWellKnownSid_ptr)(WELL_KNOWN_SID_TYPE, SID *, SID *, unsigned long *); typedef BOOL (WINAPI *CreateWellKnownSid_ptr)(WELL_KNOWN_SID_TYPE, SID *, SID *, unsigned long *);
typedef BOOL (WINAPI *IsWellKnownSid_ptr)(SID *, WELL_KNOWN_SID_TYPE); typedef BOOL (WINAPI *IsWellKnownSid_ptr)(SID *, WELL_KNOWN_SID_TYPE);
@ -12,6 +20,7 @@ typedef struct {
HMODULE advapi32; HMODULE advapi32;
AttachConsole_ptr AttachConsole; AttachConsole_ptr AttachConsole;
SleepConditionVariableCS_ptr SleepConditionVariableCS; SleepConditionVariableCS_ptr SleepConditionVariableCS;
QueryFullProcessImageName_ptr QueryFullProcessImageName;
WakeConditionVariable_ptr WakeConditionVariable; WakeConditionVariable_ptr WakeConditionVariable;
CreateWellKnownSid_ptr CreateWellKnownSid; CreateWellKnownSid_ptr CreateWellKnownSid;
IsWellKnownSid_ptr IsWellKnownSid; IsWellKnownSid_ptr IsWellKnownSid;

@ -411,7 +411,18 @@ int print_process(nssm_service_t *service, kill_t *k) {
buffer[i] = _T('\0'); buffer[i] = _T('\0');
} }
} }
if (! GetModuleFileNameEx(k->process_handle, NULL, exe, _countof(exe))) _sntprintf_s(exe, _countof(exe), _TRUNCATE, _T("???"));
unsigned long size = _countof(exe);
if (! imports.QueryFullProcessImageName || ! imports.QueryFullProcessImageName(k->process_handle, 0, exe, &size)) {
/*
Fall back to GetModuleFileNameEx(), which won't work for WOW64 processes.
*/
if (! GetModuleFileNameEx(k->process_handle, NULL, exe, _countof(exe))) {
long error = GetLastError();
if (error == ERROR_PARTIAL_COPY) _sntprintf_s(exe, _countof(exe), _TRUNCATE, _T("[WOW64]"));
else _sntprintf_s(exe, _countof(exe), _TRUNCATE, _T("???"));
}
}
_tprintf(_T("% 8lu %s%s\n"), k->pid, buffer ? buffer : _T(""), exe); _tprintf(_T("% 8lu %s%s\n"), k->pid, buffer ? buffer : _T(""), exe);

Loading…
Cancel
Save