Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: third_party/psutil/psutil/_psutil_mswindows.c

Issue 8159001: Update third_party/psutil and fix the licence issue with it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove the suppression and unnecessary files. Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/psutil/psutil/_psutil_mswindows.h ('k') | third_party/psutil/psutil/_psutil_osx.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * $Id: _psutil_mswindows.c 796 2010-11-12 20:31:28Z g.rodola $ 2 * $Id: _psutil_mswindows.c 1142 2011-10-05 18:45:49Z g.rodola $
3 *
4 * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
3 * 7 *
4 * Windows platform-specific module methods for _psutil_mswindows 8 * Windows platform-specific module methods for _psutil_mswindows
5 */ 9 */
6 10
7 #include <Python.h> 11 #include <Python.h>
8 #include <windows.h> 12 #include <windows.h>
9 #include <Psapi.h> 13 #include <Psapi.h>
10 #include <time.h> 14 #include <time.h>
11 #include <lm.h> 15 #include <lm.h>
12 #include <tchar.h> 16 #include <tchar.h>
13 #include <tlhelp32.h> 17 #include <tlhelp32.h>
14 #include <iphlpapi.h> 18 #include <iphlpapi.h>
15 19
16 #include "_psutil_mswindows.h" 20 #include "_psutil_mswindows.h"
21 #include "_psutil_common.h"
17 #include "arch/mswindows/security.h" 22 #include "arch/mswindows/security.h"
18 #include "arch/mswindows/process_info.h" 23 #include "arch/mswindows/process_info.h"
19 #include "arch/mswindows/process_handles.h" 24 #include "arch/mswindows/process_handles.h"
25 #include "arch/mswindows/ntextapi.h"
20 26
21 27
22 // ------------------------ Python init ---------------------------
23
24 static PyMethodDef
25 PsutilMethods[] =
26 {
27 // --- per-process functions
28
29 {"get_process_name", get_process_name, METH_VARARGS,
30 "Return process name"},
31 {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
32 "Return process cmdline as a list of cmdline arguments"},
33 {"get_process_ppid", get_process_ppid, METH_VARARGS,
34 "Return process ppid as an integer"},
35 {"kill_process", kill_process, METH_VARARGS,
36 "Kill the process identified by the given PID"},
37 {"get_process_cpu_times", get_process_cpu_times, METH_VARARGS,
38 "Return tuple of user/kern time for the given PID"},
39 {"get_process_create_time", get_process_create_time, METH_VARARGS,
40 "Return a float indicating the process create time expressed in "
41 "seconds since the epoch"},
42 {"get_memory_info", get_memory_info, METH_VARARGS,
43 "Return a tuple of RSS/VMS memory information"},
44 {"get_process_cwd", get_process_cwd, METH_VARARGS,
45 "Return process current working directory"},
46 {"suspend_process", suspend_process, METH_VARARGS,
47 "Suspend a process"},
48 {"resume_process", resume_process, METH_VARARGS,
49 "Resume a process"},
50 {"get_process_open_files", get_process_open_files, METH_VARARGS,
51 "Return files opened by process"},
52 {"_QueryDosDevice", _QueryDosDevice, METH_VARARGS,
53 "QueryDosDevice binding"},
54 {"get_process_username", get_process_username, METH_VARARGS,
55 "Return the username of a process"},
56 {"get_process_connections", get_process_connections, METH_VARARGS,
57 "Return the network connections of a process"},
58 {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
59 "Return the network connections of a process"},
60
61 // --- system-related functions
62
63 {"get_pid_list", get_pid_list, METH_VARARGS,
64 "Returns a list of PIDs currently running on the system"},
65 {"pid_exists", pid_exists, METH_VARARGS,
66 "Determine if the process exists in the current process list."},
67 {"get_num_cpus", get_num_cpus, METH_VARARGS,
68 "Returns the number of CPUs on the system"},
69 {"get_system_uptime", get_system_uptime, METH_VARARGS,
70 "Return system uptime"},
71 {"get_total_phymem", get_total_phymem, METH_VARARGS,
72 "Return the total amount of physical memory, in bytes"},
73 {"get_total_virtmem", get_total_virtmem, METH_VARARGS,
74 "Return the total amount of virtual memory, in bytes"},
75 {"get_avail_phymem", get_avail_phymem, METH_VARARGS,
76 "Return the amount of available physical memory, in bytes"},
77 {"get_avail_virtmem", get_avail_virtmem, METH_VARARGS,
78 "Return the amount of available virtual memory, in bytes"},
79 {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
80 "Return system cpu times as a tuple (user, system, idle)"},
81
82 {NULL, NULL, 0, NULL}
83 };
84
85
86 struct module_state {
87 PyObject *error;
88 };
89
90 #if PY_MAJOR_VERSION >= 3
91 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
92 #else
93 #define GETSTATE(m) (&_state)
94 static struct module_state _state;
95 #endif
96
97 #if PY_MAJOR_VERSION >= 3
98
99 static int psutil_mswindows_traverse(PyObject *m, visitproc visit, void *arg ) {
100 Py_VISIT(GETSTATE(m)->error);
101 return 0;
102 }
103
104 static int psutil_mswindows_clear(PyObject *m) {
105 Py_CLEAR(GETSTATE(m)->error);
106 return 0;
107 }
108
109 static struct PyModuleDef moduledef = {
110 PyModuleDef_HEAD_INIT,
111 "psutil_mswindows",
112 NULL,
113 sizeof(struct module_state),
114 PsutilMethods,
115 NULL,
116 psutil_mswindows_traverse,
117 psutil_mswindows_clear,
118 NULL
119 };
120
121 #define INITERROR return NULL
122
123 PyObject* PyInit__psutil_mswindows(void)
124
125 #else
126 #define INITERROR return
127 void init_psutil_mswindows(void)
128 #endif
129 {
130 struct module_state *st = NULL;
131 #if PY_MAJOR_VERSION >= 3
132 PyObject *module = PyModule_Create(&moduledef);
133 #else
134 PyObject *module = Py_InitModule("_psutil_mswindows", PsutilMethods);
135 #endif
136
137 if (module == NULL) {
138 INITERROR;
139 }
140
141 st = GETSTATE(module);
142 st->error = PyErr_NewException("_psutil_mswindow.Error", NULL, NULL);
143 if (st->error == NULL) {
144 Py_DECREF(module);
145 INITERROR;
146 }
147
148 SetSeDebug();
149
150 #if PY_MAJOR_VERSION >= 3
151 return module;
152 #endif
153 }
154
155
156 // ------------------------ Public functions ---------------------------
157
158 /* 28 /*
159 * Return a Python float representing the system uptime expressed in seconds 29 * Return a Python float representing the system uptime expressed in seconds
160 * since the epoch. 30 * since the epoch.
161 */ 31 */
162 static PyObject* 32 static PyObject*
163 get_system_uptime(PyObject* self, PyObject* args) 33 get_system_uptime(PyObject* self, PyObject* args)
164 { 34 {
165 double uptime; 35 double uptime;
166 time_t pt; 36 time_t pt;
167 FILETIME fileTime; 37 FILETIME fileTime;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 116
247 /* 117 /*
248 * Kill a process given its PID. 118 * Kill a process given its PID.
249 */ 119 */
250 static PyObject* 120 static PyObject*
251 kill_process(PyObject* self, PyObject* args) 121 kill_process(PyObject* self, PyObject* args)
252 { 122 {
253 HANDLE hProcess; 123 HANDLE hProcess;
254 long pid; 124 long pid;
255 125
256 if (! PyArg_ParseTuple(args, "l", &pid)) 126 if (! PyArg_ParseTuple(args, "l", &pid)) {
257 return NULL; 127 return NULL;
258 if (pid == 0) 128 }
129 if (pid == 0) {
259 return AccessDenied(); 130 return AccessDenied();
131 }
260 132
261 hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid); 133 hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
262 if (hProcess == NULL) { 134 if (hProcess == NULL) {
263 if (GetLastError() == ERROR_INVALID_PARAMETER) { 135 if (GetLastError() == ERROR_INVALID_PARAMETER) {
264 // see http://code.google.com/p/psutil/issues/detail?id=24 136 // see http://code.google.com/p/psutil/issues/detail?id=24
265 NoSuchProcess(); 137 NoSuchProcess();
266 } 138 }
267 else { 139 else {
268 PyErr_SetFromWindowsErr(0); 140 PyErr_SetFromWindowsErr(0);
269 } 141 }
270 return NULL; 142 return NULL;
271 } 143 }
272 144
273 // kill the process 145 // kill the process
274 if (! TerminateProcess(hProcess, 0)) { 146 if (! TerminateProcess(hProcess, 0)) {
275 PyErr_SetFromWindowsErr(0); 147 PyErr_SetFromWindowsErr(0);
276 CloseHandle(hProcess); 148 CloseHandle(hProcess);
277 return NULL; 149 return NULL;
278 } 150 }
279 151
280 CloseHandle(hProcess); 152 CloseHandle(hProcess);
281 Py_INCREF(Py_None); 153 Py_INCREF(Py_None);
282 return Py_None; 154 return Py_None;
283 } 155 }
284 156
285 157
158 /*
159 * Wait for process to terminate and return its exit code.
160 */
161 static PyObject*
162 process_wait(PyObject* self, PyObject* args)
163 {
164 HANDLE hProcess;
165 DWORD ExitCode;
166 DWORD retVal;
167 long pid;
168 long timeout;
169
170 if (! PyArg_ParseTuple(args, "ll", &pid, &timeout)) {
171 return NULL;
172 }
173 if (pid == 0) {
174 return AccessDenied();
175 }
176
177 hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);
178 if (hProcess == NULL) {
179 if (GetLastError() == ERROR_INVALID_PARAMETER) {
180 // no such process; we do not want to raise NSP but
181 // return None instead.
182 Py_INCREF(Py_None);
183 return Py_None;
184 }
185 else {
186 PyErr_SetFromWindowsErr(0);
187 return NULL;
188 }
189 }
190
191 // wait until the process has terminated
192 Py_BEGIN_ALLOW_THREADS
193 retVal = WaitForSingleObject(hProcess, timeout);
194 Py_END_ALLOW_THREADS
195
196 if (retVal == WAIT_FAILED) {
197 CloseHandle(hProcess);
198 return PyErr_SetFromWindowsErr(GetLastError());
199 }
200 if (retVal == WAIT_TIMEOUT) {
201 CloseHandle(hProcess);
202 return Py_BuildValue("l", WAIT_TIMEOUT);
203 }
204
205 // get the exit code; note: subprocess module (erroneously?) uses
206 // what returned by WaitForSingleObject
207 if (GetExitCodeProcess(hProcess, &ExitCode) == 0) {
208 CloseHandle(hProcess);
209 return PyErr_SetFromWindowsErr(GetLastError());
210 }
211 CloseHandle(hProcess);
212 #if PY_MAJOR_VERSION >= 3
213 return PyLong_FromLong((long) ExitCode);
214 #else
215 return PyInt_FromLong((long) ExitCode);
216 #endif
217 }
218
286 219
287 /* 220 /*
288 * Return a Python tuple (user_time, kernel_time) 221 * Return a Python tuple (user_time, kernel_time)
289 */ 222 */
290 static PyObject* 223 static PyObject*
291 get_process_cpu_times(PyObject* self, PyObject* args) 224 get_process_cpu_times(PyObject* self, PyObject* args)
292 { 225 {
293 long pid; 226 long pid;
294 HANDLE hProcess; 227 HANDLE hProcess;
295 FILETIME ftCreate, ftExit, ftKernel, ftUser; 228 FILETIME ftCreate, ftExit, ftKernel, ftUser;
296 229
297 if (! PyArg_ParseTuple(args, "l", &pid)) { 230 if (! PyArg_ParseTuple(args, "l", &pid)) {
298 return NULL; 231 return NULL;
299 } 232 }
300 233
301 // special case for PID 0 234 // special case for PID 0
302 if (0 == pid){ 235 if (0 == pid){
303 return Py_BuildValue("(dd)", 0.0, 0.0); 236 return Py_BuildValue("(dd)", 0.0, 0.0);
304 } 237 }
305 238
306 hProcess = handle_from_pid(pid); 239 hProcess = handle_from_pid(pid);
307 if (hProcess == NULL) { 240 if (hProcess == NULL) {
308 return NULL; 241 return NULL;
309 } 242 }
310 243
311 if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) { 244 if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
245 CloseHandle(hProcess);
312 if (GetLastError() == ERROR_ACCESS_DENIED) { 246 if (GetLastError() == ERROR_ACCESS_DENIED) {
313 // usually means the process has died so we throw a NoSuchProcess 247 // usually means the process has died so we throw a NoSuchProcess
314 // here 248 // here
315 CloseHandle(hProcess);
316 return NoSuchProcess(); 249 return NoSuchProcess();
317 } 250 }
318 PyErr_SetFromWindowsErr(0); 251 else {
319 CloseHandle(hProcess); 252 PyErr_SetFromWindowsErr(0);
320 return NULL; 253 return NULL;
254 }
321 } 255 }
322 256
323 CloseHandle(hProcess); 257 CloseHandle(hProcess);
324 258
325 /* 259 /*
326 user and kernel times are represented as a FILETIME structure wich contains 260 user and kernel times are represented as a FILETIME structure wich contains
327 a 64-bit value representing the number of 100-nanosecond intervals since 261 a 64-bit value representing the number of 100-nanosecond intervals since
328 January 1, 1601 (UTC). 262 January 1, 1601 (UTC).
329 http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx 263 http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
330 264
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 if ( (0 == pid) || (4 == pid) ){ 297 if ( (0 == pid) || (4 == pid) ){
364 return Py_BuildValue("d", 0.0); 298 return Py_BuildValue("d", 0.0);
365 } 299 }
366 300
367 hProcess = handle_from_pid(pid); 301 hProcess = handle_from_pid(pid);
368 if (hProcess == NULL) { 302 if (hProcess == NULL) {
369 return NULL; 303 return NULL;
370 } 304 }
371 305
372 if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) { 306 if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
307 CloseHandle(hProcess);
373 if (GetLastError() == ERROR_ACCESS_DENIED) { 308 if (GetLastError() == ERROR_ACCESS_DENIED) {
374 // usually means the process has died so we throw a NoSuchProcess he re 309 // usually means the process has died so we throw a NoSuchProcess he re
375 return NoSuchProcess(); 310 return NoSuchProcess();
376 } 311 }
377 else { 312 else {
378 PyErr_SetFromWindowsErr(0); 313 PyErr_SetFromWindowsErr(0);
314 return NULL;
379 } 315 }
380 CloseHandle(hProcess);
381 return NULL;
382 } 316 }
383 317
384 CloseHandle(hProcess); 318 CloseHandle(hProcess);
385 319
386 /* 320 /*
387 Convert the FILETIME structure to a Unix time. 321 Convert the FILETIME structure to a Unix time.
388 It's the best I could find by googling and borrowing code here and there. 322 It's the best I could find by googling and borrowing code here and there.
389 The time returned has a precision of 1 second. 323 The time returned has a precision of 1 second.
390 */ 324 */
391 unix_time = ((LONGLONG)ftCreate.dwHighDateTime) << 32; 325 unix_time = ((LONGLONG)ftCreate.dwHighDateTime) << 32;
(...skipping 22 matching lines...) Expand all
414 348
415 /* 349 /*
416 * Return process name as a Python string. 350 * Return process name as a Python string.
417 */ 351 */
418 static PyObject* 352 static PyObject*
419 get_process_name(PyObject* self, PyObject* args) { 353 get_process_name(PyObject* self, PyObject* args) {
420 long pid; 354 long pid;
421 int pid_return; 355 int pid_return;
422 PyObject* name; 356 PyObject* name;
423 357
424 if (! PyArg_ParseTuple(args, "l", &pid)) 358 if (! PyArg_ParseTuple(args, "l", &pid)) {
425 return NULL; 359 return NULL;
360 }
426 361
427 if (pid == 0) { 362 if (pid == 0) {
428 return Py_BuildValue("s", "System Idle Process"); 363 return Py_BuildValue("s", "System Idle Process");
429 } 364 }
430 else if (pid == 4) { 365 else if (pid == 4) {
431 return Py_BuildValue("s", "System"); 366 return Py_BuildValue("s", "System");
432 } 367 }
433 368
434 pid_return = pid_is_running(pid); 369 pid_return = pid_is_running(pid);
435 if (pid_return == 0) { 370 if (pid_return == 0) {
436 return NoSuchProcess(); 371 return NoSuchProcess();
437 } 372 }
438 if (pid_return == -1) { 373 if (pid_return == -1) {
439 return NULL; 374 return NULL;
440 } 375 }
441 376
442 name = get_name(pid); 377 name = get_name(pid);
443 if (name == NULL) 378 if (name == NULL) {
444 return NULL; // exception set in get_name() 379 return NULL; // exception set in get_name()
380 }
445 return name; 381 return name;
446 } 382 }
447 383
448 384
449 /* 385 /*
450 * Return process parent pid as a Python integer. 386 * Return process parent pid as a Python integer.
451 */ 387 */
452 static PyObject* 388 static PyObject*
453 get_process_ppid(PyObject* self, PyObject* args) { 389 get_process_ppid(PyObject* self, PyObject* args) {
454 long pid; 390 long pid;
455 int pid_return; 391 int pid_return;
456 PyObject* ppid; 392 PyObject* ppid;
457 393
458 if (! PyArg_ParseTuple(args, "l", &pid)) 394 if (! PyArg_ParseTuple(args, "l", &pid)) {
459 return NULL; 395 return NULL;
460 if ((pid == 0) || (pid == 4)) 396 }
397 if ((pid == 0) || (pid == 4)) {
461 return Py_BuildValue("l", 0); 398 return Py_BuildValue("l", 0);
399 }
462 400
463 pid_return = pid_is_running(pid); 401 pid_return = pid_is_running(pid);
464 if (pid_return == 0) { 402 if (pid_return == 0) {
465 return NoSuchProcess(); 403 return NoSuchProcess();
466 } 404 }
467 if (pid_return == -1) { 405 if (pid_return == -1) {
468 return NULL; 406 return NULL;
469 } 407 }
470 408
471 ppid = get_ppid(pid); 409 ppid = get_ppid(pid);
472 if (ppid == NULL) 410 if (ppid == NULL) {
473 return NULL; // exception set in get_ppid() 411 return NULL; // exception set in get_ppid()
412 }
474 return ppid; 413 return ppid;
475 } 414 }
476 415
477 /* 416 /*
478 * Return process cmdline as a Python list of cmdline arguments. 417 * Return process cmdline as a Python list of cmdline arguments.
479 */ 418 */
480 static PyObject* 419 static PyObject*
481 get_process_cmdline(PyObject* self, PyObject* args) { 420 get_process_cmdline(PyObject* self, PyObject* args) {
482 long pid; 421 long pid;
483 int pid_return; 422 int pid_return;
484 PyObject* arglist; 423 PyObject* arglist;
485 424
486 if (! PyArg_ParseTuple(args, "l", &pid)) 425 if (! PyArg_ParseTuple(args, "l", &pid)) {
487 return NULL; 426 return NULL;
488 if ((pid == 0) || (pid == 4)) 427 }
428 if ((pid == 0) || (pid == 4)) {
489 return Py_BuildValue("[]"); 429 return Py_BuildValue("[]");
430 }
490 431
491 pid_return = pid_is_running(pid); 432 pid_return = pid_is_running(pid);
492 if (pid_return == 0) { 433 if (pid_return == 0) {
493 return NoSuchProcess(); 434 return NoSuchProcess();
494 } 435 }
495 if (pid_return == -1) { 436 if (pid_return == -1) {
496 return NULL; 437 return NULL;
497 } 438 }
498 439
499 // May fail any of several ReadProcessMemory calls etc. and not indicate 440 // May fail any of several ReadProcessMemory calls etc. and not indicate
(...skipping 22 matching lines...) Expand all
522 if (! PyArg_ParseTuple(args, "l", &pid)) { 463 if (! PyArg_ParseTuple(args, "l", &pid)) {
523 return NULL; 464 return NULL;
524 } 465 }
525 466
526 hProcess = handle_from_pid(pid); 467 hProcess = handle_from_pid(pid);
527 if (NULL == hProcess) { 468 if (NULL == hProcess) {
528 return NULL; 469 return NULL;
529 } 470 }
530 471
531 if (! GetProcessMemoryInfo(hProcess, &counters, sizeof(counters)) ) { 472 if (! GetProcessMemoryInfo(hProcess, &counters, sizeof(counters)) ) {
473 CloseHandle(hProcess);
532 return PyErr_SetFromWindowsErr(0); 474 return PyErr_SetFromWindowsErr(0);
533 } 475 }
534 476
477 CloseHandle(hProcess);
535 return Py_BuildValue("(nn)", counters.WorkingSetSize, counters.PagefileUsage ); 478 return Py_BuildValue("(nn)", counters.WorkingSetSize, counters.PagefileUsage );
536 } 479 }
537 480
538 481
539 /* 482 /*
540 * Return a Python integer indicating the total amount of physical memory 483 * Return a Python integer indicating the total amount of physical memory
541 * in bytes. 484 * in bytes.
542 */ 485 */
543 static PyObject* 486 static PyObject*
544 get_total_phymem(PyObject* self, PyObject* args) 487 get_system_phymem(PyObject* self, PyObject* args)
545 { 488 {
546 MEMORYSTATUSEX memInfo; 489 MEMORYSTATUSEX memInfo;
547 memInfo.dwLength = sizeof(MEMORYSTATUSEX); 490 memInfo.dwLength = sizeof(MEMORYSTATUSEX);
548 491
549 if (! GlobalMemoryStatusEx(&memInfo) ) { 492 if (! GlobalMemoryStatusEx(&memInfo) ) {
550 return PyErr_SetFromWindowsErr(0); 493 return PyErr_SetFromWindowsErr(0);
551 } 494 }
552 495
553 return Py_BuildValue("L", memInfo.ullTotalPhys); 496 return Py_BuildValue("(LLLLLLk)",
554 } 497 memInfo.ullTotalPhys, // total
555 498 memInfo.ullAvailPhys, // avail
556 499 memInfo.ullTotalPageFile, // total page file
557 /* 500 memInfo.ullAvailPageFile, // avail page file
558 * Return a Python integer indicating the total amount of virtual memory 501 memInfo.ullTotalVirtual, // total virtual
559 * in bytes. 502 memInfo.ullAvailVirtual, // avail virtual
560 */ 503 memInfo.dwMemoryLoad // percent
561 static PyObject* 504 );
562 get_total_virtmem(PyObject* self, PyObject* args)
563 {
564 MEMORYSTATUSEX memInfo;
565 memInfo.dwLength = sizeof(MEMORYSTATUSEX);
566
567 if (! GlobalMemoryStatusEx(&memInfo) ) {
568 return PyErr_SetFromWindowsErr(0);
569 }
570
571 return Py_BuildValue("L", memInfo.ullTotalPageFile);
572 }
573
574
575 /*
576 * Return a Python integer indicating the amount of available physical memory
577 * in bytes.
578 */
579 static PyObject*
580 get_avail_phymem(PyObject* self, PyObject* args)
581 {
582 MEMORYSTATUSEX memInfo;
583 memInfo.dwLength = sizeof(MEMORYSTATUSEX);
584 if (! GlobalMemoryStatusEx(&memInfo) ) {
585 return PyErr_SetFromWindowsErr(0);
586 }
587 return Py_BuildValue("L", memInfo.ullAvailPhys);
588 }
589
590
591 /*
592 * Return a Python integer indicating the amount of available virtual memory
593 * in bytes.
594 */
595 static PyObject*
596 get_avail_virtmem(PyObject* self, PyObject* args)
597 {
598 MEMORYSTATUSEX memInfo;
599 memInfo.dwLength = sizeof(MEMORYSTATUSEX);
600
601 if (! GlobalMemoryStatusEx(&memInfo) ) {
602 return PyErr_SetFromWindowsErr(0);
603 }
604 return Py_BuildValue("L", memInfo.ullAvailPageFile);
605 } 505 }
606 506
607 507
608 #define LO_T ((float)1e-7) 508 #define LO_T ((float)1e-7)
609 #define HI_T (LO_T*4294967296.0) 509 #define HI_T (LO_T*4294967296.0)
610 510
611 // structures and enums from winternl.h (not available under mingw)
612 typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
613 LARGE_INTEGER IdleTime;
614 LARGE_INTEGER KernelTime;
615 LARGE_INTEGER UserTime;
616 LARGE_INTEGER Reserved1[2];
617 ULONG Reserved2;
618 } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFOR MATION;
619
620
621 typedef enum _SYSTEM_INFORMATION_CLASS {
622 SystemBasicInformation = 0,
623 SystemPerformanceInformation = 2,
624 SystemTimeOfDayInformation = 3,
625 SystemProcessInformation = 5,
626 SystemProcessorPerformanceInformation = 8,
627 SystemInterruptInformation = 23,
628 SystemExceptionInformation = 33,
629 SystemRegistryQuotaInformation = 37,
630 SystemLookasideInformation = 45
631 } SYSTEM_INFORMATION_CLASS;
632
633 511
634 /* 512 /*
635 * Return a Python tuple representing user, kernel and idle CPU times 513 * Return a Python list of tuples representing user, kernel and idle
514 * CPU times for every CPU on the system.
636 */ 515 */
637 static PyObject* 516 static PyObject*
638 get_system_cpu_times(PyObject* self, PyObject* args) 517 get_system_cpu_times(PyObject* self, PyObject* args)
639 { 518 {
640 typedef BOOL (_stdcall *GST_PROC) (LPFILETIME, LPFILETIME, LPFILETIME);
641 static GST_PROC GetSystemTimes;
642 static BOOL bFirstCall = TRUE;
643 float idle, kernel, user; 519 float idle, kernel, user;
520 typedef DWORD (_stdcall *NTQSI_PROC) (int, PVOID, ULONG, PULONG);
521 NTQSI_PROC NtQuerySystemInformation;
522 HINSTANCE hNtDll;
523 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
524 SYSTEM_INFO si;
525 UINT i;
526 PyObject *arg = NULL;
527 PyObject *retlist = PyList_New(0);
644 528
645 // Improves performance calling GetProcAddress only the first time 529 // dynamic linking is mandatory to use NtQuerySystemInformation
646 if (bFirstCall) { 530 hNtDll = LoadLibrary(TEXT("ntdll.dll"));
647 // retrieves GetSystemTimes address in Kernel32 531 if (hNtDll != NULL) {
648 GetSystemTimes=(GST_PROC)GetProcAddress(GetModuleHandle 532 // gets NtQuerySystemInformation address
649 (TEXT("Kernel32.dll")), 533 NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
650 "GetSystemTimes"); 534 hNtDll, "NtQuerySystemInformation");
651 bFirstCall = FALSE; 535
536 if (NtQuerySystemInformation != NULL)
537 {
538 // retrives number of processors
539 GetSystemInfo(&si);
540
541 // allocates an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
542 // structures, one per processor
543 sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) \
544 malloc(si.dwNumberOfProcessors * \
545 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
546 if (sppi != NULL)
547 {
548 // gets cpu time informations
549 if (0 == NtQuerySystemInformation(
550 SystemProcessorPerformanceInformation,
551 sppi,
552 si.dwNumberOfProcessors * sizeof
553 (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
554 NULL)
555 )
556 {
557 // computes system global times summing each processor value
558 idle = user = kernel = 0;
559 for (i=0; i<si.dwNumberOfProcessors; i++) {
560 user = (float)((HI_T * sppi[i].UserTime.HighPart) + \
561 (LO_T * sppi[i].UserTime.LowPart));
562 idle = (float)((HI_T * sppi[i].IdleTime.HighPart) + \
563 (LO_T * sppi[i].IdleTime.LowPart));
564 kernel = (float)((HI_T * sppi[i].KernelTime.HighPart) + \
565 (LO_T * sppi[i].KernelTime.LowPart));
566 // kernel time includes idle time on windows
567 // we return only busy kernel time subtracting
568 // idle time from kernel time
569 arg = Py_BuildValue("(ddd)", user,
570 kernel - idle,
571 idle);
572 PyList_Append(retlist, arg);
573 Py_XDECREF(arg);
574 }
575 free(sppi);
576 FreeLibrary(hNtDll);
577 return retlist;
578
579 } // END NtQuerySystemInformation
580 } // END malloc SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
581 } // END GetProcAddress
582 } // END LoadLibrary
583
584 if (sppi) {
585 free(sppi);
652 } 586 }
653 587 if (hNtDll) {
654 588 FreeLibrary(hNtDll);
655 // Uses GetSystemTimes if supported (winXP sp1+)
656 if (NULL!=GetSystemTimes) {
657 // GetSystemTimes supported
658
659 FILETIME idle_time;
660 FILETIME kernel_time;
661 FILETIME user_time;
662
663 if (!GetSystemTimes(&idle_time, &kernel_time, &user_time)) {
664 return PyErr_SetFromWindowsErr(0);
665 }
666
667 idle = (float)((HI_T * idle_time.dwHighDateTime) + \
668 (LO_T * idle_time.dwLowDateTime));
669 user = (float)((HI_T * user_time.dwHighDateTime) + \
670 (LO_T * user_time.dwLowDateTime));
671 kernel = (float)((HI_T * kernel_time.dwHighDateTime) + \
672 (LO_T * kernel_time.dwLowDateTime));
673
674 // kernel time includes idle time on windows
675 // we return only busy kernel time subtracting idle time from kernel tim e
676 return Py_BuildValue("(fff)", user,
677 kernel - idle,
678 idle);
679
680 } 589 }
681 590 PyErr_SetFromWindowsErr(0);
682 else { 591 return NULL;
683 // GetSystemTimes NOT supported, use NtQuerySystemInformation instead
684
685 typedef DWORD (_stdcall *NTQSI_PROC) (int, PVOID, ULONG, PULONG);
686 NTQSI_PROC NtQuerySystemInformation;
687 HINSTANCE hNtDll;
688 SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
689 SYSTEM_INFO si;
690 UINT i;
691
692 // dynamic linking is mandatory to use NtQuerySystemInformation
693 hNtDll = LoadLibrary(TEXT("ntdll.dll"));
694 if (hNtDll != NULL) {
695 // gets NtQuerySystemInformation address
696 NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
697 hNtDll, "NtQuerySystemInformation");
698
699 if (NtQuerySystemInformation != NULL)
700 {
701 // retrives number of processors
702 GetSystemInfo(&si);
703
704 // allocates an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATIO N
705 // structures, one per processor
706 sppi=(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) \
707 malloc(si.dwNumberOfProcessors * \
708 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
709 if (sppi != NULL)
710 {
711 // gets cpu time informations
712 if (0 == NtQuerySystemInformation(
713 SystemProcessorPerformanceInformation,
714 sppi,
715 si.dwNumberOfProcessors * sizeof(SYSTEM_PROCESSO R_PERFORMANCE_INFORMATION),
716 NULL))
717 {
718 // computes system global times summing each processor v alue
719 idle = user = kernel = 0;
720 for (i=0; i<si.dwNumberOfProcessors; i++) {
721 idle += (float)((HI_T * sppi[i].IdleTime.HighPart) + \
722 (LO_T * sppi[i].IdleTime.LowPart));
723 user += (float)((HI_T * sppi[i].UserTime.HighPart) + \
724 (LO_T * sppi[i].UserTime.LowPart));
725 kernel += (float)((HI_T * sppi[i].KernelTime.HighPar t) + \
726 (LO_T * sppi[i].KernelTime.LowPart ));
727 }
728
729 // kernel time includes idle time on windows
730 // we return only busy kernel time subtracting idle
731 // time from kernel time
732 return Py_BuildValue("(ddd)", user,
733 kernel - idle,
734 idle
735 );
736
737 } // END NtQuerySystemInformation
738
739 } // END malloc SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
740
741 } // END GetProcAddress
742
743 } // END LoadLibrary
744
745 PyErr_SetFromWindowsErr(0);
746 if (sppi) {
747 free(sppi);
748 }
749 if (hNtDll) {
750 FreeLibrary(hNtDll);
751 }
752 return 0;
753
754 } // END GetSystemTimes NOT supported
755 } 592 }
756 593
757 594
758 /* 595 /*
759 * Sid to User convertion
760 */
761 BOOL SidToUser(PSID pSid, LPTSTR szUser, DWORD dwUserLen, LPTSTR szDomain, DWORD
762 dwDomainLen, DWORD pid)
763 {
764 SID_NAME_USE snuSIDNameUse;
765 DWORD dwULen;
766 DWORD dwDLen;
767
768 dwULen = dwUserLen;
769 dwDLen = dwDomainLen;
770
771 if ( IsValidSid( pSid ) ) {
772 // Get user and domain name based on SID
773 if ( LookupAccountSid( NULL, pSid, szUser, &dwULen, szDomain, &dwDLen, & snuSIDNameUse) ) {
774 // LocalSystem processes are incorrectly reported as owned
775 // by BUILTIN\Administrators We modify that behavior to
776 // conform to standard taskmanager only if the process is
777 // actually a System process
778 if (is_system_proc(pid) == 1) {
779 // default to *not* changing the data if we fail to
780 // check for local system privileges, so only look for
781 // definite confirmed system processes and ignore errors
782 if ( lstrcmpi(szDomain, TEXT("builtin")) == 0 && lstrcmpi(szUser , TEXT("administrators")) == 0) {
783 strncpy (szUser, "SYSTEM", dwUserLen);
784 strncpy (szDomain, "NT AUTHORITY", dwDomainLen);
785 }
786 }
787
788 return TRUE;
789 }
790 }
791
792 return FALSE;
793 }
794
795 typedef struct _UNICODE_STRING {
796 USHORT Length;
797 USHORT MaximumLength;
798 PWSTR Buffer;
799 } UNICODE_STRING, *PUNICODE_STRING;
800
801 /*
802 * Return process current working directory as a Python string. 596 * Return process current working directory as a Python string.
803 */ 597 */
804 598
805 static PyObject* 599 static PyObject*
806 get_process_cwd(PyObject* self, PyObject* args) 600 get_process_cwd(PyObject* self, PyObject* args)
807 { 601 {
808 long pid; 602 long pid;
809 HANDLE processHandle; 603 HANDLE processHandle;
810 PVOID pebAddress; 604 PVOID pebAddress;
811 PVOID rtlUserProcParamsAddress; 605 PVOID rtlUserProcParamsAddress;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 /* 709 /*
916 * Resume or suspends a process 710 * Resume or suspends a process
917 */ 711 */
918 int 712 int
919 suspend_resume_process(DWORD pid, int suspend) 713 suspend_resume_process(DWORD pid, int suspend)
920 { 714 {
921 // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx 715 // a huge thanks to http://www.codeproject.com/KB/threads/pausep.aspx
922 HANDLE hThreadSnap = NULL; 716 HANDLE hThreadSnap = NULL;
923 THREADENTRY32 te32 = {0}; 717 THREADENTRY32 te32 = {0};
924 718
719 if (pid == 0) {
720 AccessDenied();
721 return FALSE;
722 }
723
925 hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 724 hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
926 if (hThreadSnap == INVALID_HANDLE_VALUE) { 725 if (hThreadSnap == INVALID_HANDLE_VALUE) {
927 PyErr_SetFromWindowsErr(0); 726 PyErr_SetFromWindowsErr(0);
928 return FALSE; 727 return FALSE;
929 } 728 }
930 729
931 // Fill in the size of the structure before using it 730 // Fill in the size of the structure before using it
932 te32.dwSize = sizeof(THREADENTRY32); 731 te32.dwSize = sizeof(THREADENTRY32);
933 732
934 if (! Thread32First(hThreadSnap, &te32)) { 733 if (! Thread32First(hThreadSnap, &te32)) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 return NULL; 807 return NULL;
1009 } 808 }
1010 Py_INCREF(Py_None); 809 Py_INCREF(Py_None);
1011 return Py_None; 810 return Py_None;
1012 } 811 }
1013 812
1014 813
1015 static PyObject* 814 static PyObject*
1016 get_process_num_threads(PyObject* self, PyObject* args) 815 get_process_num_threads(PyObject* self, PyObject* args)
1017 { 816 {
817 DWORD pid;
818 PSYSTEM_PROCESS_INFORMATION process;
819 PVOID buffer;
820 int num;
821
822 if (! PyArg_ParseTuple(args, "l", &pid)) {
823 return NULL;
824 }
825 if (get_process_info(pid, &process, &buffer) != 1) {
826 free(buffer);
827 return NULL;
828 }
829 if (pid_is_running(pid) == 0) {
830 free(buffer);
831 return NoSuchProcess();
832 }
833
834 num = (int)process->NumberOfThreads;
835 free(buffer);
836 return Py_BuildValue("i", num);
837 }
838
839
840 static PyObject*
841 get_process_threads(PyObject* self, PyObject* args)
842 {
843 PyObject* retList = PyList_New(0);
844 PyObject* pyTuple = NULL;
845 HANDLE hThreadSnap = NULL;
846 THREADENTRY32 te32 = {0};
1018 long pid; 847 long pid;
1019 int pid_return; 848 int pid_return;
1020 long nthreads = 0; 849 int rc;
1021 HANDLE hThreadSnap = NULL; 850 FILETIME ftDummy, ftKernel, ftUser;
1022 THREADENTRY32 te32 = {0};
1023 851
1024 if (! PyArg_ParseTuple(args, "l", &pid)) 852 if (! PyArg_ParseTuple(args, "l", &pid)) {
1025 return NULL; 853 return NULL;
854 }
1026 if (pid == 0) { 855 if (pid == 0) {
1027 // raise AD instead of returning 0 as procexp is able to 856 // raise AD instead of returning 0 as procexp is able to
1028 // retrieve useful information somehow 857 // retrieve useful information somehow
1029 return AccessDenied(); 858 return AccessDenied();
1030 } 859 }
1031 860
1032 pid_return = pid_is_running(pid); 861 pid_return = pid_is_running(pid);
1033 if (pid_return == 0) { 862 if (pid_return == 0) {
1034 return NoSuchProcess(); 863 return NoSuchProcess();
1035 } 864 }
(...skipping 18 matching lines...) Expand all
1054 883
1055 // Walk the thread snapshot to find all threads of the process. 884 // Walk the thread snapshot to find all threads of the process.
1056 // If the thread belongs to the process, increase the counter. 885 // If the thread belongs to the process, increase the counter.
1057 do 886 do
1058 { 887 {
1059 if (te32.th32OwnerProcessID == pid) 888 if (te32.th32OwnerProcessID == pid)
1060 { 889 {
1061 HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, 890 HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,
1062 FALSE, te32.th32ThreadID); 891 FALSE, te32.th32ThreadID);
1063 if (hThread == NULL) { 892 if (hThread == NULL) {
1064 if (GetLastError() == ERROR_INVALID_PARAMETER) { 893 // thread has disappeared on us
1065 NoSuchProcess(); 894 continue;
1066 } 895 }
1067 else { 896
1068 PyErr_SetFromWindowsErr(0); 897 rc = GetThreadTimes(hThread, &ftDummy, &ftDummy, &ftKernel, &ftUser) ;
1069 } 898 if (rc == 0) {
899 PyErr_SetFromWindowsErr(0);
1070 CloseHandle(hThread); 900 CloseHandle(hThread);
1071 CloseHandle(hThreadSnap); 901 CloseHandle(hThreadSnap);
1072 return NULL; 902 return NULL;
1073 } 903 }
1074 nthreads += 1; 904
905 /*
906 user and kernel times are represented as a FILETIME structure
907 wich contains a 64-bit value representing the number of
908 100-nanosecond intervals since January 1, 1601 (UTC).
909 http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
910
911 To convert it into a float representing the seconds that the
912 process has executed in user/kernel mode I borrowed the code
913 below from Python's Modules/posixmodule.c
914 */
915 pyTuple = Py_BuildValue("kdd",
916 te32.th32ThreadID,
917 (double)(ftUser.dwHighDateTime*429.4967296 + \
918 ftUser.dwLowDateTime*1e-7),
919 (double)(ftKernel.dwHighDateTime*429.4967296 + \
920 ftKernel.dwLowDateTime*1e-7)
921 );
922 PyList_Append(retList, pyTuple);
923 Py_XDECREF(pyTuple);
924
1075 CloseHandle(hThread); 925 CloseHandle(hThread);
1076 } 926 }
1077 } while (Thread32Next(hThreadSnap, &te32)); 927 } while (Thread32Next(hThreadSnap, &te32));
1078 928
1079 // every process should be supposed to have at least one thread 929 CloseHandle(hThreadSnap);
1080 if (nthreads == 0) { 930 return retList;
1081 return NoSuchProcess(); 931 }
1082 }
1083 932
1084 return Py_BuildValue("l", nthreads);
1085 }
1086 933
1087 934
1088 static PyObject* 935 static PyObject*
1089 get_process_open_files(PyObject* self, PyObject* args) 936 get_process_open_files(PyObject* self, PyObject* args)
1090 { 937 {
1091 long pid; 938 long pid;
1092 HANDLE processHandle; 939 HANDLE processHandle;
1093 DWORD access = PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION; 940 DWORD access = PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
1094 PyObject* filesList; 941 PyObject* filesList;
1095 942
1096 if (! PyArg_ParseTuple(args, "l", &pid)) { 943 if (! PyArg_ParseTuple(args, "l", &pid)) {
1097 return NULL; 944 return NULL;
1098 } 945 }
1099 946
1100 processHandle = handle_from_pid_waccess(pid, access); 947 processHandle = handle_from_pid_waccess(pid, access);
1101 if (processHandle == NULL) { 948 if (processHandle == NULL) {
1102 return NULL; 949 return NULL;
1103 } 950 }
1104 951
1105 filesList = get_open_files(pid, processHandle); 952 filesList = get_open_files(pid, processHandle);
953 CloseHandle(processHandle);
1106 if (filesList == NULL) { 954 if (filesList == NULL) {
1107 return PyErr_SetFromWindowsErr(0); 955 return PyErr_SetFromWindowsErr(0);
1108 } 956 }
1109 return filesList; 957 return filesList;
1110 } 958 }
1111 959
1112 960
1113 /* 961 /*
1114 Accept a filename's drive in native format like "\Device\HarddiskVolume1\" 962 Accept a filename's drive in native format like "\Device\HarddiskVolume1\"
1115 and return the corresponding drive letter (e.g. "C:\\"). 963 and return the corresponding drive letter (e.g. "C:\\").
1116 If no match is found return an empty string. 964 If no match is found return an empty string.
1117 */ 965 */
1118 static PyObject* 966 static PyObject*
1119 _QueryDosDevice(PyObject* self, PyObject* args) 967 win32_QueryDosDevice(PyObject* self, PyObject* args)
1120 { 968 {
1121 LPCTSTR lpDevicePath; 969 LPCTSTR lpDevicePath;
1122 TCHAR d = TEXT('A'); 970 TCHAR d = TEXT('A');
1123 TCHAR szBuff[5]; 971 TCHAR szBuff[5];
1124 972
1125 if (!PyArg_ParseTuple(args, "s", &lpDevicePath)) { 973 if (!PyArg_ParseTuple(args, "s", &lpDevicePath)) {
1126 return NULL; 974 return NULL;
1127 } 975 }
1128 976
1129 while(d <= TEXT('Z')) 977 while(d <= TEXT('Z'))
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1434 1282
1435 table = malloc(tableSize); 1283 table = malloc(tableSize);
1436 1284
1437 if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET, 1285 if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
1438 TCP_TABLE_OWNER_PID_ALL, 0) == 0) 1286 TCP_TABLE_OWNER_PID_ALL, 0) == 0)
1439 { 1287 {
1440 tcp4Table = table; 1288 tcp4Table = table;
1441 1289
1442 for (i = 0; i < tcp4Table->dwNumEntries; i++) 1290 for (i = 0; i < tcp4Table->dwNumEntries; i++)
1443 { 1291 {
1444 if (tcp4Table->table[i].dwOwningPid != pid) 1292 if (tcp4Table->table[i].dwOwningPid != pid) {
1445 continue; 1293 continue;
1294 }
1446 1295
1447 if (tcp4Table->table[i].dwLocalAddr != 0 || 1296 if (tcp4Table->table[i].dwLocalAddr != 0 ||
1448 tcp4Table->table[i].dwLocalPort != 0) 1297 tcp4Table->table[i].dwLocalPort != 0)
1449 { 1298 {
1450 struct in_addr addr; 1299 struct in_addr addr;
1451 1300
1452 addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr; 1301 addr.S_un.S_addr = tcp4Table->table[i].dwLocalAddr;
1453 rtlIpv4AddressToStringA(&addr, addressBufferLocal); 1302 rtlIpv4AddressToStringA(&addr, addressBufferLocal);
1454 addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal, 1303 addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
1455 BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort)); 1304 BYTESWAP_USHORT(tcp4Table->table[i].dwLocalPort));
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 1414
1566 table = malloc(tableSize); 1415 table = malloc(tableSize);
1567 1416
1568 if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET, 1417 if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
1569 UDP_TABLE_OWNER_PID, 0) == 0) 1418 UDP_TABLE_OWNER_PID, 0) == 0)
1570 { 1419 {
1571 udp4Table = table; 1420 udp4Table = table;
1572 1421
1573 for (i = 0; i < udp4Table->dwNumEntries; i++) 1422 for (i = 0; i < udp4Table->dwNumEntries; i++)
1574 { 1423 {
1575 if (udp4Table->table[i].dwOwningPid != pid) 1424 if (udp4Table->table[i].dwOwningPid != pid) {
1576 continue; 1425 continue;
1426 }
1577 1427
1578 if (udp4Table->table[i].dwLocalAddr != 0 || 1428 if (udp4Table->table[i].dwLocalAddr != 0 ||
1579 udp4Table->table[i].dwLocalPort != 0) 1429 udp4Table->table[i].dwLocalPort != 0)
1580 { 1430 {
1581 struct in_addr addr; 1431 struct in_addr addr;
1582 1432
1583 addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr; 1433 addr.S_un.S_addr = udp4Table->table[i].dwLocalAddr;
1584 rtlIpv4AddressToStringA(&addr, addressBufferLocal); 1434 rtlIpv4AddressToStringA(&addr, addressBufferLocal);
1585 addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal, 1435 addressTupleLocal = Py_BuildValue("(si)", addressBufferLocal,
1586 BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort)); 1436 BYTESWAP_USHORT(udp4Table->table[i].dwLocalPort));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1646 ); 1496 );
1647 PyList_Append(connectionsList, connectionTuple); 1497 PyList_Append(connectionsList, connectionTuple);
1648 } 1498 }
1649 } 1499 }
1650 1500
1651 free(table); 1501 free(table);
1652 1502
1653 return connectionsList; 1503 return connectionsList;
1654 } 1504 }
1655 1505
1506
1507 /*
1508 * Get process priority as a Python integer.
1509 */
1510 static PyObject*
1511 get_process_priority(PyObject* self, PyObject* args)
1512 {
1513 long pid;
1514 DWORD priority;
1515 HANDLE hProcess;
1516 if (! PyArg_ParseTuple(args, "l", &pid)) {
1517 return NULL;
1518 }
1519
1520 hProcess = handle_from_pid(pid);
1521 if (hProcess == NULL) {
1522 return NULL;
1523 }
1524
1525 priority = GetPriorityClass(hProcess);
1526 CloseHandle(hProcess);
1527 if (priority == 0) {
1528 PyErr_SetFromWindowsErr(0);
1529 return NULL;
1530 }
1531 return Py_BuildValue("i", priority);
1532 }
1533
1534
1535 /*
1536 * Set process priority.
1537 */
1538 static PyObject*
1539 set_process_priority(PyObject* self, PyObject* args)
1540 {
1541 long pid;
1542 int priority;
1543 int retval;
1544 HANDLE hProcess;
1545 DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
1546 if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
1547 return NULL;
1548 }
1549
1550 hProcess = handle_from_pid_waccess(pid, dwDesiredAccess);
1551 if (hProcess == NULL) {
1552 return NULL;
1553 }
1554
1555 retval = SetPriorityClass(hProcess, priority);
1556 CloseHandle(hProcess);
1557 if (retval == 0) {
1558 PyErr_SetFromWindowsErr(0);
1559 return NULL;
1560 }
1561 Py_INCREF(Py_None);
1562 return Py_None;
1563 }
1564
1565
1566 /*
1567 * Return a Python tuple referencing process I/O counters.
1568 */
1569 static PyObject*
1570 get_process_io_counters(PyObject* self, PyObject* args)
1571 {
1572 DWORD pid;
1573 HANDLE hProcess;
1574 IO_COUNTERS IoCounters;
1575
1576 if (! PyArg_ParseTuple(args, "l", &pid)) {
1577 return NULL;
1578 }
1579 if (pid == 0) {
1580 return AccessDenied();
1581 }
1582 hProcess = handle_from_pid(pid);
1583 if (NULL == hProcess) {
1584 return NULL;
1585 }
1586 if (! GetProcessIoCounters(hProcess, &IoCounters)) {
1587 CloseHandle(hProcess);
1588 return PyErr_SetFromWindowsErr(0);
1589 }
1590 CloseHandle(hProcess);
1591 return Py_BuildValue("(KKKK)", IoCounters.ReadOperationCount,
1592 IoCounters.WriteOperationCount,
1593 IoCounters.ReadTransferCount,
1594 IoCounters.WriteTransferCount);
1595 }
1596
1597
1598 /*
1599 * Return True if one of the process threads is in a waiting or
1600 * suspended status.
1601 */
1602 static PyObject*
1603 is_process_suspended(PyObject* self, PyObject* args)
1604 {
1605 DWORD pid;
1606 ULONG i;
1607 PSYSTEM_PROCESS_INFORMATION process;
1608 PVOID buffer;
1609
1610 if (! PyArg_ParseTuple(args, "l", &pid)) {
1611 return NULL;
1612 }
1613 if (get_process_info(pid, &process, &buffer) != 1) {
1614 free(buffer);
1615 return NULL;
1616 }
1617 if (pid_is_running(pid) == 0) {
1618 free(buffer);
1619 return NoSuchProcess();
1620 }
1621
1622 for (i = 0; i < process->NumberOfThreads; i++) {
1623 if (process->Threads[i].ThreadState != Waiting ||
1624 process->Threads[i].WaitReason != Suspended)
1625 {
1626 free(buffer);
1627 Py_RETURN_FALSE;
1628 }
1629 }
1630 free(buffer);
1631 Py_RETURN_TRUE;
1632 }
1633
1634
1635 /*
1636 * Return path's disk total and free as a Python tuple.
1637 */
1638 static PyObject*
1639 get_disk_usage(PyObject* self, PyObject* args)
1640 {
1641 BOOL retval;
1642 ULARGE_INTEGER _, total, free;
1643 LPCTSTR path;
1644
1645 if (! PyArg_ParseTuple(args, "s", &path)) {
1646 return NULL;
1647 }
1648
1649 Py_BEGIN_ALLOW_THREADS
1650 retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
1651 Py_END_ALLOW_THREADS
1652 if (retval == 0) {
1653 return PyErr_SetFromWindowsErr(0);
1654 }
1655
1656 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
1657 }
1658
1659
1660 /*
1661 * Return disk partitions as a list of namedtuples.
1662 */
1663 static PyObject*
1664 win32_GetLogicalDriveStrings(PyObject* self, PyObject* args)
1665 {
1666 DWORD num_bytes;
1667 char drive_strings[255];
1668 char* drive_letter = drive_strings;
1669 PyObject* py_retlist = PyList_New(0);
1670
1671 Py_BEGIN_ALLOW_THREADS
1672 num_bytes = GetLogicalDriveStrings(254, drive_letter);
1673 Py_END_ALLOW_THREADS
1674
1675 if (num_bytes == 0) {
1676 return PyErr_SetFromWindowsErr(0);
1677 }
1678
1679 while (*drive_letter != 0) {
1680 PyList_Append(py_retlist, Py_BuildValue("s", drive_letter));
1681 drive_letter = strchr(drive_letter, 0) +1;
1682 }
1683
1684 return py_retlist;
1685 }
1686
1687
1688 static PyObject*
1689 win32_GetDriveType(PyObject* self, PyObject* args)
1690 {
1691 LPCTSTR drive_letter;
1692 int type;
1693 char* type_str;
1694
1695 if (! PyArg_ParseTuple(args, "s", &drive_letter)) {
1696 return NULL;
1697 }
1698
1699 Py_BEGIN_ALLOW_THREADS
1700 type = GetDriveType(drive_letter);
1701 Py_END_ALLOW_THREADS
1702
1703 switch (type) {
1704 case DRIVE_UNKNOWN:
1705 type_str = "unknown";
1706 break;
1707 case DRIVE_NO_ROOT_DIR:
1708 type_str = "unmounted";
1709 case DRIVE_REMOVABLE:
1710 type_str = "removable";
1711 break;
1712 case DRIVE_FIXED:
1713 type_str = "fixed";
1714 break;
1715 case DRIVE_REMOTE:
1716 type_str = "remote";
1717 break;
1718 case DRIVE_CDROM:
1719 type_str = "cdrom";
1720 break;
1721 case DRIVE_RAMDISK:
1722 type_str = "ramdisk";
1723 break;
1724 default:
1725 type_str = "?";
1726 break;
1727 }
1728
1729 return Py_BuildValue("s", type_str);
1730 }
1731
1732
1733 // ------------------------ Python init ---------------------------
1734
1735 static PyMethodDef
1736 PsutilMethods[] =
1737 {
1738 // --- per-process functions
1739
1740 {"get_process_name", get_process_name, METH_VARARGS,
1741 "Return process name"},
1742 {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
1743 "Return process cmdline as a list of cmdline arguments"},
1744 {"get_process_ppid", get_process_ppid, METH_VARARGS,
1745 "Return process ppid as an integer"},
1746 {"kill_process", kill_process, METH_VARARGS,
1747 "Kill the process identified by the given PID"},
1748 {"get_process_cpu_times", get_process_cpu_times, METH_VARARGS,
1749 "Return tuple of user/kern time for the given PID"},
1750 {"get_process_create_time", get_process_create_time, METH_VARARGS,
1751 "Return a float indicating the process create time expressed in "
1752 "seconds since the epoch"},
1753 {"get_memory_info", get_memory_info, METH_VARARGS,
1754 "Return a tuple of RSS/VMS memory information"},
1755 {"get_process_cwd", get_process_cwd, METH_VARARGS,
1756 "Return process current working directory"},
1757 {"suspend_process", suspend_process, METH_VARARGS,
1758 "Suspend a process"},
1759 {"resume_process", resume_process, METH_VARARGS,
1760 "Resume a process"},
1761 {"get_process_open_files", get_process_open_files, METH_VARARGS,
1762 "Return files opened by process"},
1763 {"get_process_username", get_process_username, METH_VARARGS,
1764 "Return the username of a process"},
1765 {"get_process_connections", get_process_connections, METH_VARARGS,
1766 "Return the network connections of a process"},
1767 {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
1768 "Return the network connections of a process"},
1769 {"get_process_threads", get_process_threads, METH_VARARGS,
1770 "Return process threads information as a list of tuple"},
1771 {"process_wait", process_wait, METH_VARARGS,
1772 "Wait for process to terminate and return its exit code."},
1773 {"get_process_priority", get_process_priority, METH_VARARGS,
1774 "Return process priority."},
1775 {"set_process_priority", set_process_priority, METH_VARARGS,
1776 "Set process priority."},
1777 {"get_process_io_counters", get_process_io_counters, METH_VARARGS,
1778 "Get process I/O counters."},
1779 {"is_process_suspended", is_process_suspended, METH_VARARGS,
1780 "Return True if one of the process threads is in a suspended state"},
1781
1782 // --- system-related functions
1783
1784 {"get_pid_list", get_pid_list, METH_VARARGS,
1785 "Returns a list of PIDs currently running on the system"},
1786 {"pid_exists", pid_exists, METH_VARARGS,
1787 "Determine if the process exists in the current process list."},
1788 {"get_num_cpus", get_num_cpus, METH_VARARGS,
1789 "Returns the number of CPUs on the system"},
1790 {"get_system_uptime", get_system_uptime, METH_VARARGS,
1791 "Return system uptime"},
1792 {"get_system_phymem", get_system_phymem, METH_VARARGS,
1793 "Return the total amount of physical memory, in bytes"},
1794 {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
1795 "Return system per-cpu times as a list of tuples"},
1796 {"get_disk_usage", get_disk_usage, METH_VARARGS,
1797 "Return path's disk total and free as a Python tuple."},
1798
1799 // --- windows API bindings
1800 {"win32_GetLogicalDriveStrings", win32_GetLogicalDriveStrings, METH_VARARGS ,
1801 "GetLogicalDriveStrings binding"},
1802 {"win32_GetDriveType", win32_GetDriveType, METH_VARARGS,
1803 "GetDriveType binding"},
1804 {"win32_QueryDosDevice", win32_QueryDosDevice, METH_VARARGS,
1805 "QueryDosDevice binding"},
1806
1807 {NULL, NULL, 0, NULL}
1808 };
1809
1810
1811 struct module_state {
1812 PyObject *error;
1813 };
1814
1815 #if PY_MAJOR_VERSION >= 3
1816 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
1817 #else
1818 #define GETSTATE(m) (&_state)
1819 static struct module_state _state;
1820 #endif
1821
1822 #if PY_MAJOR_VERSION >= 3
1823
1824 static int psutil_mswindows_traverse(PyObject *m, visitproc visit, void *arg ) {
1825 Py_VISIT(GETSTATE(m)->error);
1826 return 0;
1827 }
1828
1829 static int psutil_mswindows_clear(PyObject *m) {
1830 Py_CLEAR(GETSTATE(m)->error);
1831 return 0;
1832 }
1833
1834 static struct PyModuleDef moduledef = {
1835 PyModuleDef_HEAD_INIT,
1836 "psutil_mswindows",
1837 NULL,
1838 sizeof(struct module_state),
1839 PsutilMethods,
1840 NULL,
1841 psutil_mswindows_traverse,
1842 psutil_mswindows_clear,
1843 NULL
1844 };
1845
1846 #define INITERROR return NULL
1847
1848 PyObject* PyInit__psutil_mswindows(void)
1849
1850 #else
1851 #define INITERROR return
1852 void init_psutil_mswindows(void)
1853 #endif
1854 {
1855 struct module_state *st = NULL;
1856 #if PY_MAJOR_VERSION >= 3
1857 PyObject *module = PyModule_Create(&moduledef);
1858 #else
1859 PyObject *module = Py_InitModule("_psutil_mswindows", PsutilMethods);
1860 #endif
1861
1862 if (module == NULL) {
1863 INITERROR;
1864 }
1865
1866 st = GETSTATE(module);
1867 st->error = PyErr_NewException("_psutil_mswindow.Error", NULL, NULL);
1868 if (st->error == NULL) {
1869 Py_DECREF(module);
1870 INITERROR;
1871 }
1872
1873 // Public constants
1874 // http://msdn.microsoft.com/en-us/library/ms683211(v=vs.85).aspx
1875 PyModule_AddIntConstant(module, "ABOVE_NORMAL_PRIORITY_CLASS",
1876 ABOVE_NORMAL_PRIORITY_CLASS);
1877 PyModule_AddIntConstant(module, "BELOW_NORMAL_PRIORITY_CLASS",
1878 BELOW_NORMAL_PRIORITY_CLASS);
1879 PyModule_AddIntConstant(module, "HIGH_PRIORITY_CLASS",
1880 HIGH_PRIORITY_CLASS);
1881 PyModule_AddIntConstant(module, "IDLE_PRIORITY_CLASS",
1882 IDLE_PRIORITY_CLASS);
1883 PyModule_AddIntConstant(module, "NORMAL_PRIORITY_CLASS",
1884 NORMAL_PRIORITY_CLASS);
1885 PyModule_AddIntConstant(module, "REALTIME_PRIORITY_CLASS",
1886 REALTIME_PRIORITY_CLASS);
1887 // private constants
1888 PyModule_AddIntConstant(module, "INFINITE", INFINITE);
1889 SetSeDebug();
1890
1891 #if PY_MAJOR_VERSION >= 3
1892 return module;
1893 #endif
1894 }
1895
1896
1897
OLDNEW
« no previous file with comments | « third_party/psutil/psutil/_psutil_mswindows.h ('k') | third_party/psutil/psutil/_psutil_osx.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698