| 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; | 
| +} | 
| + | 
| + | 
|  |