6 * Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
7 * Copyright (C) 2009 Maxime Vernier <maxime.vernier@gmail.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 (x1 < x2 ? -1 : (x1 > x2 ? 1 : 0))
32 } PROCESS_PAGE_LIST_ITEM
, *LPPROCESS_PAGE_LIST_ITEM
;
34 HWND hProcessPage
; /* Process List Property Page */
36 HWND hProcessPageListCtrl
; /* Process ListCtrl Window */
37 HWND hProcessPageHeaderCtrl
; /* Process Header Control */
38 HWND hProcessPageEndProcessButton
; /* Process End Process button */
39 HWND hProcessPageShowAllProcessesButton
;/* Process Show All Processes checkbox */
41 static int nProcessPageWidth
;
42 static int nProcessPageHeight
;
43 static BOOL bProcessSort
= FALSE
;
44 static BOOL bProcessSortAscending
= FALSE
;
45 static HANDLE hProcessPageEvent
= NULL
; /* When this event becomes signaled then we refresh the process list */
46 static ULONG ProcessSortColumnIndex
= 0;
48 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
);
49 void AddProcess(ULONG Index
);
50 void UpdateProcesses();
51 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
);
52 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
);
53 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
);
54 void ProcessPageShowContextMenu(DWORD dwProcessId
);
55 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
);
56 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
);
59 ProcessPageWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
65 HANDLE hRefreshThread
= NULL
;
70 * Save the width and height
72 GetClientRect(hDlg
, &rc
);
73 nProcessPageWidth
= rc
.right
;
74 nProcessPageHeight
= rc
.bottom
;
76 /* Update window position */
77 SetWindowPos(hDlg
, NULL
, 15, 30, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
80 * Get handles to the controls
82 hProcessPageListCtrl
= GetDlgItem(hDlg
, IDC_PROCESSLIST
);
83 hProcessPageHeaderCtrl
= ListView_GetHeader(hProcessPageListCtrl
);
84 hProcessPageEndProcessButton
= GetDlgItem(hDlg
, IDC_ENDPROCESS
);
85 hProcessPageShowAllProcessesButton
= GetDlgItem(hDlg
, IDC_SHOWALLPROCESSES
);
88 * Set the title, and extended window styles for the list control
90 SetWindowTextW(hProcessPageListCtrl
, L
"Processes");
91 (void)ListView_SetExtendedListViewStyle(hProcessPageListCtrl
, ListView_GetExtendedListViewStyle(hProcessPageListCtrl
) | LVS_EX_FULLROWSELECT
| LVS_EX_HEADERDRAGDROP
);
96 * Subclass the process list control so we can intercept WM_ERASEBKGND
98 OldProcessListWndProc
= (WNDPROC
)(LONG_PTR
) SetWindowLongPtrW(hProcessPageListCtrl
, GWL_WNDPROC
, (LONG_PTR
)ProcessListWndProc
);
100 /* Start our refresh thread */
101 hRefreshThread
= CreateThread(NULL
, 0, ProcessPageRefreshThread
, NULL
, 0, NULL
);
106 /* Close the event handle, this will make the */
107 /* refresh thread exit when the wait fails */
108 CloseHandle(hProcessPageEvent
);
109 CloseHandle(hRefreshThread
);
111 SaveColumnSettings();
116 /* Handle the button clicks */
117 switch (LOWORD(wParam
))
120 ProcessPage_OnEndProcess();
125 if (wParam
== SIZE_MINIMIZED
)
130 nXDifference
= cx
- nProcessPageWidth
;
131 nYDifference
= cy
- nProcessPageHeight
;
132 nProcessPageWidth
= cx
;
133 nProcessPageHeight
= cy
;
135 /* Reposition the application page's controls */
136 GetWindowRect(hProcessPageListCtrl
, &rc
);
137 cx
= (rc
.right
- rc
.left
) + nXDifference
;
138 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
139 SetWindowPos(hProcessPageListCtrl
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
140 InvalidateRect(hProcessPageListCtrl
, NULL
, TRUE
);
142 GetClientRect(hProcessPageEndProcessButton
, &rc
);
143 MapWindowPoints(hProcessPageEndProcessButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), (sizeof(RECT
)/sizeof(POINT
)) );
144 cx
= rc
.left
+ nXDifference
;
145 cy
= rc
.top
+ nYDifference
;
146 SetWindowPos(hProcessPageEndProcessButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
147 InvalidateRect(hProcessPageEndProcessButton
, NULL
, TRUE
);
149 GetClientRect(hProcessPageShowAllProcessesButton
, &rc
);
150 MapWindowPoints(hProcessPageShowAllProcessesButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), (sizeof(RECT
)/sizeof(POINT
)) );
152 cy
= rc
.top
+ nYDifference
;
153 SetWindowPos(hProcessPageShowAllProcessesButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
154 InvalidateRect(hProcessPageShowAllProcessesButton
, NULL
, TRUE
);
160 ProcessPageOnNotify(wParam
, lParam
);
167 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
)
177 LPPROCESS_PAGE_LIST_ITEM pData
;
179 idctrl
= (int) wParam
;
180 pnmh
= (LPNMHDR
) lParam
;
181 pnmv
= (LPNMLISTVIEW
) lParam
;
182 pnmdi
= (NMLVDISPINFO
*) lParam
;
183 pnmhdr
= (LPNMHEADER
) lParam
;
185 if (pnmh
->hwndFrom
== hProcessPageListCtrl
)
190 case LVN_ITEMCHANGED
:
195 case LVN_GETDISPINFO
:
197 if (!(pnmdi
->item
.mask
& LVIF_TEXT
))
200 pData
= (LPPROCESS_PAGE_LIST_ITEM
)pnmdi
->item
.lParam
;
201 Index
= pData
->Index
;
202 ColumnIndex
= pnmdi
->item
.iSubItem
;
204 PerfDataGetText(Index
, ColumnIndex
, pnmdi
->item
.pszText
, pnmdi
->item
.cchTextMax
);
210 for (Index
=0; Index
<(ULONG
)ListView_GetItemCount(hProcessPageListCtrl
); Index
++)
212 memset(&lvitem
, 0, sizeof(LVITEM
));
214 lvitem
.mask
= LVIF_STATE
;
215 lvitem
.stateMask
= LVIS_SELECTED
;
216 lvitem
.iItem
= Index
;
218 (void)ListView_GetItem(hProcessPageListCtrl
, &lvitem
);
220 if (lvitem
.state
& LVIS_SELECTED
)
224 if ((ListView_GetSelectedCount(hProcessPageListCtrl
) == 1) &&
225 (PerfDataGetProcessId(Index
) != 0))
227 ProcessPageShowContextMenu(PerfDataGetProcessId(Index
));
234 else if (pnmh
->hwndFrom
== hProcessPageHeaderCtrl
)
240 ProcessSortColumnIndex
= pnmhdr
->iItem
;
241 bProcessSortAscending
= !bProcessSortAscending
;
242 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
247 case HDN_ITEMCHANGED
:
249 UpdateColumnDataHints();
255 UpdateColumnDataHints();
263 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
)
268 for (i
=0,j
=0; i
<(wcslen(strNumber
) % 3); i
++, j
++)
269 temp
[j
] = strNumber
[i
];
270 for (k
=0; i
<wcslen(strNumber
); i
++,j
++,k
++) {
271 if ((k
% 3 == 0) && (j
> 0))
273 temp
[j
] = strNumber
[i
];
276 wcsncpy(strNumber
, temp
, nMaxCount
);
279 void ProcessPageShowContextMenu(DWORD dwProcessId
)
287 DWORD dwProcessPriorityClass
;
288 WCHAR strDebugger
[260];
289 DWORD dwDebuggerSize
;
292 memset(&si
, 0, sizeof(SYSTEM_INFO
));
297 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_PROCESS_PAGE_CONTEXT
));
298 hSubMenu
= GetSubMenu(hMenu
, 0);
299 hPriorityMenu
= GetSubMenu(hSubMenu
, 4);
301 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dwProcessId
);
302 dwProcessPriorityClass
= GetPriorityClass(hProcess
);
303 CloseHandle(hProcess
);
305 if (si
.dwNumberOfProcessors
< 2)
306 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_SETAFFINITY
, MF_BYCOMMAND
);
308 if (!DebugChannelsAreSupported())
309 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_DEBUGCHANNELS
, MF_BYCOMMAND
);
311 switch (dwProcessPriorityClass
) {
312 case REALTIME_PRIORITY_CLASS
:
313 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, MF_BYCOMMAND
);
315 case HIGH_PRIORITY_CLASS
:
316 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_HIGH
, MF_BYCOMMAND
);
318 case ABOVE_NORMAL_PRIORITY_CLASS
:
319 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
, MF_BYCOMMAND
);
321 case NORMAL_PRIORITY_CLASS
:
322 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_NORMAL
, MF_BYCOMMAND
);
324 case BELOW_NORMAL_PRIORITY_CLASS
:
325 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
, MF_BYCOMMAND
);
327 case IDLE_PRIORITY_CLASS
:
328 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, MF_BYCOMMAND
);
332 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
334 dwDebuggerSize
= 260;
335 if (RegQueryValueExW(hKey
, L
"Debugger", NULL
, NULL
, (LPBYTE
)strDebugger
, &dwDebuggerSize
) == ERROR_SUCCESS
)
337 CharUpper(strDebugger
);
338 if (wcsstr(strDebugger
, L
"DRWTSN32"))
339 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
342 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
346 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
348 TrackPopupMenu(hSubMenu
, TPM_LEFTALIGN
|TPM_TOPALIGN
|TPM_LEFTBUTTON
, pt
.x
, pt
.y
, 0, hMainWnd
, NULL
);
352 void RefreshProcessPage(void)
354 /* Signal the event so that our refresh thread */
355 /* will wake up and refresh the process page */
356 SetEvent(hProcessPageEvent
);
359 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
)
361 ULONG OldProcessorUsage
= 0;
362 ULONG OldProcessCount
= 0;
363 WCHAR szCpuUsage
[256], szProcesses
[256];
365 /* Create the event */
366 hProcessPageEvent
= CreateEventW(NULL
, TRUE
, TRUE
, NULL
);
368 /* If we couldn't create the event then exit the thread */
369 if (!hProcessPageEvent
)
372 LoadStringW(hInst
, IDS_STATUS_CPUUSAGE
, szCpuUsage
, 256);
373 LoadStringW(hInst
, IDS_STATUS_PROCESSES
, szProcesses
, 256);
378 /* Wait on the event */
379 dwWaitVal
= WaitForSingleObject(hProcessPageEvent
, INFINITE
);
381 /* If the wait failed then the event object must have been */
382 /* closed and the task manager is exiting so exit this thread */
383 if (dwWaitVal
== WAIT_FAILED
)
386 if (dwWaitVal
== WAIT_OBJECT_0
) {
389 /* Reset our event */
390 ResetEvent(hProcessPageEvent
);
394 if (IsWindowVisible(hProcessPage
))
395 InvalidateRect(hProcessPageListCtrl
, NULL
, FALSE
);
397 if (OldProcessorUsage
!= PerfDataGetProcessorUsage()) {
398 OldProcessorUsage
= PerfDataGetProcessorUsage();
399 wsprintfW(text
, szCpuUsage
, OldProcessorUsage
);
400 SendMessageW(hStatusWnd
, SB_SETTEXT
, 1, (LPARAM
)text
);
402 if (OldProcessCount
!= PerfDataGetProcessCount()) {
403 OldProcessCount
= PerfDataGetProcessCount();
404 wsprintfW(text
, szProcesses
, OldProcessCount
);
405 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)text
);
412 void UpdateProcesses()
419 LPPROCESS_PAGE_LIST_ITEM pData
;
422 /* Remove old processes */
423 for (i
= 0; i
< ListView_GetItemCount(hProcessPageListCtrl
); i
++)
425 memset(&item
, 0, sizeof (LV_ITEM
));
426 item
.mask
= LVIF_PARAM
;
428 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
429 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
430 (void)PerfDataGet(pData
->Index
, &pPerfData
);
431 pid
= PerfDataGetProcessId(pData
->Index
);
432 for (l
= 0; l
< PerfDataGetProcessCount(); l
++)
434 if (PerfDataGetProcessId(l
) == pid
)
442 (void)ListView_DeleteItem(hApplicationPageListCtrl
, i
);
443 HeapFree(GetProcessHeap(), 0, pData
);
446 for (l
= 0; l
< PerfDataGetProcessCount(); l
++)
452 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
456 void AddProcess(ULONG Index
)
458 LPPROCESS_PAGE_LIST_ITEM pData
;
461 BOOL bAlreadyInList
= FALSE
;
464 pid
= PerfDataGetProcessId(Index
);
466 /* Check to see if it's already in our list */
467 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
469 memset(&item
, 0, sizeof(LV_ITEM
));
470 item
.mask
= LVIF_PARAM
;
472 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
473 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
474 if (PerfDataGetProcessId(pData
->Index
) == pid
)
476 bAlreadyInList
= TRUE
;
480 if (!bAlreadyInList
) /* Add */
482 pData
= (LPPROCESS_PAGE_LIST_ITEM
)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM
));
483 pData
->Index
= Index
;
485 /* Add the item to the list */
486 memset(&item
, 0, sizeof(LV_ITEM
));
487 item
.mask
= LVIF_TEXT
|LVIF_PARAM
;
488 item
.pszText
= LPSTR_TEXTCALLBACK
;
489 item
.iItem
= ListView_GetItemCount(hProcessPageListCtrl
);
490 item
.lParam
= (LPARAM
)pData
;
491 (void)ListView_InsertItem(hProcessPageListCtrl
, &item
);
495 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
)
497 IO_COUNTERS iocounters
;
500 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IMAGENAME
)
501 PerfDataGetImageName(Index
, lpText
, nMaxCount
);
502 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PID
)
503 wsprintfW(lpText
, L
"%d", PerfDataGetProcessId(Index
));
504 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USERNAME
)
505 PerfDataGetUserName(Index
, lpText
, nMaxCount
);
506 if (ColumnDataHints
[ColumnIndex
] == COLUMN_SESSIONID
)
507 wsprintfW(lpText
, L
"%d", PerfDataGetSessionId(Index
));
508 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUUSAGE
)
509 wsprintfW(lpText
, L
"%02d", PerfDataGetCPUUsage(Index
));
510 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUTIME
)
516 time
= PerfDataGetCPUTime(Index
);
517 gethmsfromlargeint(time
, &dwHours
, &dwMinutes
, &dwSeconds
);
518 wsprintfW(lpText
, L
"%d:%02d:%02d", dwHours
, dwMinutes
, dwSeconds
);
520 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGE
)
522 wsprintfW(lpText
, L
"%d", PerfDataGetWorkingSetSizeBytes(Index
) / 1024);
523 CommaSeparateNumberString(lpText
, nMaxCount
);
524 wcscat(lpText
, L
" K");
526 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PEAKMEMORYUSAGE
)
528 wsprintfW(lpText
, L
"%d", PerfDataGetPeakWorkingSetSizeBytes(Index
) / 1024);
529 CommaSeparateNumberString(lpText
, nMaxCount
);
530 wcscat(lpText
, L
" K");
532 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGEDELTA
)
534 wsprintfW(lpText
, L
"%d", PerfDataGetWorkingSetSizeDelta(Index
) / 1024);
535 CommaSeparateNumberString(lpText
, nMaxCount
);
536 wcscat(lpText
, L
" K");
538 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTS
)
540 wsprintfW(lpText
, L
"%d", PerfDataGetPageFaultCount(Index
));
541 CommaSeparateNumberString(lpText
, nMaxCount
);
543 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTSDELTA
)
545 wsprintfW(lpText
, L
"%d", PerfDataGetPageFaultCountDelta(Index
));
546 CommaSeparateNumberString(lpText
, nMaxCount
);
548 if (ColumnDataHints
[ColumnIndex
] == COLUMN_VIRTUALMEMORYSIZE
)
550 wsprintfW(lpText
, L
"%d", PerfDataGetVirtualMemorySizeBytes(Index
) / 1024);
551 CommaSeparateNumberString(lpText
, nMaxCount
);
552 wcscat(lpText
, L
" K");
554 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEDPOOL
)
556 wsprintfW(lpText
, L
"%d", PerfDataGetPagedPoolUsagePages(Index
) / 1024);
557 CommaSeparateNumberString(lpText
, nMaxCount
);
558 wcscat(lpText
, L
" K");
560 if (ColumnDataHints
[ColumnIndex
] == COLUMN_NONPAGEDPOOL
)
562 wsprintfW(lpText
, L
"%d", PerfDataGetNonPagedPoolUsagePages(Index
) / 1024);
563 CommaSeparateNumberString(lpText
, nMaxCount
);
564 wcscat(lpText
, L
" K");
566 if (ColumnDataHints
[ColumnIndex
] == COLUMN_BASEPRIORITY
)
567 wsprintfW(lpText
, L
"%d", PerfDataGetBasePriority(Index
));
568 if (ColumnDataHints
[ColumnIndex
] == COLUMN_HANDLECOUNT
)
570 wsprintfW(lpText
, L
"%d", PerfDataGetHandleCount(Index
));
571 CommaSeparateNumberString(lpText
, nMaxCount
);
573 if (ColumnDataHints
[ColumnIndex
] == COLUMN_THREADCOUNT
)
575 wsprintfW(lpText
, L
"%d", PerfDataGetThreadCount(Index
));
576 CommaSeparateNumberString(lpText
, nMaxCount
);
578 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USEROBJECTS
)
580 wsprintfW(lpText
, L
"%d", PerfDataGetUSERObjectCount(Index
));
581 CommaSeparateNumberString(lpText
, nMaxCount
);
583 if (ColumnDataHints
[ColumnIndex
] == COLUMN_GDIOBJECTS
)
585 wsprintfW(lpText
, L
"%d", PerfDataGetGDIObjectCount(Index
));
586 CommaSeparateNumberString(lpText
, nMaxCount
);
588 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADS
)
590 PerfDataGetIOCounters(Index
, &iocounters
);
591 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadOperationCount); */
592 _ui64tow(iocounters
.ReadOperationCount
, lpText
, 10);
593 CommaSeparateNumberString(lpText
, nMaxCount
);
595 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITES
)
597 PerfDataGetIOCounters(Index
, &iocounters
);
598 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteOperationCount); */
599 _ui64tow(iocounters
.WriteOperationCount
, lpText
, 10);
600 CommaSeparateNumberString(lpText
, nMaxCount
);
602 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHER
)
604 PerfDataGetIOCounters(Index
, &iocounters
);
605 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherOperationCount); */
606 _ui64tow(iocounters
.OtherOperationCount
, lpText
, 10);
607 CommaSeparateNumberString(lpText
, nMaxCount
);
609 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADBYTES
)
611 PerfDataGetIOCounters(Index
, &iocounters
);
612 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadTransferCount); */
613 _ui64tow(iocounters
.ReadTransferCount
, lpText
, 10);
614 CommaSeparateNumberString(lpText
, nMaxCount
);
616 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITEBYTES
)
618 PerfDataGetIOCounters(Index
, &iocounters
);
619 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteTransferCount); */
620 _ui64tow(iocounters
.WriteTransferCount
, lpText
, 10);
621 CommaSeparateNumberString(lpText
, nMaxCount
);
623 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHERBYTES
)
625 PerfDataGetIOCounters(Index
, &iocounters
);
626 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherTransferCount); */
627 _ui64tow(iocounters
.OtherTransferCount
, lpText
, 10);
628 CommaSeparateNumberString(lpText
, nMaxCount
);
635 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
)
638 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000L);
639 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000L) / 600000000L);
640 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000L) % 600000000L) / 10000000L);
642 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000LL);
643 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000LL) / 600000000LL);
644 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000LL) % 600000000LL) / 10000000LL);
648 int largeintcmp(LARGE_INTEGER l1
, LARGE_INTEGER l2
)
658 gethmsfromlargeint(l1
, &dwHours1
, &dwMinutes1
, &dwSeconds1
);
659 gethmsfromlargeint(l2
, &dwHours2
, &dwMinutes2
, &dwSeconds2
);
660 ret
= CMP(dwHours1
, dwHours2
);
663 ret
= CMP(dwMinutes1
, dwMinutes2
);
666 ret
= CMP(dwSeconds1
, dwSeconds2
);
672 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
675 LPPROCESS_PAGE_LIST_ITEM Param1
;
676 LPPROCESS_PAGE_LIST_ITEM Param2
;
684 IO_COUNTERS iocounters1
;
685 IO_COUNTERS iocounters2
;
689 if (bProcessSortAscending
) {
690 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
691 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
693 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
694 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
696 ColumnIndex
= ProcessSortColumnIndex
;
698 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IMAGENAME
)
700 PerfDataGetImageName(Param1
->Index
, text1
, sizeof (text1
) / sizeof (*text1
));
701 PerfDataGetImageName(Param2
->Index
, text2
, sizeof (text2
) / sizeof (*text2
));
702 ret
= _wcsicmp(text1
, text2
);
704 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_PID
)
706 l1
= PerfDataGetProcessId(Param1
->Index
);
707 l2
= PerfDataGetProcessId(Param2
->Index
);
710 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_USERNAME
)
712 PerfDataGetUserName(Param1
->Index
, text1
, sizeof (text1
) / sizeof (*text1
));
713 PerfDataGetUserName(Param2
->Index
, text2
, sizeof (text2
) / sizeof (*text2
));
714 ret
= _wcsicmp(text1
, text2
);
716 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_SESSIONID
)
718 l1
= PerfDataGetSessionId(Param1
->Index
);
719 l2
= PerfDataGetSessionId(Param2
->Index
);
722 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUUSAGE
)
724 l1
= PerfDataGetCPUUsage(Param1
->Index
);
725 l2
= PerfDataGetCPUUsage(Param2
->Index
);
728 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUTIME
)
730 time1
= PerfDataGetCPUTime(Param1
->Index
);
731 time2
= PerfDataGetCPUTime(Param2
->Index
);
732 ret
= largeintcmp(time1
, time2
);
734 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGE
)
736 l1
= PerfDataGetWorkingSetSizeBytes(Param1
->Index
);
737 l2
= PerfDataGetWorkingSetSizeBytes(Param2
->Index
);
740 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_PEAKMEMORYUSAGE
)
742 l1
= PerfDataGetPeakWorkingSetSizeBytes(Param1
->Index
);
743 l2
= PerfDataGetPeakWorkingSetSizeBytes(Param2
->Index
);
746 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGEDELTA
)
748 l1
= PerfDataGetWorkingSetSizeDelta(Param1
->Index
);
749 l2
= PerfDataGetWorkingSetSizeDelta(Param2
->Index
);
752 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTS
)
754 l1
= PerfDataGetPageFaultCount(Param1
->Index
);
755 l2
= PerfDataGetPageFaultCount(Param2
->Index
);
758 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTSDELTA
)
760 l1
= PerfDataGetPageFaultCountDelta(Param1
->Index
);
761 l2
= PerfDataGetPageFaultCountDelta(Param2
->Index
);
764 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_VIRTUALMEMORYSIZE
)
766 l1
= PerfDataGetVirtualMemorySizeBytes(Param1
->Index
);
767 l2
= PerfDataGetVirtualMemorySizeBytes(Param2
->Index
);
770 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEDPOOL
)
772 l1
= PerfDataGetPagedPoolUsagePages(Param1
->Index
);
773 l2
= PerfDataGetPagedPoolUsagePages(Param2
->Index
);
776 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_NONPAGEDPOOL
)
778 l1
= PerfDataGetNonPagedPoolUsagePages(Param1
->Index
);
779 l2
= PerfDataGetNonPagedPoolUsagePages(Param2
->Index
);
782 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_BASEPRIORITY
)
784 l1
= PerfDataGetBasePriority(Param1
->Index
);
785 l2
= PerfDataGetBasePriority(Param2
->Index
);
788 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_HANDLECOUNT
)
790 l1
= PerfDataGetHandleCount(Param1
->Index
);
791 l2
= PerfDataGetHandleCount(Param2
->Index
);
794 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_THREADCOUNT
)
796 l1
= PerfDataGetThreadCount(Param1
->Index
);
797 l2
= PerfDataGetThreadCount(Param2
->Index
);
800 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_USEROBJECTS
)
802 l1
= PerfDataGetUSERObjectCount(Param1
->Index
);
803 l2
= PerfDataGetUSERObjectCount(Param2
->Index
);
806 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_GDIOBJECTS
)
808 l1
= PerfDataGetGDIObjectCount(Param1
->Index
);
809 l2
= PerfDataGetGDIObjectCount(Param2
->Index
);
812 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADS
)
814 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
815 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
816 ull1
= iocounters1
.ReadOperationCount
;
817 ull2
= iocounters2
.ReadOperationCount
;
818 ret
= CMP(ull1
, ull2
);
820 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITES
)
822 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
823 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
824 ull1
= iocounters1
.WriteOperationCount
;
825 ull2
= iocounters2
.WriteOperationCount
;
826 ret
= CMP(ull1
, ull2
);
828 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHER
)
830 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
831 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
832 ull1
= iocounters1
.OtherOperationCount
;
833 ull2
= iocounters2
.OtherOperationCount
;
834 ret
= CMP(ull1
, ull2
);
836 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADBYTES
)
838 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
839 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
840 ull1
= iocounters1
.ReadTransferCount
;
841 ull2
= iocounters2
.ReadTransferCount
;
842 ret
= CMP(ull1
, ull2
);
844 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITEBYTES
)
846 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
847 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
848 ull1
= iocounters1
.WriteTransferCount
;
849 ull2
= iocounters2
.WriteTransferCount
;
850 ret
= CMP(ull1
, ull2
);
852 else if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHERBYTES
)
854 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
855 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
856 ull1
= iocounters1
.OtherTransferCount
;
857 ull2
= iocounters2
.OtherTransferCount
;
858 ret
= CMP(ull1
, ull2
);