diff --git a/src/os/win32/peb.c b/src/os/win32/peb.c index 153effe9..4fdbfcb8 100644 --- a/src/os/win32/peb.c +++ b/src/os/win32/peb.c @@ -99,6 +99,9 @@ int sigar_proc_exe_peb_get(sigar_t *sigar, HANDLE proc, RTL_USER_PROCESS_PARAMETERS rtl; DWORD size; + procexe->name[0] = '\0'; + procexe->cwd[0] = '\0'; + if ((status = sigar_rtl_get(sigar, proc, &rtl)) != SIGAR_OK) { return status; } @@ -111,9 +114,6 @@ int sigar_proc_exe_peb_get(sigar_t *sigar, HANDLE proc, { SIGAR_W2A(buf, procexe->name, sizeof(procexe->name)); } - else { - procexe->name[0] = '\0'; - } size = rtl_bufsize(buf, rtl.CurrentDirectoryName); memset(buf, '\0', sizeof(buf)); @@ -123,9 +123,6 @@ int sigar_proc_exe_peb_get(sigar_t *sigar, HANDLE proc, { SIGAR_W2A(buf, procexe->cwd, sizeof(procexe->cwd)); } - else { - procexe->cwd[0] = '\0'; - } return SIGAR_OK; } @@ -171,15 +168,16 @@ int sigar_proc_args_peb_get(sigar_t *sigar, HANDLE proc, } size = rtl_bufsize(buf, rtl.CommandLine); + if (size <= 0) { + return ERROR_DATATYPE_MISMATCH; /* fallback to wmi */ + } memset(buf, '\0', sizeof(buf)); - - if ((size > 0) && - ReadProcessMemory(proc, rtl.CommandLine.Buffer, buf, size, NULL)) - { + + if (ReadProcessMemory(proc, rtl.CommandLine.Buffer, buf, size, NULL)) { return sigar_parse_proc_args(sigar, buf, procargs); } else { - return SIGAR_OK; + return GetLastError(); } } diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 9d61ba0a..ccbc8c37 100644 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -1435,19 +1435,21 @@ static int sigar_remote_proc_args_get(sigar_t *sigar, sigar_pid_t pid, char cmdline[SIGAR_CMDLINE_MAX], *ptr = cmdline, *arg; HANDLE proc = open_process(pid); - if (!proc) { - return GetLastError(); + if (proc) { + status = sigar_proc_args_peb_get(sigar, proc, procargs); + + CloseHandle(proc); + + if (status == SIGAR_OK) { + return status; + } } - status = sigar_proc_args_peb_get(sigar, proc, procargs); - - CloseHandle(proc); - - if (status == ERROR_DATATYPE_MISMATCH) { - /* we are 32-bit, pid process is 64-bit */ - status = sigar_proc_args_wmi_get(sigar, pid, procargs); + /* likely we are 32-bit, pid process is 64-bit */ + status = sigar_proc_args_wmi_get(sigar, pid, procargs); + if (status == ERROR_NOT_FOUND) { + status = SIGAR_NO_SUCH_PROCESS; } - return status; } @@ -1608,10 +1610,13 @@ SIGAR_DECLARE(int) sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid, } status = sigar_proc_exe_peb_get(sigar, proc, procexe); - if (status == ERROR_DATATYPE_MISMATCH) { - /* we are 32-bit, pid process is 64-bit */ - procexe->cwd[0] = '\0'; /* XXX where else can we try? */ + if (procexe->name[0] == '\0') { + /* likely we are 32-bit, pid process is 64-bit */ + /* procexe->cwd[0] = XXX where else can we try? */ status = sigar_proc_exe_wmi_get(sigar, pid, procexe); + if (status == ERROR_NOT_FOUND) { + status = SIGAR_NO_SUCH_PROCESS; + } } if (procexe->cwd[0] != '\0') { diff --git a/src/os/win32/wmi.cpp b/src/os/win32/wmi.cpp index a816bbd9..82229cab 100644 --- a/src/os/win32/wmi.cpp +++ b/src/os/win32/wmi.cpp @@ -42,15 +42,18 @@ class WMI { HRESULT GetProcStringProperty(DWORD pid, TCHAR *name, TCHAR *value, DWORD len); HRESULT GetProcExecutablePath(DWORD pid, TCHAR *value); HRESULT GetProcCommandLine(DWORD pid, TCHAR *value); + int GetLastError(); private: IWbemServices *wbem; + HRESULT result; BSTR GetProcQuery(DWORD pid); }; WMI::WMI() { wbem = NULL; + result = S_OK; CoInitializeEx(NULL, COINIT_MULTITHREADED); } @@ -60,14 +63,31 @@ WMI::~WMI() CoUninitialize(); } +/* XXX must be a better way to map HRESULT */ +int WMI::GetLastError() +{ + switch (result) { + case S_OK: + return ERROR_SUCCESS; + case WBEM_E_NOT_FOUND: + return ERROR_NOT_FOUND; + case WBEM_E_ACCESS_DENIED: + return ERROR_ACCESS_DENIED; + case WBEM_E_NOT_SUPPORTED: + return SIGAR_ENOTIMPL; + default: + return ERROR_INVALID_FUNCTION; + } +} + HRESULT WMI::Open(LPCTSTR machine, LPCTSTR user, LPCTSTR pass) { - HRESULT result; IWbemLocator *locator; wchar_t path[MAX_PATH]; if (wbem) { - return S_OK; + result = S_OK; + return result; } result = @@ -116,6 +136,7 @@ void WMI::Close() if (wbem) { wbem->Release(); wbem = NULL; + result = S_OK; } } @@ -128,7 +149,6 @@ BSTR WMI::GetProcQuery(DWORD pid) HRESULT WMI::GetProcStringProperty(DWORD pid, TCHAR *name, TCHAR *value, DWORD len) { - HRESULT result; IWbemClassObject *obj; VARIANT var; @@ -177,11 +197,11 @@ extern "C" int sigar_proc_args_wmi_get(sigar_t *sigar, sigar_pid_t pid, WMI *wmi = new WMI(); if (FAILED(wmi->Open())) { - return GetLastError(); + return wmi->GetLastError(); } if (FAILED(wmi->GetProcCommandLine(pid, buf))) { - status = GetLastError(); + status = wmi->GetLastError(); } else { status = sigar_parse_proc_args(sigar, buf, procargs); @@ -201,13 +221,13 @@ extern "C" int sigar_proc_exe_wmi_get(sigar_t *sigar, sigar_pid_t pid, WMI *wmi = new WMI(); if (FAILED(wmi->Open())) { - return GetLastError(); + return wmi->GetLastError(); } procexe->name[0] = '\0'; if (FAILED(wmi->GetProcExecutablePath(pid, buf))) { - status = GetLastError(); + status = wmi->GetLastError(); } else { status = SIGAR_OK;