Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix most warnings and test failures on win32 #579

Merged
merged 5 commits into from
Feb 8, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is wise. If I comment this line the compiler says:

psutil/arch/windows/security.c(89) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider sing strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Why not use strcpy_s instead?

# see: https://github.com/giampaolo/psutil/issues/348
('PSAPI_VERSION', 1),
],
Expand Down
Loading