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
29 (x1 < x2 ? -1 : (x1 > x2 ? 1 : 0))
34 } PROCESS_PAGE_LIST_ITEM
, *LPPROCESS_PAGE_LIST_ITEM
;
36 HWND hProcessPage
; /* Process List Property Page */
38 HWND hProcessPageListCtrl
; /* Process ListCtrl Window */
39 HWND hProcessPageHeaderCtrl
; /* Process Header Control */
40 HWND hProcessPageEndProcessButton
; /* Process End Process button */
41 HWND hProcessPageShowAllProcessesButton
;/* Process Show All Processes checkbox */
43 static int nProcessPageWidth
;
44 static int nProcessPageHeight
;
46 static HANDLE hProcessThread
= NULL
;
47 static DWORD dwProcessThread
;
50 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
);
51 void AddProcess(ULONG Index
);
52 void UpdateProcesses();
53 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
);
54 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
);
55 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
);
56 void ProcessPageShowContextMenu(DWORD dwProcessId
);
57 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
);
58 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
);
59 int ProcessRunning(ULONG ProcessId
);
61 int ProcGetIndexByProcessId(DWORD dwProcessId
)
65 LPPROCESS_PAGE_LIST_ITEM pData
;
67 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
69 memset(&item
, 0, sizeof(LV_ITEM
));
70 item
.mask
= LVIF_PARAM
;
72 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
73 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
74 if (pData
->ProcessId
== dwProcessId
)
82 DWORD
GetSelectedProcessId(void)
87 if(ListView_GetSelectedCount(hProcessPageListCtrl
) == 1)
89 Index
= ListView_GetSelectionMark(hProcessPageListCtrl
);
91 memset(&lvitem
, 0, sizeof(LVITEM
));
93 lvitem
.mask
= LVIF_PARAM
;
96 (void)ListView_GetItem(hProcessPageListCtrl
, &lvitem
);
99 return ((LPPROCESS_PAGE_LIST_ITEM
)lvitem
.lParam
)->ProcessId
;
106 ProcessPageWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
116 * Save the width and height
118 GetClientRect(hDlg
, &rc
);
119 nProcessPageWidth
= rc
.right
;
120 nProcessPageHeight
= rc
.bottom
;
122 /* Update window position */
123 SetWindowPos(hDlg
, NULL
, 15, 30, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
126 * Get handles to the controls
128 hProcessPageListCtrl
= GetDlgItem(hDlg
, IDC_PROCESSLIST
);
129 hProcessPageHeaderCtrl
= ListView_GetHeader(hProcessPageListCtrl
);
130 hProcessPageEndProcessButton
= GetDlgItem(hDlg
, IDC_ENDPROCESS
);
131 hProcessPageShowAllProcessesButton
= GetDlgItem(hDlg
, IDC_SHOWALLPROCESSES
);
134 * Set the title, and extended window styles for the list control
136 SetWindowTextW(hProcessPageListCtrl
, L
"Processes");
137 (void)ListView_SetExtendedListViewStyle(hProcessPageListCtrl
, ListView_GetExtendedListViewStyle(hProcessPageListCtrl
) | LVS_EX_FULLROWSELECT
| LVS_EX_HEADERDRAGDROP
);
142 * Subclass the process list control so we can intercept WM_ERASEBKGND
144 OldProcessListWndProc
= (WNDPROC
)SetWindowLongPtrW(hProcessPageListCtrl
, GWLP_WNDPROC
, (LONG_PTR
)ProcessListWndProc
);
147 /* Start our refresh thread */
148 hProcessThread
= CreateThread(NULL
, 0, ProcessPageRefreshThread
, NULL
, 0, &dwProcessThread
);
153 /* Close the event handle, this will make the */
154 /* refresh thread exit when the wait fails */
156 EndLocalThread(&hProcessThread
, dwProcessThread
);
158 SaveColumnSettings();
162 /* Handle the button clicks */
163 switch (LOWORD(wParam
))
166 ProcessPage_OnEndProcess();
171 if (wParam
== SIZE_MINIMIZED
)
176 nXDifference
= cx
- nProcessPageWidth
;
177 nYDifference
= cy
- nProcessPageHeight
;
178 nProcessPageWidth
= cx
;
179 nProcessPageHeight
= cy
;
181 /* Reposition the application page's controls */
182 GetWindowRect(hProcessPageListCtrl
, &rc
);
183 cx
= (rc
.right
- rc
.left
) + nXDifference
;
184 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
185 SetWindowPos(hProcessPageListCtrl
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
186 InvalidateRect(hProcessPageListCtrl
, NULL
, TRUE
);
188 GetClientRect(hProcessPageEndProcessButton
, &rc
);
189 MapWindowPoints(hProcessPageEndProcessButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), sizeof(RECT
)/sizeof(POINT
));
190 cx
= rc
.left
+ nXDifference
;
191 cy
= rc
.top
+ nYDifference
;
192 SetWindowPos(hProcessPageEndProcessButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
193 InvalidateRect(hProcessPageEndProcessButton
, NULL
, TRUE
);
195 GetClientRect(hProcessPageShowAllProcessesButton
, &rc
);
196 MapWindowPoints(hProcessPageShowAllProcessesButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), sizeof(RECT
)/sizeof(POINT
));
198 cy
= rc
.top
+ nYDifference
;
199 SetWindowPos(hProcessPageShowAllProcessesButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
200 InvalidateRect(hProcessPageShowAllProcessesButton
, NULL
, TRUE
);
204 ProcessPageOnNotify(wParam
, lParam
);
208 if (wParam
== VK_DELETE
)
209 ProcessPage_OnEndProcess();
216 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
)
223 LPPROCESS_PAGE_LIST_ITEM pData
;
225 pnmh
= (LPNMHDR
) lParam
;
226 pnmdi
= (NMLVDISPINFO
*) lParam
;
227 pnmhdr
= (LPNMHEADER
) lParam
;
229 if (pnmh
->hwndFrom
== hProcessPageListCtrl
)
234 case LVN_ITEMCHANGED
:
239 case LVN_GETDISPINFO
:
241 if (!(pnmdi
->item
.mask
& LVIF_TEXT
))
244 pData
= (LPPROCESS_PAGE_LIST_ITEM
)pnmdi
->item
.lParam
;
245 Index
= PerfDataGetProcessIndex(pData
->ProcessId
);
246 ColumnIndex
= pnmdi
->item
.iSubItem
;
248 PerfDataGetText(Index
, ColumnIndex
, pnmdi
->item
.pszText
, pnmdi
->item
.cchTextMax
);
254 ProcessPageShowContextMenu(GetSelectedProcessId());
259 if (((LPNMLVKEYDOWN
)lParam
)->wVKey
== VK_DELETE
)
260 ProcessPage_OnEndProcess();
265 else if (pnmh
->hwndFrom
== hProcessPageHeaderCtrl
)
271 TaskManagerSettings
.SortColumn
= ColumnDataHints
[pnmhdr
->iItem
];
272 TaskManagerSettings
.SortAscending
= !TaskManagerSettings
.SortAscending
;
273 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
277 case HDN_ITEMCHANGED
:
279 UpdateColumnDataHints();
285 UpdateColumnDataHints();
293 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
)
298 for (i
=0,j
=0; i
<(wcslen(strNumber
) % 3); i
++, j
++)
299 temp
[j
] = strNumber
[i
];
300 for (k
=0; i
<wcslen(strNumber
); i
++,j
++,k
++) {
301 if ((k
% 3 == 0) && (j
> 0))
303 temp
[j
] = strNumber
[i
];
306 wcsncpy(strNumber
, temp
, nMaxCount
);
309 void ProcessPageShowContextMenu(DWORD dwProcessId
)
317 DWORD dwProcessPriorityClass
;
318 WCHAR strDebugger
[260];
319 DWORD dwDebuggerSize
;
322 memset(&si
, 0, sizeof(SYSTEM_INFO
));
327 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_PROCESS_PAGE_CONTEXT
));
328 hSubMenu
= GetSubMenu(hMenu
, 0);
329 hPriorityMenu
= GetSubMenu(hSubMenu
, 4);
331 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dwProcessId
);
332 dwProcessPriorityClass
= GetPriorityClass(hProcess
);
333 CloseHandle(hProcess
);
335 if (si
.dwNumberOfProcessors
< 2)
336 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_SETAFFINITY
, MF_BYCOMMAND
);
338 if (!DebugChannelsAreSupported())
339 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_DEBUGCHANNELS
, MF_BYCOMMAND
);
341 switch (dwProcessPriorityClass
) {
342 case REALTIME_PRIORITY_CLASS
:
343 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, MF_BYCOMMAND
);
345 case HIGH_PRIORITY_CLASS
:
346 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_HIGH
, MF_BYCOMMAND
);
348 case ABOVE_NORMAL_PRIORITY_CLASS
:
349 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
, MF_BYCOMMAND
);
351 case NORMAL_PRIORITY_CLASS
:
352 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_NORMAL
, MF_BYCOMMAND
);
354 case BELOW_NORMAL_PRIORITY_CLASS
:
355 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
, MF_BYCOMMAND
);
357 case IDLE_PRIORITY_CLASS
:
358 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, MF_BYCOMMAND
);
362 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
364 dwDebuggerSize
= 260;
365 if (RegQueryValueExW(hKey
, L
"Debugger", NULL
, NULL
, (LPBYTE
)strDebugger
, &dwDebuggerSize
) == ERROR_SUCCESS
)
367 CharUpper(strDebugger
);
368 if (wcsstr(strDebugger
, L
"DRWTSN32"))
369 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
372 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
376 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
378 TrackPopupMenu(hSubMenu
, TPM_LEFTALIGN
|TPM_TOPALIGN
|TPM_LEFTBUTTON
, pt
.x
, pt
.y
, 0, hMainWnd
, NULL
);
382 void RefreshProcessPage(void)
385 /* Signal the event so that our refresh thread */
386 /* will wake up and refresh the process page */
387 PostThreadMessage(dwProcessThread
, WM_TIMER
, 0, 0);
391 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
)
393 ULONG OldProcessorUsage
= 0;
394 ULONG OldProcessCount
= 0;
395 WCHAR szCpuUsage
[256], szProcesses
[256];
398 LoadStringW(hInst
, IDS_STATUS_CPUUSAGE
, szCpuUsage
, 256);
399 LoadStringW(hInst
, IDS_STATUS_PROCESSES
, szProcesses
, 256);
402 /* Wait for an the event or application close */
403 if (GetMessage(&msg
, NULL
, 0, 0) <= 0)
406 if (msg
.message
== WM_TIMER
) {
411 if (IsWindowVisible(hProcessPage
))
412 InvalidateRect(hProcessPageListCtrl
, NULL
, FALSE
);
414 if (OldProcessorUsage
!= PerfDataGetProcessorUsage()) {
415 OldProcessorUsage
= PerfDataGetProcessorUsage();
416 wsprintfW(text
, szCpuUsage
, OldProcessorUsage
);
417 SendMessageW(hStatusWnd
, SB_SETTEXT
, 1, (LPARAM
)text
);
419 if (OldProcessCount
!= PerfDataGetProcessCount()) {
420 OldProcessCount
= PerfDataGetProcessCount();
421 wsprintfW(text
, szProcesses
, OldProcessCount
);
422 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)text
);
429 void UpdateProcesses()
434 LPPROCESS_PAGE_LIST_ITEM pData
;
436 SendMessage(hProcessPageListCtrl
, WM_SETREDRAW
, FALSE
, 0);
438 /* Remove old processes */
439 for (i
= 0; i
< ListView_GetItemCount(hProcessPageListCtrl
); i
++)
441 memset(&item
, 0, sizeof (LV_ITEM
));
442 item
.mask
= LVIF_PARAM
;
444 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
445 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
446 if (!ProcessRunning(pData
->ProcessId
))
448 (void)ListView_DeleteItem(hProcessPageListCtrl
, i
);
449 HeapFree(GetProcessHeap(), 0, pData
);
453 /* Check for difference in listview process and performance process counts */
454 if (ListView_GetItemCount(hProcessPageListCtrl
) != PerfDataGetProcessCount())
456 /* Add new processes by checking against the current items */
457 for (l
= 0; l
< PerfDataGetProcessCount(); l
++)
463 if (TaskManagerSettings
.SortColumn
!= -1)
465 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
468 SendMessage(hProcessPageListCtrl
, WM_SETREDRAW
, TRUE
, 0);
471 BOOL
ProcessRunning(ULONG ProcessId
)
476 if (ProcessId
== 0) {
480 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, ProcessId
);
481 if (hProcess
== NULL
) {
485 if (GetExitCodeProcess(hProcess
, &exitCode
)) {
486 CloseHandle(hProcess
);
487 return (exitCode
== STILL_ACTIVE
);
490 CloseHandle(hProcess
);
494 void AddProcess(ULONG Index
)
496 LPPROCESS_PAGE_LIST_ITEM pData
;
499 BOOL bAlreadyInList
= FALSE
;
502 pid
= PerfDataGetProcessId(Index
);
504 /* Check to see if it's already in our list */
505 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
507 memset(&item
, 0, sizeof(LV_ITEM
));
508 item
.mask
= LVIF_PARAM
;
510 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
511 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
512 if (pData
->ProcessId
== pid
)
514 bAlreadyInList
= TRUE
;
518 if (!bAlreadyInList
) /* Add */
520 pData
= (LPPROCESS_PAGE_LIST_ITEM
)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM
));
521 pData
->ProcessId
= pid
;
523 /* Add the item to the list */
524 memset(&item
, 0, sizeof(LV_ITEM
));
525 item
.mask
= LVIF_TEXT
|LVIF_PARAM
;
526 item
.pszText
= LPSTR_TEXTCALLBACK
;
527 item
.iItem
= ListView_GetItemCount(hProcessPageListCtrl
);
528 item
.lParam
= (LPARAM
)pData
;
529 (void)ListView_InsertItem(hProcessPageListCtrl
, &item
);
533 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
)
535 IO_COUNTERS iocounters
;
538 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IMAGENAME
)
539 PerfDataGetImageName(Index
, lpText
, nMaxCount
);
540 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PID
)
541 wsprintfW(lpText
, L
"%lu", PerfDataGetProcessId(Index
));
542 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USERNAME
)
543 PerfDataGetUserName(Index
, lpText
, nMaxCount
);
544 if (ColumnDataHints
[ColumnIndex
] == COLUMN_SESSIONID
)
545 wsprintfW(lpText
, L
"%lu", PerfDataGetSessionId(Index
));
546 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUUSAGE
)
547 wsprintfW(lpText
, L
"%02lu", PerfDataGetCPUUsage(Index
));
548 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUTIME
)
554 time
= PerfDataGetCPUTime(Index
);
555 gethmsfromlargeint(time
, &dwHours
, &dwMinutes
, &dwSeconds
);
556 wsprintfW(lpText
, L
"%lu:%02lu:%02lu", dwHours
, dwMinutes
, dwSeconds
);
558 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGE
)
560 wsprintfW(lpText
, L
"%lu", PerfDataGetWorkingSetSizeBytes(Index
) / 1024);
561 CommaSeparateNumberString(lpText
, nMaxCount
);
562 wcscat(lpText
, L
" K");
564 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PEAKMEMORYUSAGE
)
566 wsprintfW(lpText
, L
"%lu", PerfDataGetPeakWorkingSetSizeBytes(Index
) / 1024);
567 CommaSeparateNumberString(lpText
, nMaxCount
);
568 wcscat(lpText
, L
" K");
570 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGEDELTA
)
572 wsprintfW(lpText
, L
"%lu", PerfDataGetWorkingSetSizeDelta(Index
) / 1024);
573 CommaSeparateNumberString(lpText
, nMaxCount
);
574 wcscat(lpText
, L
" K");
576 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTS
)
578 wsprintfW(lpText
, L
"%lu", PerfDataGetPageFaultCount(Index
));
579 CommaSeparateNumberString(lpText
, nMaxCount
);
581 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTSDELTA
)
583 wsprintfW(lpText
, L
"%lu", PerfDataGetPageFaultCountDelta(Index
));
584 CommaSeparateNumberString(lpText
, nMaxCount
);
586 if (ColumnDataHints
[ColumnIndex
] == COLUMN_VIRTUALMEMORYSIZE
)
588 wsprintfW(lpText
, L
"%lu", PerfDataGetVirtualMemorySizeBytes(Index
) / 1024);
589 CommaSeparateNumberString(lpText
, nMaxCount
);
590 wcscat(lpText
, L
" K");
592 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEDPOOL
)
594 wsprintfW(lpText
, L
"%lu", PerfDataGetPagedPoolUsagePages(Index
) / 1024);
595 CommaSeparateNumberString(lpText
, nMaxCount
);
596 wcscat(lpText
, L
" K");
598 if (ColumnDataHints
[ColumnIndex
] == COLUMN_NONPAGEDPOOL
)
600 wsprintfW(lpText
, L
"%lu", PerfDataGetNonPagedPoolUsagePages(Index
) / 1024);
601 CommaSeparateNumberString(lpText
, nMaxCount
);
602 wcscat(lpText
, L
" K");
604 if (ColumnDataHints
[ColumnIndex
] == COLUMN_BASEPRIORITY
)
605 wsprintfW(lpText
, L
"%lu", PerfDataGetBasePriority(Index
));
606 if (ColumnDataHints
[ColumnIndex
] == COLUMN_HANDLECOUNT
)
608 wsprintfW(lpText
, L
"%lu", PerfDataGetHandleCount(Index
));
609 CommaSeparateNumberString(lpText
, nMaxCount
);
611 if (ColumnDataHints
[ColumnIndex
] == COLUMN_THREADCOUNT
)
613 wsprintfW(lpText
, L
"%lu", PerfDataGetThreadCount(Index
));
614 CommaSeparateNumberString(lpText
, nMaxCount
);
616 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USEROBJECTS
)
618 wsprintfW(lpText
, L
"%lu", PerfDataGetUSERObjectCount(Index
));
619 CommaSeparateNumberString(lpText
, nMaxCount
);
621 if (ColumnDataHints
[ColumnIndex
] == COLUMN_GDIOBJECTS
)
623 wsprintfW(lpText
, L
"%lu", PerfDataGetGDIObjectCount(Index
));
624 CommaSeparateNumberString(lpText
, nMaxCount
);
626 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADS
)
628 PerfDataGetIOCounters(Index
, &iocounters
);
629 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadOperationCount); */
630 _ui64tow(iocounters
.ReadOperationCount
, lpText
, 10);
631 CommaSeparateNumberString(lpText
, nMaxCount
);
633 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITES
)
635 PerfDataGetIOCounters(Index
, &iocounters
);
636 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteOperationCount); */
637 _ui64tow(iocounters
.WriteOperationCount
, lpText
, 10);
638 CommaSeparateNumberString(lpText
, nMaxCount
);
640 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHER
)
642 PerfDataGetIOCounters(Index
, &iocounters
);
643 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherOperationCount); */
644 _ui64tow(iocounters
.OtherOperationCount
, lpText
, 10);
645 CommaSeparateNumberString(lpText
, nMaxCount
);
647 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADBYTES
)
649 PerfDataGetIOCounters(Index
, &iocounters
);
650 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadTransferCount); */
651 _ui64tow(iocounters
.ReadTransferCount
, lpText
, 10);
652 CommaSeparateNumberString(lpText
, nMaxCount
);
654 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITEBYTES
)
656 PerfDataGetIOCounters(Index
, &iocounters
);
657 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteTransferCount); */
658 _ui64tow(iocounters
.WriteTransferCount
, lpText
, 10);
659 CommaSeparateNumberString(lpText
, nMaxCount
);
661 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHERBYTES
)
663 PerfDataGetIOCounters(Index
, &iocounters
);
664 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherTransferCount); */
665 _ui64tow(iocounters
.OtherTransferCount
, lpText
, 10);
666 CommaSeparateNumberString(lpText
, nMaxCount
);
673 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
)
676 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000L);
677 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000L) / 600000000L);
678 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000L) % 600000000L) / 10000000L);
680 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000LL);
681 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000LL) / 600000000LL);
682 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000LL) % 600000000LL) / 10000000LL);
686 int largeintcmp(LARGE_INTEGER l1
, LARGE_INTEGER l2
)
696 gethmsfromlargeint(l1
, &dwHours1
, &dwMinutes1
, &dwSeconds1
);
697 gethmsfromlargeint(l2
, &dwHours2
, &dwMinutes2
, &dwSeconds2
);
698 ret
= CMP(dwHours1
, dwHours2
);
701 ret
= CMP(dwMinutes1
, dwMinutes2
);
704 ret
= CMP(dwSeconds1
, dwSeconds2
);
710 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
713 LPPROCESS_PAGE_LIST_ITEM Param1
;
714 LPPROCESS_PAGE_LIST_ITEM Param2
;
723 IO_COUNTERS iocounters1
;
724 IO_COUNTERS iocounters2
;
728 if (TaskManagerSettings
.SortAscending
) {
729 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
730 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
732 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
733 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
735 IndexParam1
= PerfDataGetProcessIndex(Param1
->ProcessId
);
736 IndexParam2
= PerfDataGetProcessIndex(Param2
->ProcessId
);
738 if (TaskManagerSettings
.SortColumn
== COLUMN_IMAGENAME
)
740 PerfDataGetImageName(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
741 PerfDataGetImageName(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
742 ret
= _wcsicmp(text1
, text2
);
744 else if (TaskManagerSettings
.SortColumn
== COLUMN_PID
)
746 l1
= Param1
->ProcessId
;
747 l2
= Param2
->ProcessId
;
750 else if (TaskManagerSettings
.SortColumn
== COLUMN_USERNAME
)
752 PerfDataGetUserName(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
753 PerfDataGetUserName(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
754 ret
= _wcsicmp(text1
, text2
);
756 else if (TaskManagerSettings
.SortColumn
== COLUMN_SESSIONID
)
758 l1
= PerfDataGetSessionId(IndexParam1
);
759 l2
= PerfDataGetSessionId(IndexParam2
);
762 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUUSAGE
)
764 l1
= PerfDataGetCPUUsage(IndexParam1
);
765 l2
= PerfDataGetCPUUsage(IndexParam2
);
768 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUTIME
)
770 time1
= PerfDataGetCPUTime(IndexParam1
);
771 time2
= PerfDataGetCPUTime(IndexParam2
);
772 ret
= largeintcmp(time1
, time2
);
774 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGE
)
776 l1
= PerfDataGetWorkingSetSizeBytes(IndexParam1
);
777 l2
= PerfDataGetWorkingSetSizeBytes(IndexParam2
);
780 else if (TaskManagerSettings
.SortColumn
== COLUMN_PEAKMEMORYUSAGE
)
782 l1
= PerfDataGetPeakWorkingSetSizeBytes(IndexParam1
);
783 l2
= PerfDataGetPeakWorkingSetSizeBytes(IndexParam2
);
786 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGEDELTA
)
788 l1
= PerfDataGetWorkingSetSizeDelta(IndexParam1
);
789 l2
= PerfDataGetWorkingSetSizeDelta(IndexParam2
);
792 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTS
)
794 l1
= PerfDataGetPageFaultCount(IndexParam1
);
795 l2
= PerfDataGetPageFaultCount(IndexParam2
);
798 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTSDELTA
)
800 l1
= PerfDataGetPageFaultCountDelta(IndexParam1
);
801 l2
= PerfDataGetPageFaultCountDelta(IndexParam2
);
804 else if (TaskManagerSettings
.SortColumn
== COLUMN_VIRTUALMEMORYSIZE
)
806 l1
= PerfDataGetVirtualMemorySizeBytes(IndexParam1
);
807 l2
= PerfDataGetVirtualMemorySizeBytes(IndexParam2
);
810 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEDPOOL
)
812 l1
= PerfDataGetPagedPoolUsagePages(IndexParam1
);
813 l2
= PerfDataGetPagedPoolUsagePages(IndexParam2
);
816 else if (TaskManagerSettings
.SortColumn
== COLUMN_NONPAGEDPOOL
)
818 l1
= PerfDataGetNonPagedPoolUsagePages(IndexParam1
);
819 l2
= PerfDataGetNonPagedPoolUsagePages(IndexParam2
);
822 else if (TaskManagerSettings
.SortColumn
== COLUMN_BASEPRIORITY
)
824 l1
= PerfDataGetBasePriority(IndexParam1
);
825 l2
= PerfDataGetBasePriority(IndexParam2
);
828 else if (TaskManagerSettings
.SortColumn
== COLUMN_HANDLECOUNT
)
830 l1
= PerfDataGetHandleCount(IndexParam1
);
831 l2
= PerfDataGetHandleCount(IndexParam2
);
834 else if (TaskManagerSettings
.SortColumn
== COLUMN_THREADCOUNT
)
836 l1
= PerfDataGetThreadCount(IndexParam1
);
837 l2
= PerfDataGetThreadCount(IndexParam2
);
840 else if (TaskManagerSettings
.SortColumn
== COLUMN_USEROBJECTS
)
842 l1
= PerfDataGetUSERObjectCount(IndexParam1
);
843 l2
= PerfDataGetUSERObjectCount(IndexParam2
);
846 else if (TaskManagerSettings
.SortColumn
== COLUMN_GDIOBJECTS
)
848 l1
= PerfDataGetGDIObjectCount(IndexParam1
);
849 l2
= PerfDataGetGDIObjectCount(IndexParam2
);
852 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADS
)
854 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
855 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
856 ull1
= iocounters1
.ReadOperationCount
;
857 ull2
= iocounters2
.ReadOperationCount
;
858 ret
= CMP(ull1
, ull2
);
860 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITES
)
862 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
863 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
864 ull1
= iocounters1
.WriteOperationCount
;
865 ull2
= iocounters2
.WriteOperationCount
;
866 ret
= CMP(ull1
, ull2
);
868 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHER
)
870 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
871 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
872 ull1
= iocounters1
.OtherOperationCount
;
873 ull2
= iocounters2
.OtherOperationCount
;
874 ret
= CMP(ull1
, ull2
);
876 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADBYTES
)
878 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
879 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
880 ull1
= iocounters1
.ReadTransferCount
;
881 ull2
= iocounters2
.ReadTransferCount
;
882 ret
= CMP(ull1
, ull2
);
884 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITEBYTES
)
886 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
887 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
888 ull1
= iocounters1
.WriteTransferCount
;
889 ull2
= iocounters2
.WriteTransferCount
;
890 ret
= CMP(ull1
, ull2
);
892 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHERBYTES
)
894 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
895 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
896 ull1
= iocounters1
.OtherTransferCount
;
897 ull2
= iocounters2
.OtherTransferCount
;
898 ret
= CMP(ull1
, ull2
);