| Index: third_party/psutil/psutil/_psutil_mswindows.c
|
| diff --git a/third_party/psutil/psutil/_psutil_mswindows.c b/third_party/psutil/psutil/_psutil_mswindows.c
|
| index 3964179ab97273ed3d401a1fab9bab55760a4767..484261866f929d69945b4a892ce10d123a5e054a 100644
|
| --- a/third_party/psutil/psutil/_psutil_mswindows.c
|
| +++ b/third_party/psutil/psutil/_psutil_mswindows.c
|
| @@ -1,5 +1,5 @@
|
| /*
|
| - * $Id: _psutil_mswindows.c 1142 2011-10-05 18:45:49Z g.rodola $
|
| + * $Id: _psutil_mswindows.c 1202 2011-10-24 19:00:50Z 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
|
| @@ -8,15 +8,23 @@
|
| * Windows platform-specific module methods for _psutil_mswindows
|
| */
|
|
|
| +// Fixes clash between winsock2.h and windows.h
|
| +#define WIN32_LEAN_AND_MEAN
|
| +
|
| #include <Python.h>
|
| #include <windows.h>
|
| #include <Psapi.h>
|
| #include <time.h>
|
| #include <lm.h>
|
| +#include <WinIoCtl.h>
|
| #include <tchar.h>
|
| #include <tlhelp32.h>
|
| +#include <winsock2.h>
|
| #include <iphlpapi.h>
|
|
|
| +// Link with Iphlpapi.lib
|
| +#pragma comment(lib, "IPHLPAPI.lib")
|
| +
|
| #include "_psutil_mswindows.h"
|
| #include "_psutil_common.h"
|
| #include "arch/mswindows/security.h"
|
| @@ -473,9 +481,15 @@ get_memory_info(PyObject* self, PyObject* args)
|
| CloseHandle(hProcess);
|
| return PyErr_SetFromWindowsErr(0);
|
| }
|
| -
|
| - CloseHandle(hProcess);
|
| +
|
| +// py 2.4
|
| +#if (PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION <= 4)
|
| + return Py_BuildValue("(II)", (unsigned int)counters.WorkingSetSize,
|
| + (unsigned int)counters.PagefileUsage);
|
| +#else
|
| +// py >= 2.5
|
| return Py_BuildValue("(nn)", counters.WorkingSetSize, counters.PagefileUsage);
|
| +#endif
|
| }
|
|
|
|
|
| @@ -1215,6 +1229,8 @@ get_process_connections(PyObject* self, PyObject* args)
|
| unsigned long pid;
|
| PyObject* connectionsList;
|
| PyObject* connectionTuple;
|
| + PyObject *af_filter = NULL;
|
| + PyObject *type_filter = NULL;
|
| typedef PSTR (NTAPI *_RtlIpv4AddressToStringA)(struct in_addr *,
|
| PSTR /* __out_ecount(16) */);
|
| _RtlIpv4AddressToStringA rtlIpv4AddressToStringA;
|
| @@ -1239,7 +1255,12 @@ get_process_connections(PyObject* self, PyObject* args)
|
| CHAR addressBufferRemote[65];
|
| PyObject* addressTupleRemote;
|
|
|
| - if (!PyArg_ParseTuple(args, "l", &pid)) {
|
| + if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
|
| + return NULL;
|
| + }
|
| +
|
| + if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
|
| + PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
|
| return NULL;
|
| }
|
|
|
| @@ -1276,229 +1297,247 @@ get_process_connections(PyObject* self, PyObject* args)
|
|
|
| /* TCP IPv4 */
|
|
|
| - tableSize = 0;
|
| - getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET,
|
| - TCP_TABLE_OWNER_PID_ALL, 0);
|
| -
|
| - table = malloc(tableSize);
|
| -
|
| - if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
|
| - TCP_TABLE_OWNER_PID_ALL, 0) == 0)
|
| + if ((PySequence_Contains(af_filter, PyLong_FromLong((long)AF_INET)) == 1) &&
|
| + (PySequence_Contains(type_filter, PyLong_FromLong((long)SOCK_STREAM)) == 1))
|
| {
|
| - tcp4Table = table;
|
| + tableSize = 0;
|
| + getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET,
|
| + TCP_TABLE_OWNER_PID_ALL, 0);
|
| +
|
| + table = malloc(tableSize);
|
|
|
| - for (i = 0; i < tcp4Table->dwNumEntries; i++)
|
| + if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
|
| + TCP_TABLE_OWNER_PID_ALL, 0) == 0)
|
| {
|
| - if (tcp4Table->table[i].dwOwningPid != pid) {
|
| - continue;
|
| - }
|
| + tcp4Table = table;
|
|
|
| - if (tcp4Table->table[i].dwLocalAddr != 0 ||
|
| - tcp4Table->table[i].dwLocalPort != 0)
|
| + for (i = 0; i < tcp4Table->dwNumEntries; i++)
|
| {
|
| - struct in_addr addr;
|
| + if (tcp4Table->table[i].dwOwningPid != pid) {
|
| + continue;
|
| + }
|
|
|
| - addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr;
|
| - rtlIpv4AddressToStringA(&addr, addressBufferLocal);
|
| - addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| - BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort));
|
| - }
|
| - else
|
| - {
|
| - addressTupleLocal = PyTuple_New(0);
|
| - }
|
| + if (tcp4Table->table[i].dwLocalAddr != 0 ||
|
| + tcp4Table->table[i].dwLocalPort != 0)
|
| + {
|
| + struct in_addr addr;
|
|
|
| - // On Windows <= XP, remote addr is filled even if socket
|
| - // is in LISTEN mode in which case we just ignore it.
|
| - if ((tcp4Table->table[i].dwRemoteAddr != 0 ||
|
| - tcp4Table->table[i].dwRemotePort != 0) &&
|
| - (tcp4Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
|
| - {
|
| - struct in_addr addr;
|
| + addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr;
|
| + rtlIpv4AddressToStringA(&addr, addressBufferLocal);
|
| + addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| + BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort));
|
| + }
|
| + else
|
| + {
|
| + addressTupleLocal = PyTuple_New(0);
|
| + }
|
|
|
| - addr.S_un.S_addr = tcp4Table->table[i].dwRemoteAddr;
|
| - rtlIpv4AddressToStringA(&addr, addressBufferRemote);
|
| - addressTupleRemote = Py_BuildValue("(si)", addressBufferRemote,
|
| - BYTESWAP_USHORT(tcp4Table->table[i].dwRemotePort));
|
| - }
|
| - else
|
| - {
|
| - addressTupleRemote = PyTuple_New(0);
|
| - }
|
| + // On Windows <= XP, remote addr is filled even if socket
|
| + // is in LISTEN mode in which case we just ignore it.
|
| + if ((tcp4Table->table[i].dwRemoteAddr != 0 ||
|
| + tcp4Table->table[i].dwRemotePort != 0) &&
|
| + (tcp4Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
|
| + {
|
| + struct in_addr addr;
|
| +
|
| + addr.S_un.S_addr = tcp4Table->table[i].dwRemoteAddr;
|
| + rtlIpv4AddressToStringA(&addr, addressBufferRemote);
|
| + addressTupleRemote = Py_BuildValue("(si)", addressBufferRemote,
|
| + BYTESWAP_USHORT(tcp4Table->table[i].dwRemotePort));
|
| + }
|
| + else
|
| + {
|
| + addressTupleRemote = PyTuple_New(0);
|
| + }
|
|
|
| - connectionTuple = Py_BuildValue("(iiiNNs)",
|
| - -1,
|
| - AF_INET,
|
| - SOCK_STREAM,
|
| - addressTupleLocal,
|
| - addressTupleRemote,
|
| - state_to_string(tcp4Table->table[i].dwState)
|
| - );
|
| - PyList_Append(connectionsList, connectionTuple);
|
| + connectionTuple = Py_BuildValue("(iiiNNs)",
|
| + -1,
|
| + AF_INET,
|
| + SOCK_STREAM,
|
| + addressTupleLocal,
|
| + addressTupleRemote,
|
| + state_to_string(tcp4Table->table[i].dwState)
|
| + );
|
| + PyList_Append(connectionsList, connectionTuple);
|
| + }
|
| }
|
| - }
|
|
|
| - free(table);
|
| + free(table);
|
| + }
|
|
|
| /* TCP IPv6 */
|
|
|
| - tableSize = 0;
|
| - getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6,
|
| - TCP_TABLE_OWNER_PID_ALL, 0);
|
| -
|
| - table = malloc(tableSize);
|
| -
|
| - if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET6,
|
| - TCP_TABLE_OWNER_PID_ALL, 0) == 0)
|
| + if ((PySequence_Contains(af_filter, PyLong_FromLong((long)AF_INET6)) == 1) &&
|
| + (PySequence_Contains(type_filter, PyLong_FromLong((long)SOCK_STREAM)) == 1))
|
| {
|
| - tcp6Table = table;
|
| + tableSize = 0;
|
| + getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6,
|
| + TCP_TABLE_OWNER_PID_ALL, 0);
|
|
|
| - for (i = 0; i < tcp6Table->dwNumEntries; i++)
|
| + table = malloc(tableSize);
|
| +
|
| + if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET6,
|
| + TCP_TABLE_OWNER_PID_ALL, 0) == 0)
|
| {
|
| - if (tcp6Table->table[i].dwOwningPid != pid) {
|
| - continue;
|
| - }
|
| + tcp6Table = table;
|
|
|
| - if (memcmp(tcp6Table->table[i].ucLocalAddr, null_address, 16) != 0 ||
|
| - tcp6Table->table[i].dwLocalPort != 0)
|
| + for (i = 0; i < tcp6Table->dwNumEntries; i++)
|
| {
|
| - struct in6_addr addr;
|
| + if (tcp6Table->table[i].dwOwningPid != pid) {
|
| + continue;
|
| + }
|
|
|
| - memcpy(&addr, tcp6Table->table[i].ucLocalAddr, 16);
|
| - rtlIpv6AddressToStringA(&addr, addressBufferLocal);
|
| - addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| - BYTESWAP_USHORT(tcp6Table->table[i].dwLocalPort));
|
| - }
|
| - else
|
| - {
|
| - addressTupleLocal = PyTuple_New(0);
|
| - }
|
| + if (memcmp(tcp6Table->table[i].ucLocalAddr, null_address, 16) != 0 ||
|
| + tcp6Table->table[i].dwLocalPort != 0)
|
| + {
|
| + struct in6_addr addr;
|
|
|
| - // On Windows <= XP, remote addr is filled even if socket
|
| - // is in LISTEN mode in which case we just ignore it.
|
| - if ((memcmp(tcp6Table->table[i].ucRemoteAddr, null_address, 16) != 0 ||
|
| - tcp6Table->table[i].dwRemotePort != 0) &&
|
| - (tcp6Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
|
| - {
|
| - struct in6_addr addr;
|
| + memcpy(&addr, tcp6Table->table[i].ucLocalAddr, 16);
|
| + rtlIpv6AddressToStringA(&addr, addressBufferLocal);
|
| + addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| + BYTESWAP_USHORT(tcp6Table->table[i].dwLocalPort));
|
| + }
|
| + else
|
| + {
|
| + addressTupleLocal = PyTuple_New(0);
|
| + }
|
|
|
| - memcpy(&addr, tcp6Table->table[i].ucRemoteAddr, 16);
|
| - rtlIpv6AddressToStringA(&addr, addressBufferRemote);
|
| - addressTupleRemote = Py_BuildValue("(si)", addressBufferRemote,
|
| - BYTESWAP_USHORT(tcp6Table->table[i].dwRemotePort));
|
| - }
|
| - else
|
| - {
|
| - addressTupleRemote = PyTuple_New(0);
|
| - }
|
| + // On Windows <= XP, remote addr is filled even if socket
|
| + // is in LISTEN mode in which case we just ignore it.
|
| + if ((memcmp(tcp6Table->table[i].ucRemoteAddr, null_address, 16) != 0 ||
|
| + tcp6Table->table[i].dwRemotePort != 0) &&
|
| + (tcp6Table->table[i].dwState != MIB_TCP_STATE_LISTEN))
|
| + {
|
| + struct in6_addr addr;
|
|
|
| - connectionTuple = Py_BuildValue("(iiiNNs)",
|
| - -1,
|
| - AF_INET6,
|
| - SOCK_STREAM,
|
| - addressTupleLocal,
|
| - addressTupleRemote,
|
| - state_to_string(tcp6Table->table[i].dwState)
|
| - );
|
| - PyList_Append(connectionsList, connectionTuple);
|
| + memcpy(&addr, tcp6Table->table[i].ucRemoteAddr, 16);
|
| + rtlIpv6AddressToStringA(&addr, addressBufferRemote);
|
| + addressTupleRemote = Py_BuildValue("(si)", addressBufferRemote,
|
| + BYTESWAP_USHORT(tcp6Table->table[i].dwRemotePort));
|
| + }
|
| + else
|
| + {
|
| + addressTupleRemote = PyTuple_New(0);
|
| + }
|
| +
|
| + connectionTuple = Py_BuildValue("(iiiNNs)",
|
| + -1,
|
| + AF_INET6,
|
| + SOCK_STREAM,
|
| + addressTupleLocal,
|
| + addressTupleRemote,
|
| + state_to_string(tcp6Table->table[i].dwState)
|
| + );
|
| + PyList_Append(connectionsList, connectionTuple);
|
| + }
|
| }
|
| - }
|
|
|
| - free(table);
|
| + free(table);
|
| + }
|
|
|
| /* UDP IPv4 */
|
|
|
| - tableSize = 0;
|
| - getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET,
|
| - UDP_TABLE_OWNER_PID, 0);
|
| -
|
| - table = malloc(tableSize);
|
| -
|
| - if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
|
| - UDP_TABLE_OWNER_PID, 0) == 0)
|
| + if ((PySequence_Contains(af_filter, PyLong_FromLong((long)AF_INET)) == 1) &&
|
| + (PySequence_Contains(type_filter, PyLong_FromLong((long)SOCK_DGRAM)) == 1))
|
| {
|
| - udp4Table = table;
|
| + tableSize = 0;
|
| + getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET,
|
| + UDP_TABLE_OWNER_PID, 0);
|
|
|
| - for (i = 0; i < udp4Table->dwNumEntries; i++)
|
| + table = malloc(tableSize);
|
| +
|
| + if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
|
| + UDP_TABLE_OWNER_PID, 0) == 0)
|
| {
|
| - if (udp4Table->table[i].dwOwningPid != pid) {
|
| - continue;
|
| - }
|
| + udp4Table = table;
|
|
|
| - if (udp4Table->table[i].dwLocalAddr != 0 ||
|
| - udp4Table->table[i].dwLocalPort != 0)
|
| + for (i = 0; i < udp4Table->dwNumEntries; i++)
|
| {
|
| - struct in_addr addr;
|
| + if (udp4Table->table[i].dwOwningPid != pid) {
|
| + continue;
|
| + }
|
|
|
| - addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr;
|
| - rtlIpv4AddressToStringA(&addr, addressBufferLocal);
|
| - addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| - BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort));
|
| - }
|
| - else
|
| - {
|
| - addressTupleLocal = PyTuple_New(0);
|
| - }
|
| + if (udp4Table->table[i].dwLocalAddr != 0 ||
|
| + udp4Table->table[i].dwLocalPort != 0)
|
| + {
|
| + struct in_addr addr;
|
| +
|
| + addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr;
|
| + rtlIpv4AddressToStringA(&addr, addressBufferLocal);
|
| + addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| + BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort));
|
| + }
|
| + else
|
| + {
|
| + addressTupleLocal = PyTuple_New(0);
|
| + }
|
|
|
| - connectionTuple = Py_BuildValue("(iiiNNs)",
|
| - -1,
|
| - AF_INET,
|
| - SOCK_DGRAM,
|
| - addressTupleLocal,
|
| - PyTuple_New(0),
|
| - ""
|
| - );
|
| - PyList_Append(connectionsList, connectionTuple);
|
| + connectionTuple = Py_BuildValue("(iiiNNs)",
|
| + -1,
|
| + AF_INET,
|
| + SOCK_DGRAM,
|
| + addressTupleLocal,
|
| + PyTuple_New(0),
|
| + ""
|
| + );
|
| + PyList_Append(connectionsList, connectionTuple);
|
| + }
|
| }
|
| - }
|
|
|
| - free(table);
|
| + free(table);
|
| + }
|
|
|
| /* UDP IPv6 */
|
|
|
| - tableSize = 0;
|
| - getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET6, UDP_TABLE_OWNER_PID, 0);
|
| -
|
| - table = malloc(tableSize);
|
| -
|
| - if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET6, UDP_TABLE_OWNER_PID, 0) == 0)
|
| + if ((PySequence_Contains(af_filter, PyLong_FromLong((long)AF_INET6)) == 1) &&
|
| + (PySequence_Contains(type_filter, PyLong_FromLong((long)SOCK_DGRAM)) == 1))
|
| {
|
| - udp6Table = table;
|
| + tableSize = 0;
|
| + getExtendedUdpTable(NULL, &tableSize, FALSE,
|
| + AF_INET6, UDP_TABLE_OWNER_PID, 0);
|
| +
|
| + table = malloc(tableSize);
|
|
|
| - for (i = 0; i < udp6Table->dwNumEntries; i++)
|
| + if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET6,
|
| + UDP_TABLE_OWNER_PID, 0) == 0)
|
| {
|
| - if (udp6Table->table[i].dwOwningPid != pid) {
|
| - continue;
|
| - }
|
| + udp6Table = table;
|
|
|
| - if (memcmp(udp6Table->table[i].ucLocalAddr, null_address, 16) != 0 ||
|
| - udp6Table->table[i].dwLocalPort != 0)
|
| + for (i = 0; i < udp6Table->dwNumEntries; i++)
|
| {
|
| - struct in6_addr addr;
|
| + if (udp6Table->table[i].dwOwningPid != pid) {
|
| + continue;
|
| + }
|
|
|
| - memcpy(&addr, udp6Table->table[i].ucLocalAddr, 16);
|
| - rtlIpv6AddressToStringA(&addr, addressBufferLocal);
|
| - addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| - BYTESWAP_USHORT(udp6Table->table[i].dwLocalPort));
|
| - }
|
| - else
|
| - {
|
| - addressTupleLocal = PyTuple_New(0);
|
| - }
|
| + if (memcmp(udp6Table->table[i].ucLocalAddr, null_address, 16) != 0 ||
|
| + udp6Table->table[i].dwLocalPort != 0)
|
| + {
|
| + struct in6_addr addr;
|
|
|
| - connectionTuple = Py_BuildValue("(iiiNNs)",
|
| - -1,
|
| - AF_INET6,
|
| - SOCK_DGRAM,
|
| - addressTupleLocal,
|
| - PyTuple_New(0),
|
| - ""
|
| - );
|
| - PyList_Append(connectionsList, connectionTuple);
|
| + memcpy(&addr, udp6Table->table[i].ucLocalAddr, 16);
|
| + rtlIpv6AddressToStringA(&addr, addressBufferLocal);
|
| + addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
|
| + BYTESWAP_USHORT(udp6Table->table[i].dwLocalPort));
|
| + }
|
| + else
|
| + {
|
| + addressTupleLocal = PyTuple_New(0);
|
| + }
|
| +
|
| + connectionTuple = Py_BuildValue("(iiiNNs)",
|
| + -1,
|
| + AF_INET6,
|
| + SOCK_DGRAM,
|
| + addressTupleLocal,
|
| + PyTuple_New(0),
|
| + ""
|
| + );
|
| + PyList_Append(connectionsList, connectionTuple);
|
| + }
|
| }
|
| - }
|
|
|
| - free(table);
|
| + free(table);
|
| + }
|
|
|
| return connectionsList;
|
| }
|
| @@ -1658,7 +1697,155 @@ get_disk_usage(PyObject* self, PyObject* args)
|
|
|
|
|
| /*
|
| - * Return disk partitions as a list of namedtuples.
|
| + * Return a Python list of named tuples with overall network I/O information
|
| + */
|
| +static PyObject*
|
| +get_network_io_counters(PyObject* self, PyObject* args)
|
| +{
|
| + PyObject* py_retdict = PyDict_New();
|
| + PyObject* py_nic_info = NULL;
|
| + PyObject* py_pre_nic_name = NULL;
|
| + PyObject* py_nic_name = NULL;
|
| +
|
| + int attempts = 0;
|
| + int outBufLen = 15000;
|
| + DWORD dwRetVal = 0;
|
| + MIB_IFROW *pIfRow;
|
| + ULONG flags = 0;
|
| + ULONG family = AF_UNSPEC;
|
| + PIP_ADAPTER_ADDRESSES pAddresses = NULL;
|
| + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
|
| +
|
| + do {
|
| + pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
|
| + if (pAddresses == NULL) {
|
| + Py_DECREF(py_retdict);
|
| + PyErr_SetString(PyExc_RuntimeError,
|
| + "memory allocation failed for IP_ADAPTER_ADDRESSES struct.");
|
| + return NULL;
|
| + }
|
| +
|
| + dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses,
|
| + &outBufLen);
|
| + if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
|
| + free(pAddresses);
|
| + pAddresses = NULL;
|
| + }
|
| + else {
|
| + break;
|
| + }
|
| +
|
| + attempts++;
|
| + } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (attempts < 3));
|
| +
|
| + if (dwRetVal != NO_ERROR) {
|
| + Py_DECREF(py_retdict);
|
| + PyErr_SetString(PyExc_RuntimeError, "GetAdaptersAddresses() failed.");
|
| + return NULL;
|
| + }
|
| +
|
| + pCurrAddresses = pAddresses;
|
| + while (pCurrAddresses) {
|
| + pIfRow = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
|
| +
|
| + if (pIfRow == NULL) {
|
| + Py_DECREF(py_retdict);
|
| + Py_XDECREF(py_pre_nic_name);
|
| + Py_XDECREF(py_nic_name);
|
| + Py_XDECREF(py_nic_info);
|
| + PyErr_SetString(PyExc_RuntimeError,
|
| + "memory allocation failed for MIB_IFROW struct.");
|
| + return NULL;
|
| + }
|
| +
|
| + pIfRow->dwIndex = pCurrAddresses->IfIndex;
|
| + dwRetVal = GetIfEntry(pIfRow);
|
| + if (dwRetVal != NO_ERROR) {
|
| + Py_DECREF(py_retdict);
|
| + Py_XDECREF(py_pre_nic_name);
|
| + Py_XDECREF(py_nic_name);
|
| + Py_XDECREF(py_nic_info);
|
| + PyErr_SetString(PyExc_RuntimeError,
|
| + "GetIfEntry() failed.");
|
| + return NULL;
|
| + }
|
| +
|
| + py_nic_info = Py_BuildValue("(IIII)",
|
| + pIfRow->dwOutOctets,
|
| + pIfRow->dwInOctets,
|
| + pIfRow->dwOutUcastPkts,
|
| + pIfRow->dwInUcastPkts);
|
| +
|
| + py_pre_nic_name = PyUnicode_FromWideChar(
|
| + pCurrAddresses->FriendlyName,
|
| + wcslen(pCurrAddresses->FriendlyName));
|
| + py_nic_name = PyUnicode_FromObject(py_pre_nic_name);
|
| + PyDict_SetItem(py_retdict, py_nic_name, py_nic_info);
|
| + Py_XDECREF(py_pre_nic_name);
|
| + Py_XDECREF(py_nic_name);
|
| + Py_XDECREF(py_nic_info);
|
| +
|
| + free(pIfRow);
|
| + pCurrAddresses = pCurrAddresses->Next;
|
| + }
|
| +
|
| + free(pAddresses);
|
| +
|
| + return py_retdict;
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python dict of tuples for disk I/O information
|
| + */
|
| +static PyObject*
|
| +get_disk_io_counters(PyObject* self, PyObject* args)
|
| +{
|
| + PyObject* py_retdict = PyDict_New();
|
| + PyObject* py_disk_info;
|
| +
|
| + DISK_PERFORMANCE diskPerformance;
|
| + DWORD dwSize;
|
| + HANDLE hDevice = NULL;
|
| + char szDevice[MAX_PATH];
|
| + char szDeviceDisplay[MAX_PATH];
|
| + int devNum;
|
| +
|
| + for (devNum = 0;; devNum++) {
|
| + sprintf (szDevice, "\\\\.\\PhysicalDrive%d", devNum);
|
| + hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
| + NULL, OPEN_EXISTING, 0, NULL);
|
| +
|
| + if (hDevice == INVALID_HANDLE_VALUE)
|
| + break;
|
| +
|
| + if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
|
| + &diskPerformance, sizeof (DISK_PERFORMANCE), &dwSize, NULL)) {
|
| + sprintf (szDeviceDisplay, "PhysicalDrive%d", devNum);
|
| + py_disk_info = Py_BuildValue("(IILLLL)",
|
| + diskPerformance.ReadCount,
|
| + diskPerformance.WriteCount,
|
| + diskPerformance.BytesRead,
|
| + diskPerformance.BytesWritten,
|
| + (diskPerformance.ReadTime.QuadPart
|
| + * 10) / 1000,
|
| + (diskPerformance.WriteTime.QuadPart
|
| + * 10) / 1000);
|
| + PyDict_SetItemString(py_retdict,
|
| + szDeviceDisplay,
|
| + py_disk_info);
|
| + Py_XDECREF(py_disk_info);
|
| + }
|
| +
|
| + CloseHandle(hDevice);
|
| + }
|
| +
|
| + return py_retdict;
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return disk partitions as a list of strings.
|
| */
|
| static PyObject*
|
| win32_GetLogicalDriveStrings(PyObject* self, PyObject* args)
|
| @@ -1667,6 +1854,7 @@ win32_GetLogicalDriveStrings(PyObject* self, PyObject* args)
|
| char drive_strings[255];
|
| char* drive_letter = drive_strings;
|
| PyObject* py_retlist = PyList_New(0);
|
| + PyObject* py_string = NULL;
|
|
|
| Py_BEGIN_ALLOW_THREADS
|
| num_bytes = GetLogicalDriveStrings(254, drive_letter);
|
| @@ -1677,8 +1865,10 @@ win32_GetLogicalDriveStrings(PyObject* self, PyObject* args)
|
| }
|
|
|
| while (*drive_letter != 0) {
|
| - PyList_Append(py_retlist, Py_BuildValue("s", drive_letter));
|
| - drive_letter = strchr(drive_letter, 0) +1;
|
| + py_string = Py_BuildValue("s", drive_letter);
|
| + PyList_Append(py_retlist, py_string);
|
| + Py_DECREF(py_string);
|
| + drive_letter = strchr(drive_letter, 0) + 1;
|
| }
|
|
|
| return py_retlist;
|
| @@ -1795,6 +1985,10 @@ PsutilMethods[] =
|
| "Return system per-cpu times as a list of tuples"},
|
| {"get_disk_usage", get_disk_usage, METH_VARARGS,
|
| "Return path's disk total and free as a Python tuple."},
|
| + {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
|
| + "Return dict of tuples of networks I/O information."},
|
| + {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS,
|
| + "Return dict of tuples of disks I/O information."},
|
|
|
| // --- windows API bindings
|
| {"win32_GetLogicalDriveStrings", win32_GetLogicalDriveStrings, METH_VARARGS,
|
| @@ -1892,6 +2086,3 @@ struct module_state {
|
| return module;
|
| #endif
|
| }
|
| -
|
| -
|
| -
|
|
|