| 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
 | 
| deleted file mode 100644
 | 
| index 53b14803d39bf87f9a94179418005ab0a8b4de9c..0000000000000000000000000000000000000000
 | 
| --- a/third_party/psutil/psutil/arch/mswindows/process_info.c
 | 
| +++ /dev/null
 | 
| @@ -1,490 +0,0 @@
 | 
| -/*
 | 
| - * $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.
 | 
| - */
 | 
| -
 | 
| -#include <Python.h>
 | 
| -#include <windows.h>
 | 
| -#include <Psapi.h>
 | 
| -#include <tlhelp32.h>
 | 
| -
 | 
| -#include "security.h"
 | 
| -#include "process_info.h"
 | 
| -#include "ntextapi.h"
 | 
| -
 | 
| -/*
 | 
| - * NtQueryInformationProcess code taken from
 | 
| - * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
 | 
| - * typedefs needed to compile against ntdll functions not exposted in the API
 | 
| - */
 | 
| -typedef LONG NTSTATUS;
 | 
| -
 | 
| -typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
 | 
| -    HANDLE ProcessHandle,
 | 
| -    DWORD ProcessInformationClass,
 | 
| -    PVOID ProcessInformation,
 | 
| -    DWORD ProcessInformationLength,
 | 
| -    PDWORD ReturnLength
 | 
| -    );
 | 
| -
 | 
| -typedef struct _PROCESS_BASIC_INFORMATION
 | 
| -{
 | 
| -    PVOID Reserved1;
 | 
| -    PVOID PebBaseAddress;
 | 
| -    PVOID Reserved2[2];
 | 
| -    ULONG_PTR UniqueProcessId;
 | 
| -    PVOID Reserved3;
 | 
| -} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
 | 
| -
 | 
| -
 | 
| -/*
 | 
| - * A wrapper around OpenProcess setting NSP exception if process
 | 
| - * no longer exists.
 | 
| - * "pid" is the process pid, "dwDesiredAccess" is the first argument
 | 
| - * exptected by OpenProcess.
 | 
| - * Return a process handle or NULL.
 | 
| - */
 | 
| -HANDLE
 | 
| -handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
 | 
| -{
 | 
| -    HANDLE hProcess;
 | 
| -    DWORD  processExitCode = 0;
 | 
| -
 | 
| -    hProcess = OpenProcess(dwDesiredAccess, FALSE, pid);
 | 
| -    if (hProcess == NULL) {
 | 
| -        if (GetLastError() == ERROR_INVALID_PARAMETER) {
 | 
| -            NoSuchProcess();
 | 
| -        }
 | 
| -        else {
 | 
| -            PyErr_SetFromWindowsErr(0);
 | 
| -        }
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -    /* make sure the process is running */
 | 
| -    GetExitCodeProcess(hProcess, &processExitCode);
 | 
| -    if (processExitCode == 0) {
 | 
| -        NoSuchProcess();
 | 
| -        CloseHandle(hProcess);
 | 
| -        return NULL;
 | 
| -    }
 | 
| -    return hProcess;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -/*
 | 
| - * Same as handle_from_pid_waccess but implicitly uses
 | 
| - * PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess
 | 
| - * parameter for OpenProcess.
 | 
| - */
 | 
| -HANDLE
 | 
| -handle_from_pid(DWORD pid) {
 | 
| -    DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
 | 
| -    return handle_from_pid_waccess(pid, dwDesiredAccess);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// fetch the PEB base address from NtQueryInformationProcess()
 | 
| -PVOID
 | 
| -GetPebAddress(HANDLE ProcessHandle)
 | 
| -{
 | 
| -    _NtQueryInformationProcess NtQueryInformationProcess =
 | 
| -        (_NtQueryInformationProcess)GetProcAddress(
 | 
| -        GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
 | 
| -    PROCESS_BASIC_INFORMATION pbi;
 | 
| -
 | 
| -    NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
 | 
| -    return pbi.PebBaseAddress;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -DWORD*
 | 
| -get_pids(DWORD *numberOfReturnedPIDs) {
 | 
| -    int procArraySz = 1024;
 | 
| -
 | 
| -    /* Win32 SDK says the only way to know if our process array
 | 
| -     * wasn't large enough is to check the returned size and make
 | 
| -     * sure that it doesn't match the size of the array.
 | 
| -     * If it does we allocate a larger array and try again*/
 | 
| -
 | 
| -    /* Stores the actual array */
 | 
| -    DWORD *procArray = NULL;
 | 
| -    DWORD procArrayByteSz;
 | 
| -
 | 
| -    /* Stores the byte size of the returned array from enumprocesses */
 | 
| -    DWORD enumReturnSz = 0;
 | 
| -
 | 
| -    do {
 | 
| -        free(procArray);
 | 
| -        procArrayByteSz = procArraySz * sizeof(DWORD);
 | 
| -        procArray = malloc(procArrayByteSz);
 | 
| -
 | 
| -        if (! EnumProcesses(procArray, procArrayByteSz, &enumReturnSz)) {
 | 
| -            free(procArray);
 | 
| -            PyErr_SetFromWindowsErr(0);
 | 
| -            return NULL;
 | 
| -        }
 | 
| -        else if (enumReturnSz == procArrayByteSz) {
 | 
| -            /* Process list was too large.  Allocate more space*/
 | 
| -            procArraySz += 1024;
 | 
| -        }
 | 
| -
 | 
| -        /* else we have a good list */
 | 
| -
 | 
| -    } while(enumReturnSz == procArraySz * sizeof(DWORD));
 | 
| -
 | 
| -    /* The number of elements is the returned size / size of each element */
 | 
| -    *numberOfReturnedPIDs = enumReturnSz / sizeof(DWORD);
 | 
| -
 | 
| -    return procArray;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -int
 | 
| -pid_is_running(DWORD pid)
 | 
| -{
 | 
| -    HANDLE hProcess;
 | 
| -    DWORD exitCode;
 | 
| -
 | 
| -    // Special case for PID 0 System Idle Process
 | 
| -    if (pid == 0) {
 | 
| -        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) {
 | 
| -            CloseHandle(hProcess);
 | 
| -            return 0;
 | 
| -        }
 | 
| -
 | 
| -        // access denied obviously means there's a process to deny access to...
 | 
| -        if (GetLastError() == ERROR_ACCESS_DENIED) {
 | 
| -            CloseHandle(hProcess);
 | 
| -            return 1;
 | 
| -        }
 | 
| -
 | 
| -        CloseHandle(hProcess);
 | 
| -        PyErr_SetFromWindowsErr(0);
 | 
| -        return -1;
 | 
| -    }
 | 
| -
 | 
| -    if (GetExitCodeProcess(hProcess, &exitCode)) {
 | 
| -        CloseHandle(hProcess);
 | 
| -        return (exitCode == STILL_ACTIVE);
 | 
| -    }
 | 
| -
 | 
| -    // access denied means there's a process there so we'll assume it's running
 | 
| -    if (GetLastError() == ERROR_ACCESS_DENIED) {
 | 
| -        CloseHandle(hProcess);
 | 
| -        return 1;
 | 
| -    }
 | 
| -
 | 
| -    PyErr_SetFromWindowsErr(0);
 | 
| -    CloseHandle(hProcess);
 | 
| -    return -1;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -int
 | 
| -pid_in_proclist(DWORD pid)
 | 
| -{
 | 
| -    DWORD *proclist = NULL;
 | 
| -    DWORD numberOfReturnedPIDs;
 | 
| -    DWORD i;
 | 
| -
 | 
| -    proclist = get_pids(&numberOfReturnedPIDs);
 | 
| -    if (NULL == proclist) {
 | 
| -        return -1;
 | 
| -    }
 | 
| -
 | 
| -    for (i = 0; i < numberOfReturnedPIDs; i++) {
 | 
| -        if (pid == proclist[i]) {
 | 
| -            free(proclist);
 | 
| -            return 1;
 | 
| -        }
 | 
| -    }
 | 
| -
 | 
| -    free(proclist);
 | 
| -    return 0;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Check exit code from a process handle. Return FALSE on an error also
 | 
| -BOOL is_running(HANDLE hProcess)
 | 
| -{
 | 
| -    DWORD dwCode;
 | 
| -
 | 
| -    if (NULL == hProcess) {
 | 
| -        return FALSE;
 | 
| -    }
 | 
| -
 | 
| -    if (GetExitCodeProcess(hProcess, &dwCode)) {
 | 
| -        return (dwCode == STILL_ACTIVE);
 | 
| -    }
 | 
| -    return FALSE;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Return None to represent NoSuchProcess, else return NULL for
 | 
| -// other exception or the name as a Python string
 | 
| -PyObject*
 | 
| -get_name(long pid)
 | 
| -{
 | 
| -    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 | 
| -    PROCESSENTRY32 pe = { 0 };
 | 
| -    pe.dwSize = sizeof(PROCESSENTRY32);
 | 
| -
 | 
| -    if( Process32First(h, &pe)) {
 | 
| -        do {
 | 
| -            if (pe.th32ProcessID == pid) {
 | 
| -                CloseHandle(h);
 | 
| -                return Py_BuildValue("s", pe.szExeFile);
 | 
| -            }
 | 
| -        } while(Process32Next(h, &pe));
 | 
| -
 | 
| -        // the process was never found, set NoSuchProcess exception
 | 
| -        NoSuchProcess();
 | 
| -        CloseHandle(h);
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -    CloseHandle(h);
 | 
| -    return PyErr_SetFromWindowsErr(0);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -/* returns parent pid (as a Python int) for given pid or None on failure */
 | 
| -PyObject*
 | 
| -get_ppid(long pid)
 | 
| -{
 | 
| -    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 | 
| -    PROCESSENTRY32 pe = { 0 };
 | 
| -    pe.dwSize = sizeof(PROCESSENTRY32);
 | 
| -
 | 
| -    if( Process32First(h, &pe)) {
 | 
| -        do {
 | 
| -            if (pe.th32ProcessID == pid) {
 | 
| -                ////printf("PID: %i; PPID: %i\n", pid, pe.th32ParentProcessID);
 | 
| -                CloseHandle(h);
 | 
| -                return Py_BuildValue("I", pe.th32ParentProcessID);
 | 
| -            }
 | 
| -        } while(Process32Next(h, &pe));
 | 
| -
 | 
| -        // the process was never found, set NoSuchProcess exception
 | 
| -        NoSuchProcess();
 | 
| -        CloseHandle(h);
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -    CloseHandle(h);
 | 
| -    return PyErr_SetFromWindowsErr(0);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -
 | 
| -/*
 | 
| - * returns a Python list representing the arguments for the process
 | 
| - * with given pid or NULL on error.
 | 
| - */
 | 
| -PyObject*
 | 
| -get_arg_list(long pid)
 | 
| -{
 | 
| -    int nArgs, i;
 | 
| -    LPWSTR *szArglist;
 | 
| -    HANDLE hProcess;
 | 
| -    PVOID pebAddress;
 | 
| -    PVOID rtlUserProcParamsAddress;
 | 
| -    UNICODE_STRING commandLine;
 | 
| -    WCHAR *commandLineContents;
 | 
| -    PyObject *arg = NULL;
 | 
| -    PyObject *arg_from_wchar = NULL;
 | 
| -    PyObject *argList = NULL;
 | 
| -
 | 
| -    hProcess = handle_from_pid(pid);
 | 
| -    if(hProcess == NULL) {
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -    pebAddress = GetPebAddress(hProcess);
 | 
| -
 | 
| -    /* get the address of ProcessParameters */
 | 
| -#ifdef _WIN64
 | 
| -    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32,
 | 
| -        &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
 | 
| -#else
 | 
| -    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10,
 | 
| -        &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
 | 
| -#endif
 | 
| -    {
 | 
| -        ////printf("Could not read the address of ProcessParameters!\n");
 | 
| -        PyErr_SetFromWindowsErr(0);
 | 
| -        CloseHandle(hProcess);
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -    /* read the CommandLine UNICODE_STRING structure */
 | 
| -#ifdef _WIN64
 | 
| -    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112,
 | 
| -        &commandLine, sizeof(commandLine), NULL))
 | 
| -#else
 | 
| -    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40,
 | 
| -        &commandLine, sizeof(commandLine), NULL))
 | 
| -#endif
 | 
| -    {
 | 
| -        ////printf("Could not read CommandLine!\n");
 | 
| -        CloseHandle(hProcess);
 | 
| -        PyErr_SetFromWindowsErr(0);
 | 
| -        return NULL;
 | 
| -    }
 | 
| -
 | 
| -
 | 
| -    /* allocate memory to hold the command line */
 | 
| -    commandLineContents = (WCHAR *)malloc(commandLine.Length+1);
 | 
| -
 | 
| -    /* read the command line */
 | 
| -    if (!ReadProcessMemory(hProcess, commandLine.Buffer,
 | 
| -        commandLineContents, commandLine.Length, NULL))
 | 
| -    {
 | 
| -        ////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);
 | 
| -
 | 
| -    // null-terminate the string to prevent wcslen from returning incorrect length
 | 
| -    // the length specifier is in characters, but commandLine.Length is in bytes
 | 
| -    commandLineContents[(commandLine.Length/sizeof(WCHAR))] = '\0';
 | 
| -
 | 
| -    // attemempt tp parse the command line using Win32 API, fall back on string
 | 
| -    // cmdline version otherwise
 | 
| -    szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
 | 
| -    if (NULL == szArglist) {
 | 
| -        // failed to parse arglist
 | 
| -        // encode as a UTF8 Python string object from WCHAR string
 | 
| -        arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
 | 
| -                                                commandLine.Length / 2);
 | 
| -        #if PY_MAJOR_VERSION >= 3
 | 
| -            argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
 | 
| -        #else
 | 
| -            argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
 | 
| -        #endif
 | 
| -    }
 | 
| -    else {
 | 
| -        // arglist parsed as array of UNICODE_STRING, so convert each to Python
 | 
| -        // 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]),
 | 
| -            //                  szArglist[i], wcslen(szArglist[i]));
 | 
| -            arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
 | 
| -                                                    wcslen(szArglist[i])
 | 
| -                                                    );
 | 
| -            #if PY_MAJOR_VERSION >= 3
 | 
| -                arg = PyUnicode_FromObject(arg_from_wchar);
 | 
| -            #else
 | 
| -                arg = PyUnicode_AsUTF8String(arg_from_wchar);
 | 
| -            #endif
 | 
| -            Py_XDECREF(arg_from_wchar);
 | 
| -            PyList_Append(argList, arg);
 | 
| -            Py_XDECREF(arg);
 | 
| -        }
 | 
| -    }
 | 
| -
 | 
| -    LocalFree(szArglist);
 | 
| -    free(commandLineContents);
 | 
| -    CloseHandle(hProcess);
 | 
| -    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;
 | 
| -}
 | 
| -
 | 
| -
 | 
| 
 |