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))
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
;
44 static HANDLE hProcessThread
= NULL
;
45 static DWORD dwProcessThread
;
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
);
57 int ProcessRunning(ULONG ProcessId
);
59 int ProcGetIndexByProcessId(DWORD dwProcessId
)
63 LPPROCESS_PAGE_LIST_ITEM pData
;
65 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
67 memset(&item
, 0, sizeof(LV_ITEM
));
68 item
.mask
= LVIF_PARAM
;
70 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
71 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
72 if (pData
->ProcessId
== dwProcessId
)
80 DWORD
GetSelectedProcessId(void)
85 if(ListView_GetSelectedCount(hProcessPageListCtrl
) == 1)
87 Index
= ListView_GetSelectionMark(hProcessPageListCtrl
);
89 memset(&lvitem
, 0, sizeof(LVITEM
));
91 lvitem
.mask
= LVIF_PARAM
;
94 (void)ListView_GetItem(hProcessPageListCtrl
, &lvitem
);
97 return ((LPPROCESS_PAGE_LIST_ITEM
)lvitem
.lParam
)->ProcessId
;
104 ProcessPageWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
114 * Save the width and height
116 GetClientRect(hDlg
, &rc
);
117 nProcessPageWidth
= rc
.right
;
118 nProcessPageHeight
= rc
.bottom
;
120 /* Update window position */
121 SetWindowPos(hDlg
, NULL
, 15, 30, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
124 * Get handles to the controls
126 hProcessPageListCtrl
= GetDlgItem(hDlg
, IDC_PROCESSLIST
);
127 hProcessPageHeaderCtrl
= ListView_GetHeader(hProcessPageListCtrl
);
128 hProcessPageEndProcessButton
= GetDlgItem(hDlg
, IDC_ENDPROCESS
);
129 hProcessPageShowAllProcessesButton
= GetDlgItem(hDlg
, IDC_SHOWALLPROCESSES
);
132 * Set the title, and extended window styles for the list control
134 SetWindowTextW(hProcessPageListCtrl
, L
"Processes");
135 (void)ListView_SetExtendedListViewStyle(hProcessPageListCtrl
, ListView_GetExtendedListViewStyle(hProcessPageListCtrl
) | LVS_EX_FULLROWSELECT
| LVS_EX_HEADERDRAGDROP
);
140 * Subclass the process list control so we can intercept WM_ERASEBKGND
142 OldProcessListWndProc
= (WNDPROC
)(LONG_PTR
) SetWindowLongPtrW(hProcessPageListCtrl
, GWLP_WNDPROC
, (LONG_PTR
)ProcessListWndProc
);
145 /* Start our refresh thread */
146 hProcessThread
= CreateThread(NULL
, 0, ProcessPageRefreshThread
, NULL
, 0, &dwProcessThread
);
151 /* Close the event handle, this will make the */
152 /* refresh thread exit when the wait fails */
154 EndLocalThread(&hProcessThread
, dwProcessThread
);
156 SaveColumnSettings();
160 /* Handle the button clicks */
161 switch (LOWORD(wParam
))
164 ProcessPage_OnEndProcess();
169 if (wParam
== SIZE_MINIMIZED
)
174 nXDifference
= cx
- nProcessPageWidth
;
175 nYDifference
= cy
- nProcessPageHeight
;
176 nProcessPageWidth
= cx
;
177 nProcessPageHeight
= cy
;
179 /* Reposition the application page's controls */
180 GetWindowRect(hProcessPageListCtrl
, &rc
);
181 cx
= (rc
.right
- rc
.left
) + nXDifference
;
182 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
183 SetWindowPos(hProcessPageListCtrl
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
184 InvalidateRect(hProcessPageListCtrl
, NULL
, TRUE
);
186 GetClientRect(hProcessPageEndProcessButton
, &rc
);
187 MapWindowPoints(hProcessPageEndProcessButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), (sizeof(RECT
)/sizeof(POINT
)) );
188 cx
= rc
.left
+ nXDifference
;
189 cy
= rc
.top
+ nYDifference
;
190 SetWindowPos(hProcessPageEndProcessButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
191 InvalidateRect(hProcessPageEndProcessButton
, NULL
, TRUE
);
193 GetClientRect(hProcessPageShowAllProcessesButton
, &rc
);
194 MapWindowPoints(hProcessPageShowAllProcessesButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), (sizeof(RECT
)/sizeof(POINT
)) );
196 cy
= rc
.top
+ nYDifference
;
197 SetWindowPos(hProcessPageShowAllProcessesButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
198 InvalidateRect(hProcessPageShowAllProcessesButton
, NULL
, TRUE
);
202 ProcessPageOnNotify(wParam
, lParam
);
206 if (wParam
== VK_DELETE
)
207 ProcessPage_OnEndProcess();
214 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
)
221 LPPROCESS_PAGE_LIST_ITEM pData
;
223 pnmh
= (LPNMHDR
) lParam
;
224 pnmdi
= (NMLVDISPINFO
*) lParam
;
225 pnmhdr
= (LPNMHEADER
) lParam
;
227 if (pnmh
->hwndFrom
== hProcessPageListCtrl
)
232 case LVN_ITEMCHANGED
:
237 case LVN_GETDISPINFO
:
239 if (!(pnmdi
->item
.mask
& LVIF_TEXT
))
242 pData
= (LPPROCESS_PAGE_LIST_ITEM
)pnmdi
->item
.lParam
;
243 Index
= PerfDataGetProcessIndex(pData
->ProcessId
);
244 ColumnIndex
= pnmdi
->item
.iSubItem
;
246 PerfDataGetText(Index
, ColumnIndex
, pnmdi
->item
.pszText
, pnmdi
->item
.cchTextMax
);
252 ProcessPageShowContextMenu(GetSelectedProcessId());
257 if (((LPNMLVKEYDOWN
)lParam
)->wVKey
== VK_DELETE
)
258 ProcessPage_OnEndProcess();
263 else if (pnmh
->hwndFrom
== hProcessPageHeaderCtrl
)
269 TaskManagerSettings
.SortColumn
= ColumnDataHints
[pnmhdr
->iItem
];
270 TaskManagerSettings
.SortAscending
= !TaskManagerSettings
.SortAscending
;
271 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
275 case HDN_ITEMCHANGED
:
277 UpdateColumnDataHints();
283 UpdateColumnDataHints();
291 void CommaSeparateNumberString(LPWSTR strNumber
, int nMaxCount
)
296 for (i
=0,j
=0; i
<(wcslen(strNumber
) % 3); i
++, j
++)
297 temp
[j
] = strNumber
[i
];
298 for (k
=0; i
<wcslen(strNumber
); i
++,j
++,k
++) {
299 if ((k
% 3 == 0) && (j
> 0))
301 temp
[j
] = strNumber
[i
];
304 wcsncpy(strNumber
, temp
, nMaxCount
);
307 void ProcessPageShowContextMenu(DWORD dwProcessId
)
315 DWORD dwProcessPriorityClass
;
316 WCHAR strDebugger
[260];
317 DWORD dwDebuggerSize
;
320 memset(&si
, 0, sizeof(SYSTEM_INFO
));
325 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_PROCESS_PAGE_CONTEXT
));
326 hSubMenu
= GetSubMenu(hMenu
, 0);
327 hPriorityMenu
= GetSubMenu(hSubMenu
, 4);
329 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dwProcessId
);
330 dwProcessPriorityClass
= GetPriorityClass(hProcess
);
331 CloseHandle(hProcess
);
333 if (si
.dwNumberOfProcessors
< 2)
334 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_SETAFFINITY
, MF_BYCOMMAND
);
336 if (!DebugChannelsAreSupported())
337 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_DEBUGCHANNELS
, MF_BYCOMMAND
);
339 switch (dwProcessPriorityClass
) {
340 case REALTIME_PRIORITY_CLASS
:
341 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, MF_BYCOMMAND
);
343 case HIGH_PRIORITY_CLASS
:
344 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_HIGH
, MF_BYCOMMAND
);
346 case ABOVE_NORMAL_PRIORITY_CLASS
:
347 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
, MF_BYCOMMAND
);
349 case NORMAL_PRIORITY_CLASS
:
350 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_NORMAL
, MF_BYCOMMAND
);
352 case BELOW_NORMAL_PRIORITY_CLASS
:
353 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
, MF_BYCOMMAND
);
355 case IDLE_PRIORITY_CLASS
:
356 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, MF_BYCOMMAND
);
360 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
362 dwDebuggerSize
= 260;
363 if (RegQueryValueExW(hKey
, L
"Debugger", NULL
, NULL
, (LPBYTE
)strDebugger
, &dwDebuggerSize
) == ERROR_SUCCESS
)
365 CharUpper(strDebugger
);
366 if (wcsstr(strDebugger
, L
"DRWTSN32"))
367 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
370 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
374 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
376 TrackPopupMenu(hSubMenu
, TPM_LEFTALIGN
|TPM_TOPALIGN
|TPM_LEFTBUTTON
, pt
.x
, pt
.y
, 0, hMainWnd
, NULL
);
380 void RefreshProcessPage(void)
383 /* Signal the event so that our refresh thread */
384 /* will wake up and refresh the process page */
385 PostThreadMessage(dwProcessThread
, WM_TIMER
, 0, 0);
389 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
)
391 ULONG OldProcessorUsage
= 0;
392 ULONG OldProcessCount
= 0;
393 WCHAR szCpuUsage
[256], szProcesses
[256];
396 LoadStringW(hInst
, IDS_STATUS_CPUUSAGE
, szCpuUsage
, 256);
397 LoadStringW(hInst
, IDS_STATUS_PROCESSES
, szProcesses
, 256);
400 /* Wait for an the event or application close */
401 if (GetMessage(&msg
, NULL
, 0, 0) <= 0)
404 if (msg
.message
== WM_TIMER
) {
409 if (IsWindowVisible(hProcessPage
))
410 InvalidateRect(hProcessPageListCtrl
, NULL
, FALSE
);
412 if (OldProcessorUsage
!= PerfDataGetProcessorUsage()) {
413 OldProcessorUsage
= PerfDataGetProcessorUsage();
414 wsprintfW(text
, szCpuUsage
, OldProcessorUsage
);
415 SendMessageW(hStatusWnd
, SB_SETTEXT
, 1, (LPARAM
)text
);
417 if (OldProcessCount
!= PerfDataGetProcessCount()) {
418 OldProcessCount
= PerfDataGetProcessCount();
419 wsprintfW(text
, szProcesses
, OldProcessCount
);
420 SendMessageW(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)text
);
427 void UpdateProcesses()
432 LPPROCESS_PAGE_LIST_ITEM pData
;
434 SendMessage(hProcessPageListCtrl
, WM_SETREDRAW
, FALSE
, 0);
436 /* Remove old processes */
437 for (i
= 0; i
< ListView_GetItemCount(hProcessPageListCtrl
); i
++)
439 memset(&item
, 0, sizeof (LV_ITEM
));
440 item
.mask
= LVIF_PARAM
;
442 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
443 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
444 if (!ProcessRunning(pData
->ProcessId
))
446 (void)ListView_DeleteItem(hProcessPageListCtrl
, i
);
447 HeapFree(GetProcessHeap(), 0, pData
);
451 /* Check for difference in listview process and performance process counts */
452 if (ListView_GetItemCount(hProcessPageListCtrl
) != PerfDataGetProcessCount())
454 /* Add new processes by checking against the current items */
455 for (l
= 0; l
< PerfDataGetProcessCount(); l
++)
461 if (TaskManagerSettings
.SortColumn
!= -1)
463 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
466 SendMessage(hProcessPageListCtrl
, WM_SETREDRAW
, TRUE
, 0);
469 BOOL
ProcessRunning(ULONG ProcessId
)
474 if (ProcessId
== 0) {
478 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, ProcessId
);
479 if (hProcess
== NULL
) {
483 if (GetExitCodeProcess(hProcess
, &exitCode
)) {
484 CloseHandle(hProcess
);
485 return (exitCode
== STILL_ACTIVE
);
488 CloseHandle(hProcess
);
492 void AddProcess(ULONG Index
)
494 LPPROCESS_PAGE_LIST_ITEM pData
;
497 BOOL bAlreadyInList
= FALSE
;
500 pid
= PerfDataGetProcessId(Index
);
502 /* Check to see if it's already in our list */
503 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
505 memset(&item
, 0, sizeof(LV_ITEM
));
506 item
.mask
= LVIF_PARAM
;
508 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
509 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
510 if (pData
->ProcessId
== pid
)
512 bAlreadyInList
= TRUE
;
516 if (!bAlreadyInList
) /* Add */
518 pData
= (LPPROCESS_PAGE_LIST_ITEM
)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM
));
519 pData
->ProcessId
= pid
;
521 /* Add the item to the list */
522 memset(&item
, 0, sizeof(LV_ITEM
));
523 item
.mask
= LVIF_TEXT
|LVIF_PARAM
;
524 item
.pszText
= LPSTR_TEXTCALLBACK
;
525 item
.iItem
= ListView_GetItemCount(hProcessPageListCtrl
);
526 item
.lParam
= (LPARAM
)pData
;
527 (void)ListView_InsertItem(hProcessPageListCtrl
, &item
);
531 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, int nMaxCount
)
533 IO_COUNTERS iocounters
;
536 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IMAGENAME
)
537 PerfDataGetImageName(Index
, lpText
, nMaxCount
);
538 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PID
)
539 wsprintfW(lpText
, L
"%d", PerfDataGetProcessId(Index
));
540 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USERNAME
)
541 PerfDataGetUserName(Index
, lpText
, nMaxCount
);
542 if (ColumnDataHints
[ColumnIndex
] == COLUMN_SESSIONID
)
543 wsprintfW(lpText
, L
"%d", PerfDataGetSessionId(Index
));
544 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUUSAGE
)
545 wsprintfW(lpText
, L
"%02d", PerfDataGetCPUUsage(Index
));
546 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUTIME
)
552 time
= PerfDataGetCPUTime(Index
);
553 gethmsfromlargeint(time
, &dwHours
, &dwMinutes
, &dwSeconds
);
554 wsprintfW(lpText
, L
"%d:%02d:%02d", dwHours
, dwMinutes
, dwSeconds
);
556 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGE
)
558 wsprintfW(lpText
, L
"%d", PerfDataGetWorkingSetSizeBytes(Index
) / 1024);
559 CommaSeparateNumberString(lpText
, nMaxCount
);
560 wcscat(lpText
, L
" K");
562 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PEAKMEMORYUSAGE
)
564 wsprintfW(lpText
, L
"%d", PerfDataGetPeakWorkingSetSizeBytes(Index
) / 1024);
565 CommaSeparateNumberString(lpText
, nMaxCount
);
566 wcscat(lpText
, L
" K");
568 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGEDELTA
)
570 wsprintfW(lpText
, L
"%d", PerfDataGetWorkingSetSizeDelta(Index
) / 1024);
571 CommaSeparateNumberString(lpText
, nMaxCount
);
572 wcscat(lpText
, L
" K");
574 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTS
)
576 wsprintfW(lpText
, L
"%d", PerfDataGetPageFaultCount(Index
));
577 CommaSeparateNumberString(lpText
, nMaxCount
);
579 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTSDELTA
)
581 wsprintfW(lpText
, L
"%d", PerfDataGetPageFaultCountDelta(Index
));
582 CommaSeparateNumberString(lpText
, nMaxCount
);
584 if (ColumnDataHints
[ColumnIndex
] == COLUMN_VIRTUALMEMORYSIZE
)
586 wsprintfW(lpText
, L
"%d", PerfDataGetVirtualMemorySizeBytes(Index
) / 1024);
587 CommaSeparateNumberString(lpText
, nMaxCount
);
588 wcscat(lpText
, L
" K");
590 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEDPOOL
)
592 wsprintfW(lpText
, L
"%d", PerfDataGetPagedPoolUsagePages(Index
) / 1024);
593 CommaSeparateNumberString(lpText
, nMaxCount
);
594 wcscat(lpText
, L
" K");
596 if (ColumnDataHints
[ColumnIndex
] == COLUMN_NONPAGEDPOOL
)
598 wsprintfW(lpText
, L
"%d", PerfDataGetNonPagedPoolUsagePages(Index
) / 1024);
599 CommaSeparateNumberString(lpText
, nMaxCount
);
600 wcscat(lpText
, L
" K");
602 if (ColumnDataHints
[ColumnIndex
] == COLUMN_BASEPRIORITY
)
603 wsprintfW(lpText
, L
"%d", PerfDataGetBasePriority(Index
));
604 if (ColumnDataHints
[ColumnIndex
] == COLUMN_HANDLECOUNT
)
606 wsprintfW(lpText
, L
"%d", PerfDataGetHandleCount(Index
));
607 CommaSeparateNumberString(lpText
, nMaxCount
);
609 if (ColumnDataHints
[ColumnIndex
] == COLUMN_THREADCOUNT
)
611 wsprintfW(lpText
, L
"%d", PerfDataGetThreadCount(Index
));
612 CommaSeparateNumberString(lpText
, nMaxCount
);
614 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USEROBJECTS
)
616 wsprintfW(lpText
, L
"%d", PerfDataGetUSERObjectCount(Index
));
617 CommaSeparateNumberString(lpText
, nMaxCount
);
619 if (ColumnDataHints
[ColumnIndex
] == COLUMN_GDIOBJECTS
)
621 wsprintfW(lpText
, L
"%d", PerfDataGetGDIObjectCount(Index
));
622 CommaSeparateNumberString(lpText
, nMaxCount
);
624 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADS
)
626 PerfDataGetIOCounters(Index
, &iocounters
);
627 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadOperationCount); */
628 _ui64tow(iocounters
.ReadOperationCount
, lpText
, 10);
629 CommaSeparateNumberString(lpText
, nMaxCount
);
631 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITES
)
633 PerfDataGetIOCounters(Index
, &iocounters
);
634 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteOperationCount); */
635 _ui64tow(iocounters
.WriteOperationCount
, lpText
, 10);
636 CommaSeparateNumberString(lpText
, nMaxCount
);
638 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHER
)
640 PerfDataGetIOCounters(Index
, &iocounters
);
641 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherOperationCount); */
642 _ui64tow(iocounters
.OtherOperationCount
, lpText
, 10);
643 CommaSeparateNumberString(lpText
, nMaxCount
);
645 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADBYTES
)
647 PerfDataGetIOCounters(Index
, &iocounters
);
648 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadTransferCount); */
649 _ui64tow(iocounters
.ReadTransferCount
, lpText
, 10);
650 CommaSeparateNumberString(lpText
, nMaxCount
);
652 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITEBYTES
)
654 PerfDataGetIOCounters(Index
, &iocounters
);
655 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteTransferCount); */
656 _ui64tow(iocounters
.WriteTransferCount
, lpText
, 10);
657 CommaSeparateNumberString(lpText
, nMaxCount
);
659 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHERBYTES
)
661 PerfDataGetIOCounters(Index
, &iocounters
);
662 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherTransferCount); */
663 _ui64tow(iocounters
.OtherTransferCount
, lpText
, 10);
664 CommaSeparateNumberString(lpText
, nMaxCount
);
671 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
)
674 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000L);
675 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000L) / 600000000L);
676 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000L) % 600000000L) / 10000000L);
678 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000LL);
679 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000LL) / 600000000LL);
680 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000LL) % 600000000LL) / 10000000LL);
684 int largeintcmp(LARGE_INTEGER l1
, LARGE_INTEGER l2
)
694 gethmsfromlargeint(l1
, &dwHours1
, &dwMinutes1
, &dwSeconds1
);
695 gethmsfromlargeint(l2
, &dwHours2
, &dwMinutes2
, &dwSeconds2
);
696 ret
= CMP(dwHours1
, dwHours2
);
699 ret
= CMP(dwMinutes1
, dwMinutes2
);
702 ret
= CMP(dwSeconds1
, dwSeconds2
);
708 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
711 LPPROCESS_PAGE_LIST_ITEM Param1
;
712 LPPROCESS_PAGE_LIST_ITEM Param2
;
721 IO_COUNTERS iocounters1
;
722 IO_COUNTERS iocounters2
;
726 if (TaskManagerSettings
.SortAscending
) {
727 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
728 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
730 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
731 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
733 IndexParam1
= PerfDataGetProcessIndex(Param1
->ProcessId
);
734 IndexParam2
= PerfDataGetProcessIndex(Param2
->ProcessId
);
736 if (TaskManagerSettings
.SortColumn
== COLUMN_IMAGENAME
)
738 PerfDataGetImageName(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
739 PerfDataGetImageName(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
740 ret
= _wcsicmp(text1
, text2
);
742 else if (TaskManagerSettings
.SortColumn
== COLUMN_PID
)
744 l1
= Param1
->ProcessId
;
745 l2
= Param2
->ProcessId
;
748 else if (TaskManagerSettings
.SortColumn
== COLUMN_USERNAME
)
750 PerfDataGetUserName(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
751 PerfDataGetUserName(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
752 ret
= _wcsicmp(text1
, text2
);
754 else if (TaskManagerSettings
.SortColumn
== COLUMN_SESSIONID
)
756 l1
= PerfDataGetSessionId(IndexParam1
);
757 l2
= PerfDataGetSessionId(IndexParam2
);
760 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUUSAGE
)
762 l1
= PerfDataGetCPUUsage(IndexParam1
);
763 l2
= PerfDataGetCPUUsage(IndexParam2
);
766 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUTIME
)
768 time1
= PerfDataGetCPUTime(IndexParam1
);
769 time2
= PerfDataGetCPUTime(IndexParam2
);
770 ret
= largeintcmp(time1
, time2
);
772 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGE
)
774 l1
= PerfDataGetWorkingSetSizeBytes(IndexParam1
);
775 l2
= PerfDataGetWorkingSetSizeBytes(IndexParam2
);
778 else if (TaskManagerSettings
.SortColumn
== COLUMN_PEAKMEMORYUSAGE
)
780 l1
= PerfDataGetPeakWorkingSetSizeBytes(IndexParam1
);
781 l2
= PerfDataGetPeakWorkingSetSizeBytes(IndexParam2
);
784 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGEDELTA
)
786 l1
= PerfDataGetWorkingSetSizeDelta(IndexParam1
);
787 l2
= PerfDataGetWorkingSetSizeDelta(IndexParam2
);
790 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTS
)
792 l1
= PerfDataGetPageFaultCount(IndexParam1
);
793 l2
= PerfDataGetPageFaultCount(IndexParam2
);
796 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTSDELTA
)
798 l1
= PerfDataGetPageFaultCountDelta(IndexParam1
);
799 l2
= PerfDataGetPageFaultCountDelta(IndexParam2
);
802 else if (TaskManagerSettings
.SortColumn
== COLUMN_VIRTUALMEMORYSIZE
)
804 l1
= PerfDataGetVirtualMemorySizeBytes(IndexParam1
);
805 l2
= PerfDataGetVirtualMemorySizeBytes(IndexParam2
);
808 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEDPOOL
)
810 l1
= PerfDataGetPagedPoolUsagePages(IndexParam1
);
811 l2
= PerfDataGetPagedPoolUsagePages(IndexParam2
);
814 else if (TaskManagerSettings
.SortColumn
== COLUMN_NONPAGEDPOOL
)
816 l1
= PerfDataGetNonPagedPoolUsagePages(IndexParam1
);
817 l2
= PerfDataGetNonPagedPoolUsagePages(IndexParam2
);
820 else if (TaskManagerSettings
.SortColumn
== COLUMN_BASEPRIORITY
)
822 l1
= PerfDataGetBasePriority(IndexParam1
);
823 l2
= PerfDataGetBasePriority(IndexParam2
);
826 else if (TaskManagerSettings
.SortColumn
== COLUMN_HANDLECOUNT
)
828 l1
= PerfDataGetHandleCount(IndexParam1
);
829 l2
= PerfDataGetHandleCount(IndexParam2
);
832 else if (TaskManagerSettings
.SortColumn
== COLUMN_THREADCOUNT
)
834 l1
= PerfDataGetThreadCount(IndexParam1
);
835 l2
= PerfDataGetThreadCount(IndexParam2
);
838 else if (TaskManagerSettings
.SortColumn
== COLUMN_USEROBJECTS
)
840 l1
= PerfDataGetUSERObjectCount(IndexParam1
);
841 l2
= PerfDataGetUSERObjectCount(IndexParam2
);
844 else if (TaskManagerSettings
.SortColumn
== COLUMN_GDIOBJECTS
)
846 l1
= PerfDataGetGDIObjectCount(IndexParam1
);
847 l2
= PerfDataGetGDIObjectCount(IndexParam2
);
850 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADS
)
852 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
853 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
854 ull1
= iocounters1
.ReadOperationCount
;
855 ull2
= iocounters2
.ReadOperationCount
;
856 ret
= CMP(ull1
, ull2
);
858 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITES
)
860 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
861 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
862 ull1
= iocounters1
.WriteOperationCount
;
863 ull2
= iocounters2
.WriteOperationCount
;
864 ret
= CMP(ull1
, ull2
);
866 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHER
)
868 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
869 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
870 ull1
= iocounters1
.OtherOperationCount
;
871 ull2
= iocounters2
.OtherOperationCount
;
872 ret
= CMP(ull1
, ull2
);
874 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADBYTES
)
876 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
877 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
878 ull1
= iocounters1
.ReadTransferCount
;
879 ull2
= iocounters2
.ReadTransferCount
;
880 ret
= CMP(ull1
, ull2
);
882 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITEBYTES
)
884 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
885 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
886 ull1
= iocounters1
.WriteTransferCount
;
887 ull2
= iocounters2
.WriteTransferCount
;
888 ret
= CMP(ull1
, ull2
);
890 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHERBYTES
)
892 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
893 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
894 ull1
= iocounters1
.OtherTransferCount
;
895 ull2
= iocounters2
.OtherTransferCount
;
896 ret
= CMP(ull1
, ull2
);