| Index: third_party/psutil/psutil/arch/mswindows/process_info.c
|
| diff --git a/third_party/psutil/psutil/arch/mswindows/process_info.c b/third_party/psutil/psutil/arch/mswindows/process_info.c
|
| index 3713eae00910b4bde0c2ec6492de6e8a1e45143d..53b14803d39bf87f9a94179418005ab0a8b4de9c 100644
|
| --- a/third_party/psutil/psutil/arch/mswindows/process_info.c
|
| +++ b/third_party/psutil/psutil/arch/mswindows/process_info.c
|
| @@ -1,5 +1,9 @@
|
| /*
|
| - * $Id: process_info.c 778 2010-11-08 19:59:08Z g.rodola $
|
| + * $Id: process_info.c 1142 2011-10-05 18:45:49Z g.rodola $
|
| + *
|
| + * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| *
|
| * Helper functions related to fetching process information. Used by
|
| * _psutil_mswindows module methods.
|
| @@ -12,7 +16,7 @@
|
|
|
| #include "security.h"
|
| #include "process_info.h"
|
| -
|
| +#include "ntextapi.h"
|
|
|
| /*
|
| * NtQueryInformationProcess code taken from
|
| @@ -29,13 +33,6 @@ typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
|
| PDWORD ReturnLength
|
| );
|
|
|
| -typedef struct _UNICODE_STRING
|
| -{
|
| - USHORT Length;
|
| - USHORT MaximumLength;
|
| - PWSTR Buffer;
|
| -} UNICODE_STRING, *PUNICODE_STRING;
|
| -
|
| typedef struct _PROCESS_BASIC_INFORMATION
|
| {
|
| PVOID Reserved1;
|
| @@ -47,33 +44,6 @@ typedef struct _PROCESS_BASIC_INFORMATION
|
|
|
|
|
| /*
|
| - * Set OSError(errno=ESRCH, strerror="No such process") Python exception.
|
| - */
|
| -PyObject *
|
| -NoSuchProcess(void) {
|
| - PyObject *exc;
|
| - char *msg = strerror(ESRCH);
|
| - exc = PyObject_CallFunction(PyExc_OSError, "(is)", ESRCH, msg);
|
| - PyErr_SetObject(PyExc_OSError, exc);
|
| - Py_XDECREF(exc);
|
| - return NULL;
|
| -}
|
| -
|
| -/*
|
| - * Set OSError(errno=EACCES, strerror="No such process") Python exception.
|
| - */
|
| -PyObject *
|
| -AccessDenied(void) {
|
| - PyObject *exc;
|
| - char *msg = strerror(EACCES);
|
| - exc = PyObject_CallFunction(PyExc_OSError, "(is)", EACCES, msg);
|
| - PyErr_SetObject(PyExc_OSError, exc);
|
| - Py_XDECREF(exc);
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| -/*
|
| * A wrapper around OpenProcess setting NSP exception if process
|
| * no longer exists.
|
| * "pid" is the process pid, "dwDesiredAccess" is the first argument
|
| @@ -177,39 +147,6 @@ get_pids(DWORD *numberOfReturnedPIDs) {
|
|
|
|
|
| int
|
| -is_system_proc(DWORD pid) {
|
| - HANDLE hProcess;
|
| -
|
| - // Special case for PID 0 System Idle Process
|
| - // and PID 4 (SYSTEM)
|
| - if ((pid == 0) || (pid == 4)) {
|
| - return 1;
|
| - }
|
| - if (pid < 0) {
|
| - return 0;
|
| - }
|
| -
|
| - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
|
| - if (NULL == hProcess) {
|
| - // invalid parameter is no such process
|
| - if (GetLastError() == ERROR_INVALID_PARAMETER) {
|
| - return 0;
|
| - }
|
| -
|
| - // access denied obviously means there's a process to deny access to...
|
| - if (GetLastError() == ERROR_ACCESS_DENIED) {
|
| - return 1;
|
| - }
|
| -
|
| - PyErr_SetFromWindowsErr(0);
|
| - return -1;
|
| - }
|
| -
|
| - return HasSystemPrivilege(hProcess);
|
| -}
|
| -
|
| -
|
| -int
|
| pid_is_running(DWORD pid)
|
| {
|
| HANDLE hProcess;
|
| @@ -270,7 +207,7 @@ pid_in_proclist(DWORD pid)
|
|
|
| proclist = get_pids(&numberOfReturnedPIDs);
|
| if (NULL == proclist) {
|
| - return NULL;
|
| + return -1;
|
| }
|
|
|
| for (i = 0; i < numberOfReturnedPIDs; i++) {
|
| @@ -340,7 +277,7 @@ get_ppid(long pid)
|
| if( Process32First(h, &pe)) {
|
| do {
|
| if (pe.th32ProcessID == pid) {
|
| - //printf("PID: %i; PPID: %i\n", pid, pe.th32ParentProcessID);
|
| + ////printf("PID: %i; PPID: %i\n", pid, pe.th32ParentProcessID);
|
| CloseHandle(h);
|
| return Py_BuildValue("I", pe.th32ParentProcessID);
|
| }
|
| @@ -376,7 +313,6 @@ get_arg_list(long pid)
|
| PyObject *arg_from_wchar = NULL;
|
| PyObject *argList = NULL;
|
|
|
| -
|
| hProcess = handle_from_pid(pid);
|
| if(hProcess == NULL) {
|
| return NULL;
|
| @@ -393,7 +329,7 @@ get_arg_list(long pid)
|
| &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
|
| #endif
|
| {
|
| - //printf("Could not read the address of ProcessParameters!\n");
|
| + ////printf("Could not read the address of ProcessParameters!\n");
|
| PyErr_SetFromWindowsErr(0);
|
| CloseHandle(hProcess);
|
| return NULL;
|
| @@ -408,9 +344,9 @@ get_arg_list(long pid)
|
| &commandLine, sizeof(commandLine), NULL))
|
| #endif
|
| {
|
| - //printf("Could not read CommandLine!\n");
|
| - PyErr_SetFromWindowsErr(0);
|
| + ////printf("Could not read CommandLine!\n");
|
| CloseHandle(hProcess);
|
| + PyErr_SetFromWindowsErr(0);
|
| return NULL;
|
| }
|
|
|
| @@ -422,15 +358,15 @@ get_arg_list(long pid)
|
| if (!ReadProcessMemory(hProcess, commandLine.Buffer,
|
| commandLineContents, commandLine.Length, NULL))
|
| {
|
| - //printf("Could not read the command line string!\n");
|
| - PyErr_SetFromWindowsErr(0);
|
| + ////printf("Could not read the command line string!\n");
|
| CloseHandle(hProcess);
|
| + PyErr_SetFromWindowsErr(0);
|
| free(commandLineContents);
|
| return NULL;
|
| }
|
|
|
| /* print the commandline */
|
| - //printf("%.*S\n", commandLine.Length / 2, commandLineContents);
|
| + ////printf("%.*S\n", commandLine.Length / 2, commandLineContents);
|
|
|
| // null-terminate the string to prevent wcslen from returning incorrect length
|
| // the length specifier is in characters, but commandLine.Length is in bytes
|
| @@ -455,7 +391,7 @@ get_arg_list(long pid)
|
| // string object and add to arg list
|
| argList = Py_BuildValue("[]");
|
| for(i=0; i<nArgs; i++) {
|
| - //printf("%d: %.*S (%d characters)\n", i, wcslen(szArglist[i]),
|
| + ////printf("%d: %.*S (%d characters)\n", i, wcslen(szArglist[i]),
|
| // szArglist[i], wcslen(szArglist[i]));
|
| arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
|
| wcslen(szArglist[i])
|
| @@ -477,3 +413,78 @@ get_arg_list(long pid)
|
| return argList;
|
| }
|
|
|
| +
|
| +#define PH_FIRST_PROCESS(Processes) ((PSYSTEM_PROCESS_INFORMATION)(Processes))
|
| +
|
| +#define PH_NEXT_PROCESS(Process) ( \
|
| + ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \
|
| + (PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \
|
| + ((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : \
|
| + NULL \
|
| + )
|
| +
|
| +const STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
|
| +const STATUS_BUFFER_TOO_SMALL = 0xC0000023L;
|
| +
|
| +/*
|
| + * Given a process PID and a PSYSTEM_PROCESS_INFORMATION structure
|
| + * fills the structure with process information.
|
| + * On success return 1, else 0 with Python exception already set.
|
| + */
|
| +int
|
| +get_process_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess, PVOID *retBuffer)
|
| +{
|
| + static ULONG initialBufferSize = 0x4000;
|
| + NTSTATUS status;
|
| + PVOID buffer;
|
| + ULONG bufferSize;
|
| + PSYSTEM_PROCESS_INFORMATION process;
|
| +
|
| + // get NtQuerySystemInformation
|
| + typedef DWORD (_stdcall *NTQSI_PROC) (int, PVOID, ULONG, PULONG);
|
| + NTQSI_PROC NtQuerySystemInformation;
|
| + HINSTANCE hNtDll;
|
| + hNtDll = LoadLibrary(TEXT("ntdll.dll"));
|
| + NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
|
| + hNtDll, "NtQuerySystemInformation");
|
| +
|
| + bufferSize = initialBufferSize;
|
| + buffer = malloc(bufferSize);
|
| +
|
| + while (TRUE) {
|
| + status = NtQuerySystemInformation(SystemProcessInformation, buffer,
|
| + bufferSize, &bufferSize);
|
| +
|
| + if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
|
| + {
|
| + free(buffer);
|
| + buffer = malloc(bufferSize);
|
| + }
|
| + else {
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (status != 0) {
|
| + PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed");
|
| + return 0;
|
| + }
|
| +
|
| + if (bufferSize <= 0x20000) {
|
| + initialBufferSize = bufferSize;
|
| + }
|
| +
|
| + process = PH_FIRST_PROCESS(buffer);
|
| + do {
|
| + if (process->UniqueProcessId == (HANDLE)pid) {
|
| + *retProcess = process;
|
| + *retBuffer = buffer;
|
| + return 1;
|
| + }
|
| + } while ( (process = PH_NEXT_PROCESS(process)) );
|
| +
|
| + NoSuchProcess();
|
| + return 0;
|
| +}
|
| +
|
| +
|
|
|