Skip to content

Commit

Permalink
Merge pull request #579 from mindw/fix_win32_failures
Browse files Browse the repository at this point in the history
fix most warnings and test failures on win32
  • Loading branch information
giampaolo committed Feb 8, 2015
2 parents 76560ad + 2f7a403 commit b91d2f0
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 61 deletions.
4 changes: 2 additions & 2 deletions psutil/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def sockfam_to_enum(num):
return num
try:
return socket.AddressFamily(num)
except ValueError:
except (ValueError, AttributeError):
return num


Expand All @@ -184,7 +184,7 @@ def socktype_to_enum(num):
return num
try:
return socket.AddressType(num)
except ValueError:
except (ValueError, AttributeError):
return num


Expand Down
11 changes: 6 additions & 5 deletions psutil/_psutil_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) {
if (NULL == hProcess) {
return NULL;
}
if (GetProcessImageFileNameW(hProcess, &exe, MAX_PATH) == 0) {
if (GetProcessImageFileNameW(hProcess, exe, MAX_PATH) == 0) {
CloseHandle(hProcess);
PyErr_SetFromWindowsErr(0);
return NULL;
Expand Down Expand Up @@ -601,7 +601,9 @@ psutil_proc_memory_info(PyObject *self, PyObject *args)
return NULL;
}

if (! GetProcessMemoryInfo(hProcess, &cnt, sizeof(cnt)) ) {
if (! GetProcessMemoryInfo(hProcess, (PPROCESS_MEMORY_COUNTERS)&cnt,
sizeof(cnt)) )
{
CloseHandle(hProcess);
return PyErr_SetFromWindowsErr(0);
}
Expand Down Expand Up @@ -2124,8 +2126,8 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args)
{
DWORD pid;
HANDLE hProcess;
PDWORD_PTR proc_mask;
PDWORD_PTR system_mask;
DWORD_PTR proc_mask;
DWORD_PTR system_mask;

if (! PyArg_ParseTuple(args, "l", &pid)) {
return NULL;
Expand Down Expand Up @@ -2260,7 +2262,6 @@ static PyObject *
psutil_net_io_counters(PyObject *self, PyObject *args)
{
int attempts = 0;
int i;
int outBufLen = 15000;
char ifname[MAX_PATH];
DWORD dwRetVal = 0;
Expand Down
5 changes: 5 additions & 0 deletions psutil/arch/windows/ntextapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* found in the LICENSE file.
*/

#if !defined(__NTEXTAPI_H__)
#define __NTEXTAPI_H__

typedef enum _KTHREAD_STATE {
Initialized,
Ready,
Expand Down Expand Up @@ -285,3 +288,5 @@ typedef enum _PROCESSINFOCLASS {
ProcessImageInformation,
MaxProcessInfoClass
} PROCESSINFOCLASS;

#endif // __NTEXTAPI_H__
128 changes: 87 additions & 41 deletions psutil/arch/windows/process_handles.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,26 @@
#endif

#include <Python.h>
#include <windows.h>
#include <stdio.h>
#include <windows.h>
#include <strsafe.h>
#include "process_handles.h"

#ifndef NT_SUCCESS
#define NT_SUCCESS(x) ((x) >= 0)
#endif

#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004

#define SystemHandleInformation 16
#include <winternl.h>
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2

#define HANDLE_TYPE_FILE 28

typedef LONG NTSTATUS;

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef LONG NTSTATUS;

typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)(
ULONG SystemInformationClass,
Expand All @@ -58,19 +56,29 @@ typedef NTSTATUS (NTAPI *_NtQueryObject)(
PULONG ReturnLength
);

typedef struct _SYSTEM_HANDLE {
ULONG ProcessId;
BYTE ObjectTypeNumber;
BYTE Flags;
USHORT Handle;

// Undocumented FILE_INFORMATION_CLASS: FileNameInformation
const SYSTEM_INFORMATION_CLASS SystemExtendedHandleInformation = (SYSTEM_INFORMATION_CLASS)64;

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
{
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
HANDLE UniqueProcessId;
HANDLE HandleValue;
ULONG GrantedAccess;
USHORT CreatorBackTraceIndex;
USHORT ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;

typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG_PTR NumberOfHandles;
ULONG_PTR Reserved;
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;

typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG HandleCount;
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef enum _POOL_TYPE {
NonPagedPool,
Expand Down Expand Up @@ -114,28 +122,62 @@ GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
}

void PrintError(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code

LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

// Display the error message
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);

wprintf(lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(GetLastError);
}

PyObject *
psutil_get_open_files(long pid, HANDLE processHandle)
{
_NtQuerySystemInformation NtQuerySystemInformation =
GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");

_NtQueryObject NtQueryObject =
GetLibraryProcAddress("ntdll.dll", "NtQueryObject");

NTSTATUS status;
PSYSTEM_HANDLE_INFORMATION handleInfo;
PSYSTEM_HANDLE_INFORMATION_EX handleInfo;
ULONG handleInfoSize = 0x10000;
ULONG i;
ULONG fileNameLength;
PyObject *filesList = Py_BuildValue("[]");
PyObject *arg = NULL;
PyObject *fileFromWchar = NULL;
DWORD nReturn = 0;

if (filesList == NULL)
return NULL;

handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
handleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)HeapAlloc(GetProcessHeap(), 0,
handleInfoSize);

if (handleInfo == NULL) {
Py_DECREF(filesList);
PyErr_NoMemory();
Expand All @@ -145,25 +187,27 @@ psutil_get_open_files(long pid, HANDLE processHandle)
// NtQuerySystemInformation won't give us the correct buffer size,
// so we guess by doubling the buffer size.
while ((status = NtQuerySystemInformation(
SystemHandleInformation,
SystemExtendedHandleInformation,
handleInfo,
handleInfoSize,
NULL
&nReturn
)) == STATUS_INFO_LENGTH_MISMATCH)
{
handleInfo = (PSYSTEM_HANDLE_INFORMATION) \
realloc(handleInfo, handleInfoSize *= 2);
handleInfoSize *=2;
HeapFree(GetProcessHeap(), 0, handleInfo);
handleInfo = (PSYSTEM_HANDLE_INFORMATION_EX)HeapAlloc(
GetProcessHeap(), 0, handleInfoSize);
}

// NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH
if (!NT_SUCCESS(status)) {
Py_DECREF(filesList);
free(handleInfo);
HeapFree(GetProcessHeap(), 0, handleInfo);
return NULL;
}

for (i = 0; i < handleInfo->HandleCount; i++) {
SYSTEM_HANDLE handle = handleInfo->Handles[i];
for (i = 0; i < handleInfo->NumberOfHandles; i++) {
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handle = &handleInfo->Handles[i];
HANDLE dupHandle = NULL;
HANDLE mapHandle = NULL;
POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
Expand All @@ -175,31 +219,33 @@ psutil_get_open_files(long pid, HANDLE processHandle)
arg = NULL;

// Check if this handle belongs to the PID the user specified.
if (handle.ProcessId != pid)
if (handle->UniqueProcessId != (HANDLE)pid ||
handle->ObjectTypeIndex != HANDLE_TYPE_FILE)
{
continue;
}

// Skip handles with the following access codes as the next call
// to NtDuplicateObject() or NtQueryObject() might hang forever.
if ((handle.GrantedAccess == 0x0012019f)
|| (handle.GrantedAccess == 0x001a019f)
|| (handle.GrantedAccess == 0x00120189)
|| (handle.GrantedAccess == 0x00100000)) {
if ((handle->GrantedAccess == 0x0012019f)
|| (handle->GrantedAccess == 0x001a019f)
|| (handle->GrantedAccess == 0x00120189)
|| (handle->GrantedAccess == 0x00100000)) {
continue;
}

if (!DuplicateHandle(processHandle,
handle.Handle,
if (!DuplicateHandle(processHandle,
handle->HandleValue,
GetCurrentProcess(),
&dupHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS))
{
//printf("[%#x] Error: %d \n", handle.Handle, GetLastError());
//printf("[%#x] Error: %d \n", handle->HandleValue, GetLastError());
continue;
}


mapHandle = CreateFileMapping(dupHandle,
NULL,
PAGE_READONLY,
Expand Down Expand Up @@ -254,7 +300,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
/*
printf(
"[%#x] %.*S: (could not get name)\n",
handle.Handle,
handle->HandleValue,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
Expand Down Expand Up @@ -300,7 +346,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
/*
printf(
"[%#x] %.*S: %.*S\n",
handle.Handle,
handle->Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer,
objectName.Length / 2,
Expand All @@ -314,7 +360,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
/*
printf(
"[%#x] %.*S: (unnamed)\n",
handle.Handle,
handle->Handle,
objectTypeInfo->Name.Length / 2,
objectTypeInfo->Name.Buffer
);
Expand All @@ -325,7 +371,7 @@ psutil_get_open_files(long pid, HANDLE processHandle)
free(objectNameInfo);
CloseHandle(dupHandle);
}
free(handleInfo);
HeapFree(GetProcessHeap(), 0, handleInfo);
CloseHandle(processHandle);
return filesList;

Expand Down
9 changes: 9 additions & 0 deletions psutil/arch/windows/process_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
* found in the LICENSE file.
*/

#if !defined(__PROCESS_INFO_H)
#define __PROCESS_INFO_H

#include <Python.h>
#include <windows.h>
#include "security.h"
#include "ntextapi.h"

DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs);
HANDLE psutil_handle_from_pid(DWORD pid);
Expand All @@ -15,3 +20,7 @@ int psutil_pid_in_proclist(DWORD pid);
int psutil_pid_is_running(DWORD pid);
PVOID psutil_get_peb_address(HANDLE ProcessHandle);
PyObject* psutil_get_arg_list(long pid);
int psutil_get_proc_info(DWORD pid, PSYSTEM_PROCESS_INFORMATION *retProcess,
PVOID *retBuffer);

#endif
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def get_winver():
# http://www.mingw.org/wiki/Use_more_recent_defined_functions
('_WIN32_WINNT', get_winver()),
('_AVAIL_WINVER_', get_winver()),
('_CRT_SECURE_NO_WARNINGS', None),
# see: https://github.com/giampaolo/psutil/issues/348
('PSAPI_VERSION', 1),
],
Expand Down
Loading

0 comments on commit b91d2f0

Please sign in to comment.