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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 (x1 < x2 ? -1 : (x1 > x2 ? 1 : 0))
33 } PROCESS_PAGE_LIST_ITEM
, *LPPROCESS_PAGE_LIST_ITEM
;
35 HWND hProcessPage
; /* Process List Property Page */
37 HWND hProcessPageListCtrl
; /* Process ListCtrl Window */
38 HWND hProcessPageHeaderCtrl
; /* Process Header Control */
39 HWND hProcessPageEndProcessButton
; /* Process End Process button */
40 HWND hProcessPageShowAllProcessesButton
;/* Process Show All Processes checkbox */
42 static int nProcessPageWidth
;
43 static int nProcessPageHeight
;
44 static HANDLE hProcessPageEvent
= NULL
; /* When this event becomes signaled then we refresh the process list */
46 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
);
47 void AddProcess(ULONG Index
);
48 void UpdateProcesses();
49 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
);
50 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
);
51 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
);
52 void ProcessPageShowContextMenu(DWORD dwProcessId
);
53 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
);
54 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
);
55 int ProcessRunning(ULONG ProcessId
);
57 DWORD
GetSelectedProcessId(void)
62 if(ListView_GetSelectedCount(hProcessPageListCtrl
) == 1)
64 Index
= ListView_GetSelectionMark(hProcessPageListCtrl
);
66 memset(&lvitem
, 0, sizeof(LVITEM
));
68 lvitem
.mask
= LVIF_PARAM
;
71 (void)ListView_GetItem(hProcessPageListCtrl
, &lvitem
);
74 return PerfDataGetProcessId(((LPPROCESS_PAGE_LIST_ITEM
)lvitem
.lParam
)->Index
);
81 ProcessPageWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
87 HANDLE hRefreshThread
= NULL
;
92 * Save the width and height
94 GetClientRect(hDlg
, &rc
);
95 nProcessPageWidth
= rc
.right
;
96 nProcessPageHeight
= rc
.bottom
;
98 /* Update window position */
99 SetWindowPos(hDlg
, NULL
, 15, 30, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
102 * Get handles to the controls
104 hProcessPageListCtrl
= GetDlgItem(hDlg
, IDC_PROCESSLIST
);
105 hProcessPageHeaderCtrl
= ListView_GetHeader(hProcessPageListCtrl
);
106 hProcessPageEndProcessButton
= GetDlgItem(hDlg
, IDC_ENDPROCESS
);
107 hProcessPageShowAllProcessesButton
= GetDlgItem(hDlg
, IDC_SHOWALLPROCESSES
);
110 * Set the title, and extended window styles for the list control
112 SetWindowTextW(hProcessPageListCtrl
, L
"Processes");
113 (void)ListView_SetExtendedListViewStyle(hProcessPageListCtrl
, ListView_GetExtendedListViewStyle(hProcessPageListCtrl
) | LVS_EX_FULLROWSELECT
| LVS_EX_HEADERDRAGDROP
);
118 * Subclass the process list control so we can intercept WM_ERASEBKGND
120 OldProcessListWndProc
= (WNDPROC
)(LONG_PTR
) SetWindowLongPtrW(hProcessPageListCtrl
, GWL_WNDPROC
, (LONG_PTR
)ProcessListWndProc
);
122 /* Start our refresh thread */
123 hRefreshThread
= CreateThread(NULL
, 0, ProcessPageRefreshThread
, NULL
, 0, NULL
);
128 /* Close the event handle, this will make the */
129 /* refresh thread exit when the wait fails */
130 CloseHandle(hProcessPageEvent
);
131 CloseHandle(hRefreshThread
);
133 SaveColumnSettings();
138 /* Handle the button clicks */
139 switch (LOWORD(wParam
))
142 ProcessPage_OnEndProcess();
147 if (wParam
== SIZE_MINIMIZED
)
152 nXDifference
= cx
- nProcessPageWidth
;
153 nYDifference
= cy
- nProcessPageHeight
;
154 nProcessPageWidth
= cx
;
155 nProcessPageHeight
= cy
;
157 /* Reposition the application page's controls */
158 GetWindowRect(hProcessPageListCtrl
, &rc
);
159 cx
= (rc
.right
- rc
.left
) + nXDifference
;
160 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
161 SetWindowPos(hProcessPageListCtrl
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
162 InvalidateRect(hProcessPageListCtrl
, NULL
, TRUE
);
164 GetClientRect(hProcessPageEndProcessButton
, &rc
);
165 MapWindowPoints(hProcessPageEndProcessButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), (sizeof(RECT
)/sizeof(POINT
)) );
166 cx
= rc
.left
+ nXDifference
;
167 cy
= rc
.top
+ nYDifference
;
168 SetWindowPos(hProcessPageEndProcessButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
169 InvalidateRect(hProcessPageEndProcessButton
, NULL
, TRUE
);
171 GetClientRect(hProcessPageShowAllProcessesButton
, &rc
);
172 MapWindowPoints(hProcessPageShowAllProcessesButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), (sizeof(RECT
)/sizeof(POINT
)) );
174 cy
= rc
.top
+ nYDifference
;
175 SetWindowPos(hProcessPageShowAllProcessesButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
176 InvalidateRect(hProcessPageShowAllProcessesButton
, NULL
, TRUE
);
182 ProcessPageOnNotify(wParam
, lParam
);
189 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
)
198 LPPROCESS_PAGE_LIST_ITEM pData
;
200 idctrl
= (int) wParam
;
201 pnmh
= (LPNMHDR
) lParam
;
202 pnmv
= (LPNMLISTVIEW
) lParam
;
203 pnmdi
= (NMLVDISPINFO
*) lParam
;
204 pnmhdr
= (LPNMHEADER
) lParam
;
206 if (pnmh
->hwndFrom
== hProcessPageListCtrl
)
211 case LVN_ITEMCHANGED
:
216 case LVN_GETDISPINFO
:
218 if (!(pnmdi
->item
.mask
& LVIF_TEXT
))
221 pData
= (LPPROCESS_PAGE_LIST_ITEM
)pnmdi
->item
.lParam
;
222 Index
= pData
->Index
;
223 ColumnIndex
= pnmdi
->item
.iSubItem
;
225 PerfDataGetText(Index
, ColumnIndex
, pnmdi
->item
.pszText
, pnmdi
->item
.cchTextMax
);
231 ProcessPageShowContextMenu(GetSelectedProcessId());
236 else if (pnmh
->hwndFrom
== hProcessPageHeaderCtrl
)
242 TaskManagerSettings
.SortColumn
= ColumnDataHints
[pnmhdr
->iItem
];
243 TaskManagerSettings
.SortAscending
= !TaskManagerSettings
.SortAscending
;
244 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
248 case HDN_ITEMCHANGED
:
250 UpdateColumnDataHints();
256 UpdateColumnDataHints();
264 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
)
269 for (i
=0,j
=0; i
<(wcslen(strNumber
) % 3); i
++, j
++)
270 temp
[j
] = strNumber
[i
];
271 for (k
=0; i
<wcslen(strNumber
); i
++,j
++,k
++) {
272 if ((k
% 3 == 0) && (j
> 0))
274 temp
[j
] = strNumber
[i
];
277 wcsncpy(strNumber
, temp
, nMaxCount
);
280 void ProcessPageShowContextMenu(DWORD dwProcessId
)
288 DWORD dwProcessPriorityClass
;
289 WCHAR strDebugger
[260];
290 DWORD dwDebuggerSize
;
293 memset(&si
, 0, sizeof(SYSTEM_INFO
));
298 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_PROCESS_PAGE_CONTEXT
));
299 hSubMenu
= GetSubMenu(hMenu
, 0);
300 hPriorityMenu
= GetSubMenu(hSubMenu
, 4);
302 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dwProcessId
);
303 dwProcessPriorityClass
= GetPriorityClass(hProcess
);
304 CloseHandle(hProcess
);
306 if (si
.dwNumberOfProcessors
< 2)
307 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_SETAFFINITY
, MF_BYCOMMAND
);
309 if (!DebugChannelsAreSupported())
310 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_DEBUGCHANNELS
, MF_BYCOMMAND
);
312 switch (dwProcessPriorityClass
) {
313 case REALTIME_PRIORITY_CLASS
:
314 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, MF_BYCOMMAND
);
316 case HIGH_PRIORITY_CLASS
:
317 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_HIGH
, MF_BYCOMMAND
);
319 case ABOVE_NORMAL_PRIORITY_CLASS
:
320 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
, MF_BYCOMMAND
);
322 case NORMAL_PRIORITY_CLASS
:
323 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_NORMAL
, MF_BYCOMMAND
);
325 case BELOW_NORMAL_PRIORITY_CLASS
:
326 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
, MF_BYCOMMAND
);
328 case IDLE_PRIORITY_CLASS
:
329 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, MF_BYCOMMAND
);
333 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
335 dwDebuggerSize
= 260;
336 if (RegQueryValueExW(hKey
, L
"Debugger", NULL
, NULL
, (LPBYTE
)strDebugger
, &dwDebuggerSize
) == ERROR_SUCCESS
)
338 CharUpper(strDebugger
);
339 if (wcsstr(strDebugger
, L
"DRWTSN32"))
340 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
343 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
347 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
349 TrackPopupMenu(hSubMenu
, TPM_LEFTALIGN
|TPM_TOPALIGN
|TPM_LEFTBUTTON
, pt
.x
, pt
.y
, 0, hMainWnd
, NULL
);
353 void RefreshProcessPage(void)
355 /* Signal the event so that our refresh thread */
356 /* will wake up and refresh the process page */
357 SetEvent(hProcessPageEvent
);
360 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
)
362 ULONG OldProcessorUsage
= 0;
363 ULONG OldProcessCount
= 0;
364 WCHAR szCpuUsage
[256], szProcesses
[256];
366 /* Create the event */
367 hProcessPageEvent
= CreateEventW(NULL
, TRUE
, TRUE
, NULL
);
369 /* If we couldn't create the event then exit the thread */
370 if (!hProcessPageEvent
)
373 LoadStringW(hInst
, IDS_STATUS_CPUUSAGE
, szCpuUsage
, 256);
374 LoadStringW(hInst
, IDS_STATUS_PROCESSES
, szProcesses
, 256);
379 /* Wait on the event */
380 dwWaitVal
= WaitForSingleObject(hProcessPageEvent
, INFINITE
);
382 /* If the wait failed then the event object must have been */
383 /* closed and the task manager is exiting so exit this thread */
384 if (dwWaitVal
== WAIT_FAILED
)
387 if (dwWaitVal
== WAIT_OBJECT_0
) {
390 /* Reset our event */
391 ResetEvent(hProcessPageEvent
);
395 if (IsWindowVisible(hProcessPage
))
396 InvalidateRect(hProcessPageListCtrl
, NULL
, FALSE
);
398 if (OldProcessorUsage
!= PerfDataGetProcessorUsage()) {
399 OldProcessorUsage
= PerfDataGetProcessorUsage();
400 wsprintfW(text
, szCpuUsage
, OldProcessorUsage
);
401 SendMessageW(hStatusWnd
, SB_SETTEXT
, 1, (LPARAM
)text
);
403 if (OldProcessCount
!= PerfDataGetProcessCount()) {
404 OldProcessCount
= PerfDataGetProcessCount();
405 wsprintfW(text
, szProcesses
, OldProcessCount
);
406 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)text
);
413 void UpdateProcesses()
418 LPPROCESS_PAGE_LIST_ITEM pData
;
420 /* Remove old processes */
421 for (i
= 0; i
< ListView_GetItemCount(hProcessPageListCtrl
); i
++)
423 memset(&item
, 0, sizeof (LV_ITEM
));
424 item
.mask
= LVIF_PARAM
;
426 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
427 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
428 if (!ProcessRunning(pData
->ProcessId
))
430 (void)ListView_DeleteItem(hProcessPageListCtrl
, i
);
431 HeapFree(GetProcessHeap(), 0, pData
);
434 for (l
= 0; l
< PerfDataGetProcessCount(); l
++)
438 if (TaskManagerSettings
.SortColumn
!= -1)
440 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
444 BOOL
ProcessRunning(ULONG ProcessId
)
449 if (ProcessId
== 0) {
453 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, ProcessId
);
454 if (hProcess
== NULL
) {
458 if (GetExitCodeProcess(hProcess
, &exitCode
)) {
459 CloseHandle(hProcess
);
460 return (exitCode
== STILL_ACTIVE
);
463 CloseHandle(hProcess
);
467 void AddProcess(ULONG Index
)
469 LPPROCESS_PAGE_LIST_ITEM pData
;
472 BOOL bAlreadyInList
= FALSE
;
475 pid
= PerfDataGetProcessId(Index
);
477 /* Check to see if it's already in our list */
478 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
480 memset(&item
, 0, sizeof(LV_ITEM
));
481 item
.mask
= LVIF_PARAM
;
483 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
484 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
485 if (PerfDataGetProcessId(pData
->Index
) == pid
)
487 bAlreadyInList
= TRUE
;
491 if (!bAlreadyInList
) /* Add */
493 pData
= (LPPROCESS_PAGE_LIST_ITEM
)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM
));
494 pData
->Index
= Index
;
495 pData
->ProcessId
= pid
;
497 /* Add the item to the list */
498 memset(&item
, 0, sizeof(LV_ITEM
));
499 item
.mask
= LVIF_TEXT
|LVIF_PARAM
;
500 item
.pszText
= LPSTR_TEXTCALLBACK
;
501 item
.iItem
= ListView_GetItemCount(hProcessPageListCtrl
);
502 item
.lParam
= (LPARAM
)pData
;
503 (void)ListView_InsertItem(hProcessPageListCtrl
, &item
);
507 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
)
509 IO_COUNTERS iocounters
;
512 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IMAGENAME
)
513 PerfDataGetImageName(Index
, lpText
, nMaxCount
);
514 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PID
)
515 wsprintfW(lpText
, L
"%d", PerfDataGetProcessId(Index
));
516 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USERNAME
)
517 PerfDataGetUserName(Index
, lpText
, nMaxCount
);
518 if (ColumnDataHints
[ColumnIndex
] == COLUMN_SESSIONID
)
519 wsprintfW(lpText
, L
"%d", PerfDataGetSessionId(Index
));
520 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUUSAGE
)
521 wsprintfW(lpText
, L
"%02d", PerfDataGetCPUUsage(Index
));
522 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUTIME
)
528 time
= PerfDataGetCPUTime(Index
);
529 gethmsfromlargeint(time
, &dwHours
, &dwMinutes
, &dwSeconds
);
530 wsprintfW(lpText
, L
"%d:%02d:%02d", dwHours
, dwMinutes
, dwSeconds
);
532 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGE
)
534 wsprintfW(lpText
, L
"%d", PerfDataGetWorkingSetSizeBytes(Index
) / 1024);
535 CommaSeparateNumberString(lpText
, nMaxCount
);
536 wcscat(lpText
, L
" K");
538 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PEAKMEMORYUSAGE
)
540 wsprintfW(lpText
, L
"%d", PerfDataGetPeakWorkingSetSizeBytes(Index
) / 1024);
541 CommaSeparateNumberString(lpText
, nMaxCount
);
542 wcscat(lpText
, L
" K");
544 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGEDELTA
)
546 wsprintfW(lpText
, L
"%d", PerfDataGetWorkingSetSizeDelta(Index
) / 1024);
547 CommaSeparateNumberString(lpText
, nMaxCount
);
548 wcscat(lpText
, L
" K");
550 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTS
)
552 wsprintfW(lpText
, L
"%d", PerfDataGetPageFaultCount(Index
));
553 CommaSeparateNumberString(lpText
, nMaxCount
);
555 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTSDELTA
)
557 wsprintfW(lpText
, L
"%d", PerfDataGetPageFaultCountDelta(Index
));
558 CommaSeparateNumberString(lpText
, nMaxCount
);
560 if (ColumnDataHints
[ColumnIndex
] == COLUMN_VIRTUALMEMORYSIZE
)
562 wsprintfW(lpText
, L
"%d", PerfDataGetVirtualMemorySizeBytes(Index
) / 1024);
563 CommaSeparateNumberString(lpText
, nMaxCount
);
564 wcscat(lpText
, L
" K");
566 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEDPOOL
)
568 wsprintfW(lpText
, L
"%d", PerfDataGetPagedPoolUsagePages(Index
) / 1024);
569 CommaSeparateNumberString(lpText
, nMaxCount
);
570 wcscat(lpText
, L
" K");
572 if (ColumnDataHints
[ColumnIndex
] == COLUMN_NONPAGEDPOOL
)
574 wsprintfW(lpText
, L
"%d", PerfDataGetNonPagedPoolUsagePages(Index
) / 1024);
575 CommaSeparateNumberString(lpText
, nMaxCount
);
576 wcscat(lpText
, L
" K");
578 if (ColumnDataHints
[ColumnIndex
] == COLUMN_BASEPRIORITY
)
579 wsprintfW(lpText
, L
"%d", PerfDataGetBasePriority(Index
));
580 if (ColumnDataHints
[ColumnIndex
] == COLUMN_HANDLECOUNT
)
582 wsprintfW(lpText
, L
"%d", PerfDataGetHandleCount(Index
));
583 CommaSeparateNumberString(lpText
, nMaxCount
);
585 if (ColumnDataHints
[ColumnIndex
] == COLUMN_THREADCOUNT
)
587 wsprintfW(lpText
, L
"%d", PerfDataGetThreadCount(Index
));
588 CommaSeparateNumberString(lpText
, nMaxCount
);
590 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USEROBJECTS
)
592 wsprintfW(lpText
, L
"%d", PerfDataGetUSERObjectCount(Index
));
593 CommaSeparateNumberString(lpText
, nMaxCount
);
595 if (ColumnDataHints
[ColumnIndex
] == COLUMN_GDIOBJECTS
)
597 wsprintfW(lpText
, L
"%d", PerfDataGetGDIObjectCount(Index
));
598 CommaSeparateNumberString(lpText
, nMaxCount
);
600 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADS
)
602 PerfDataGetIOCounters(Index
, &iocounters
);
603 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadOperationCount); */
604 _ui64tow(iocounters
.ReadOperationCount
, lpText
, 10);
605 CommaSeparateNumberString(lpText
, nMaxCount
);
607 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITES
)
609 PerfDataGetIOCounters(Index
, &iocounters
);
610 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteOperationCount); */
611 _ui64tow(iocounters
.WriteOperationCount
, lpText
, 10);
612 CommaSeparateNumberString(lpText
, nMaxCount
);
614 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHER
)
616 PerfDataGetIOCounters(Index
, &iocounters
);
617 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherOperationCount); */
618 _ui64tow(iocounters
.OtherOperationCount
, lpText
, 10);
619 CommaSeparateNumberString(lpText
, nMaxCount
);
621 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADBYTES
)
623 PerfDataGetIOCounters(Index
, &iocounters
);
624 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadTransferCount); */
625 _ui64tow(iocounters
.ReadTransferCount
, lpText
, 10);
626 CommaSeparateNumberString(lpText
, nMaxCount
);
628 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITEBYTES
)
630 PerfDataGetIOCounters(Index
, &iocounters
);
631 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteTransferCount); */
632 _ui64tow(iocounters
.WriteTransferCount
, lpText
, 10);
633 CommaSeparateNumberString(lpText
, nMaxCount
);
635 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHERBYTES
)
637 PerfDataGetIOCounters(Index
, &iocounters
);
638 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherTransferCount); */
639 _ui64tow(iocounters
.OtherTransferCount
, lpText
, 10);
640 CommaSeparateNumberString(lpText
, nMaxCount
);
647 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
)
650 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000L);
651 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000L) / 600000000L);
652 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000L) % 600000000L) / 10000000L);
654 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000LL);
655 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000LL) / 600000000LL);
656 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000LL) % 600000000LL) / 10000000LL);
660 int largeintcmp(LARGE_INTEGER l1
, LARGE_INTEGER l2
)
670 gethmsfromlargeint(l1
, &dwHours1
, &dwMinutes1
, &dwSeconds1
);
671 gethmsfromlargeint(l2
, &dwHours2
, &dwMinutes2
, &dwSeconds2
);
672 ret
= CMP(dwHours1
, dwHours2
);
675 ret
= CMP(dwMinutes1
, dwMinutes2
);
678 ret
= CMP(dwSeconds1
, dwSeconds2
);
684 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
687 LPPROCESS_PAGE_LIST_ITEM Param1
;
688 LPPROCESS_PAGE_LIST_ITEM Param2
;
695 IO_COUNTERS iocounters1
;
696 IO_COUNTERS iocounters2
;
700 if (TaskManagerSettings
.SortAscending
) {
701 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
702 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
704 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
705 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
708 if (TaskManagerSettings
.SortColumn
== COLUMN_IMAGENAME
)
710 PerfDataGetImageName(Param1
->Index
, text1
, sizeof (text1
) / sizeof (*text1
));
711 PerfDataGetImageName(Param2
->Index
, text2
, sizeof (text2
) / sizeof (*text2
));
712 ret
= _wcsicmp(text1
, text2
);
714 else if (TaskManagerSettings
.SortColumn
== COLUMN_PID
)
716 l1
= PerfDataGetProcessId(Param1
->Index
);
717 l2
= PerfDataGetProcessId(Param2
->Index
);
720 else if (TaskManagerSettings
.SortColumn
== COLUMN_USERNAME
)
722 PerfDataGetUserName(Param1
->Index
, text1
, sizeof (text1
) / sizeof (*text1
));
723 PerfDataGetUserName(Param2
->Index
, text2
, sizeof (text2
) / sizeof (*text2
));
724 ret
= _wcsicmp(text1
, text2
);
726 else if (TaskManagerSettings
.SortColumn
== COLUMN_SESSIONID
)
728 l1
= PerfDataGetSessionId(Param1
->Index
);
729 l2
= PerfDataGetSessionId(Param2
->Index
);
732 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUUSAGE
)
734 l1
= PerfDataGetCPUUsage(Param1
->Index
);
735 l2
= PerfDataGetCPUUsage(Param2
->Index
);
738 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUTIME
)
740 time1
= PerfDataGetCPUTime(Param1
->Index
);
741 time2
= PerfDataGetCPUTime(Param2
->Index
);
742 ret
= largeintcmp(time1
, time2
);
744 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGE
)
746 l1
= PerfDataGetWorkingSetSizeBytes(Param1
->Index
);
747 l2
= PerfDataGetWorkingSetSizeBytes(Param2
->Index
);
750 else if (TaskManagerSettings
.SortColumn
== COLUMN_PEAKMEMORYUSAGE
)
752 l1
= PerfDataGetPeakWorkingSetSizeBytes(Param1
->Index
);
753 l2
= PerfDataGetPeakWorkingSetSizeBytes(Param2
->Index
);
756 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGEDELTA
)
758 l1
= PerfDataGetWorkingSetSizeDelta(Param1
->Index
);
759 l2
= PerfDataGetWorkingSetSizeDelta(Param2
->Index
);
762 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTS
)
764 l1
= PerfDataGetPageFaultCount(Param1
->Index
);
765 l2
= PerfDataGetPageFaultCount(Param2
->Index
);
768 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTSDELTA
)
770 l1
= PerfDataGetPageFaultCountDelta(Param1
->Index
);
771 l2
= PerfDataGetPageFaultCountDelta(Param2
->Index
);
774 else if (TaskManagerSettings
.SortColumn
== COLUMN_VIRTUALMEMORYSIZE
)
776 l1
= PerfDataGetVirtualMemorySizeBytes(Param1
->Index
);
777 l2
= PerfDataGetVirtualMemorySizeBytes(Param2
->Index
);
780 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEDPOOL
)
782 l1
= PerfDataGetPagedPoolUsagePages(Param1
->Index
);
783 l2
= PerfDataGetPagedPoolUsagePages(Param2
->Index
);
786 else if (TaskManagerSettings
.SortColumn
== COLUMN_NONPAGEDPOOL
)
788 l1
= PerfDataGetNonPagedPoolUsagePages(Param1
->Index
);
789 l2
= PerfDataGetNonPagedPoolUsagePages(Param2
->Index
);
792 else if (TaskManagerSettings
.SortColumn
== COLUMN_BASEPRIORITY
)
794 l1
= PerfDataGetBasePriority(Param1
->Index
);
795 l2
= PerfDataGetBasePriority(Param2
->Index
);
798 else if (TaskManagerSettings
.SortColumn
== COLUMN_HANDLECOUNT
)
800 l1
= PerfDataGetHandleCount(Param1
->Index
);
801 l2
= PerfDataGetHandleCount(Param2
->Index
);
804 else if (TaskManagerSettings
.SortColumn
== COLUMN_THREADCOUNT
)
806 l1
= PerfDataGetThreadCount(Param1
->Index
);
807 l2
= PerfDataGetThreadCount(Param2
->Index
);
810 else if (TaskManagerSettings
.SortColumn
== COLUMN_USEROBJECTS
)
812 l1
= PerfDataGetUSERObjectCount(Param1
->Index
);
813 l2
= PerfDataGetUSERObjectCount(Param2
->Index
);
816 else if (TaskManagerSettings
.SortColumn
== COLUMN_GDIOBJECTS
)
818 l1
= PerfDataGetGDIObjectCount(Param1
->Index
);
819 l2
= PerfDataGetGDIObjectCount(Param2
->Index
);
822 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADS
)
824 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
825 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
826 ull1
= iocounters1
.ReadOperationCount
;
827 ull2
= iocounters2
.ReadOperationCount
;
828 ret
= CMP(ull1
, ull2
);
830 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITES
)
832 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
833 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
834 ull1
= iocounters1
.WriteOperationCount
;
835 ull2
= iocounters2
.WriteOperationCount
;
836 ret
= CMP(ull1
, ull2
);
838 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHER
)
840 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
841 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
842 ull1
= iocounters1
.OtherOperationCount
;
843 ull2
= iocounters2
.OtherOperationCount
;
844 ret
= CMP(ull1
, ull2
);
846 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADBYTES
)
848 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
849 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
850 ull1
= iocounters1
.ReadTransferCount
;
851 ull2
= iocounters2
.ReadTransferCount
;
852 ret
= CMP(ull1
, ull2
);
854 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITEBYTES
)
856 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
857 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
858 ull1
= iocounters1
.WriteTransferCount
;
859 ull2
= iocounters2
.WriteTransferCount
;
860 ret
= CMP(ull1
, ull2
);
862 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHERBYTES
)
864 PerfDataGetIOCounters(Param1
->Index
, &iocounters1
);
865 PerfDataGetIOCounters(Param2
->Index
, &iocounters2
);
866 ull1
= iocounters1
.OtherTransferCount
;
867 ull2
= iocounters2
.OtherTransferCount
;
868 ret
= CMP(ull1
, ull2
);