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 */
42 BOOL bProcessPageSelectionMade
= FALSE
; /* Is item in ListCtrl selected */
44 static int nProcessPageWidth
;
45 static int nProcessPageHeight
;
47 static HANDLE hProcessThread
= NULL
;
48 static DWORD dwProcessThread
;
51 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
);
52 void AddProcess(ULONG Index
);
53 void UpdateProcesses();
54 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
);
55 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
);
56 void CommaSeparateNumberString(LPWSTR strNumber
, ULONG nMaxCount
);
57 void ProcessPageShowContextMenu(DWORD dwProcessId
);
58 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, ULONG nMaxCount
);
59 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
);
60 int ProcessRunning(ULONG ProcessId
);
66 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 HeapFree(GetProcessHeap(), 0, pData
);
78 int ProcGetIndexByProcessId(DWORD dwProcessId
)
82 LPPROCESS_PAGE_LIST_ITEM pData
;
84 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
86 memset(&item
, 0, sizeof(LV_ITEM
));
87 item
.mask
= LVIF_PARAM
;
89 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
90 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
91 if (pData
->ProcessId
== dwProcessId
)
99 DWORD
GetSelectedProcessId(void)
104 if(ListView_GetSelectedCount(hProcessPageListCtrl
) == 1)
106 Index
= ListView_GetSelectionMark(hProcessPageListCtrl
);
108 memset(&lvitem
, 0, sizeof(LVITEM
));
110 lvitem
.mask
= LVIF_PARAM
;
111 lvitem
.iItem
= Index
;
113 (void)ListView_GetItem(hProcessPageListCtrl
, &lvitem
);
116 return ((LPPROCESS_PAGE_LIST_ITEM
)lvitem
.lParam
)->ProcessId
;
122 void ProcessPageUpdate(void)
124 /* Enable or disable the "End Process" button */
125 if (ListView_GetSelectedCount(hProcessPageListCtrl
))
126 EnableWindow(hProcessPageEndProcessButton
, TRUE
);
128 EnableWindow(hProcessPageEndProcessButton
, FALSE
);
132 ProcessPageWndProc(HWND hDlg
, UINT message
, WPARAM wParam
, LPARAM lParam
)
142 * Save the width and height
144 GetClientRect(hDlg
, &rc
);
145 nProcessPageWidth
= rc
.right
;
146 nProcessPageHeight
= rc
.bottom
;
148 /* Update window position */
149 SetWindowPos(hDlg
, NULL
, 15, 30, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
152 * Get handles to the controls
154 hProcessPageListCtrl
= GetDlgItem(hDlg
, IDC_PROCESSLIST
);
155 hProcessPageHeaderCtrl
= ListView_GetHeader(hProcessPageListCtrl
);
156 hProcessPageEndProcessButton
= GetDlgItem(hDlg
, IDC_ENDPROCESS
);
157 hProcessPageShowAllProcessesButton
= GetDlgItem(hDlg
, IDC_SHOWALLPROCESSES
);
160 * Set the title, and extended window styles for the list control
162 SetWindowTextW(hProcessPageListCtrl
, L
"Processes");
163 (void)ListView_SetExtendedListViewStyle(hProcessPageListCtrl
, ListView_GetExtendedListViewStyle(hProcessPageListCtrl
) | LVS_EX_FULLROWSELECT
| LVS_EX_HEADERDRAGDROP
);
168 * Subclass the process list control so we can intercept WM_ERASEBKGND
170 OldProcessListWndProc
= (WNDPROC
)SetWindowLongPtrW(hProcessPageListCtrl
, GWLP_WNDPROC
, (LONG_PTR
)ProcessListWndProc
);
173 /* Start our refresh thread */
174 hProcessThread
= CreateThread(NULL
, 0, ProcessPageRefreshThread
, NULL
, 0, &dwProcessThread
);
183 /* Close the event handle, this will make the */
184 /* refresh thread exit when the wait fails */
186 EndLocalThread(&hProcessThread
, dwProcessThread
);
188 SaveColumnSettings();
193 /* Handle the button clicks */
194 switch (LOWORD(wParam
))
197 ProcessPage_OnEndProcess();
202 if (wParam
== SIZE_MINIMIZED
)
207 nXDifference
= cx
- nProcessPageWidth
;
208 nYDifference
= cy
- nProcessPageHeight
;
209 nProcessPageWidth
= cx
;
210 nProcessPageHeight
= cy
;
212 /* Reposition the application page's controls */
213 GetWindowRect(hProcessPageListCtrl
, &rc
);
214 cx
= (rc
.right
- rc
.left
) + nXDifference
;
215 cy
= (rc
.bottom
- rc
.top
) + nYDifference
;
216 SetWindowPos(hProcessPageListCtrl
, NULL
, 0, 0, cx
, cy
, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOMOVE
|SWP_NOZORDER
);
217 InvalidateRect(hProcessPageListCtrl
, NULL
, TRUE
);
219 GetClientRect(hProcessPageEndProcessButton
, &rc
);
220 MapWindowPoints(hProcessPageEndProcessButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), sizeof(RECT
)/sizeof(POINT
));
221 cx
= rc
.left
+ nXDifference
;
222 cy
= rc
.top
+ nYDifference
;
223 SetWindowPos(hProcessPageEndProcessButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
224 InvalidateRect(hProcessPageEndProcessButton
, NULL
, TRUE
);
226 GetClientRect(hProcessPageShowAllProcessesButton
, &rc
);
227 MapWindowPoints(hProcessPageShowAllProcessesButton
, hDlg
, (LPPOINT
)(PRECT
)(&rc
), sizeof(RECT
)/sizeof(POINT
));
229 cy
= rc
.top
+ nYDifference
;
230 SetWindowPos(hProcessPageShowAllProcessesButton
, NULL
, cx
, cy
, 0, 0, SWP_NOACTIVATE
|SWP_NOOWNERZORDER
|SWP_NOSIZE
|SWP_NOZORDER
);
231 InvalidateRect(hProcessPageShowAllProcessesButton
, NULL
, TRUE
);
235 ProcessPageOnNotify(wParam
, lParam
);
239 if (wParam
== VK_DELETE
)
240 ProcessPage_OnEndProcess();
247 void ProcessPageOnNotify(WPARAM wParam
, LPARAM lParam
)
254 LPPROCESS_PAGE_LIST_ITEM pData
;
256 pnmh
= (LPNMHDR
) lParam
;
257 pnmdi
= (NMLVDISPINFO
*) lParam
;
258 pnmhdr
= (LPNMHEADER
) lParam
;
260 if (pnmh
->hwndFrom
== hProcessPageListCtrl
)
264 case LVN_ITEMCHANGED
:
268 case LVN_GETDISPINFO
:
270 if (!(pnmdi
->item
.mask
& LVIF_TEXT
))
273 pData
= (LPPROCESS_PAGE_LIST_ITEM
)pnmdi
->item
.lParam
;
274 Index
= PerfDataGetProcessIndex(pData
->ProcessId
);
275 ColumnIndex
= pnmdi
->item
.iSubItem
;
277 PerfDataGetText(Index
, ColumnIndex
, pnmdi
->item
.pszText
, (ULONG
)pnmdi
->item
.cchTextMax
);
283 ProcessPageShowContextMenu(GetSelectedProcessId());
288 if (((LPNMLVKEYDOWN
)lParam
)->wVKey
== VK_DELETE
)
289 ProcessPage_OnEndProcess();
294 else if (pnmh
->hwndFrom
== hProcessPageHeaderCtrl
)
300 TaskManagerSettings
.SortColumn
= ColumnDataHints
[pnmhdr
->iItem
];
301 TaskManagerSettings
.SortAscending
= !TaskManagerSettings
.SortAscending
;
302 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
306 case HDN_ITEMCHANGED
:
308 UpdateColumnDataHints();
314 UpdateColumnDataHints();
322 void CommaSeparateNumberString(LPWSTR strNumber
, ULONG nMaxCount
)
327 for (i
=0,j
=0; i
<(wcslen(strNumber
) % 3); i
++, j
++)
328 temp
[j
] = strNumber
[i
];
329 for (k
=0; i
<wcslen(strNumber
); i
++,j
++,k
++) {
330 if ((k
% 3 == 0) && (j
> 0))
332 temp
[j
] = strNumber
[i
];
335 wcsncpy(strNumber
, temp
, nMaxCount
);
338 void ProcessPageShowContextMenu(DWORD dwProcessId
)
346 DWORD dwProcessPriorityClass
;
347 WCHAR strDebugger
[260];
348 DWORD dwDebuggerSize
;
351 memset(&si
, 0, sizeof(SYSTEM_INFO
));
356 hMenu
= LoadMenuW(hInst
, MAKEINTRESOURCEW(IDR_PROCESS_PAGE_CONTEXT
));
357 hSubMenu
= GetSubMenu(hMenu
, 0);
358 hPriorityMenu
= GetSubMenu(hSubMenu
, 4);
360 hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
, FALSE
, dwProcessId
);
361 dwProcessPriorityClass
= GetPriorityClass(hProcess
);
362 CloseHandle(hProcess
);
364 if (si
.dwNumberOfProcessors
< 2)
365 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_SETAFFINITY
, MF_BYCOMMAND
);
367 if (!DebugChannelsAreSupported())
368 RemoveMenu(hSubMenu
, ID_PROCESS_PAGE_DEBUGCHANNELS
, MF_BYCOMMAND
);
370 switch (dwProcessPriorityClass
) {
371 case REALTIME_PRIORITY_CLASS
:
372 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, MF_BYCOMMAND
);
374 case HIGH_PRIORITY_CLASS
:
375 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_HIGH
, MF_BYCOMMAND
);
377 case ABOVE_NORMAL_PRIORITY_CLASS
:
378 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_ABOVENORMAL
, MF_BYCOMMAND
);
380 case NORMAL_PRIORITY_CLASS
:
381 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_NORMAL
, MF_BYCOMMAND
);
383 case BELOW_NORMAL_PRIORITY_CLASS
:
384 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_BELOWNORMAL
, MF_BYCOMMAND
);
386 case IDLE_PRIORITY_CLASS
:
387 CheckMenuRadioItem(hPriorityMenu
, ID_PROCESS_PAGE_SETPRIORITY_REALTIME
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, ID_PROCESS_PAGE_SETPRIORITY_LOW
, MF_BYCOMMAND
);
391 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
393 dwDebuggerSize
= sizeof(strDebugger
);
394 if (RegQueryValueExW(hKey
, L
"Debugger", NULL
, NULL
, (LPBYTE
)strDebugger
, &dwDebuggerSize
) == ERROR_SUCCESS
)
396 CharUpper(strDebugger
);
397 if (wcsstr(strDebugger
, L
"DRWTSN32"))
398 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
401 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
405 EnableMenuItem(hSubMenu
, ID_PROCESS_PAGE_DEBUG
, MF_BYCOMMAND
|MF_DISABLED
|MF_GRAYED
);
407 TrackPopupMenu(hSubMenu
, TPM_LEFTALIGN
|TPM_TOPALIGN
|TPM_LEFTBUTTON
, pt
.x
, pt
.y
, 0, hMainWnd
, NULL
);
411 void RefreshProcessPage(void)
414 /* Signal the event so that our refresh thread */
415 /* will wake up and refresh the process page */
416 PostThreadMessage(dwProcessThread
, WM_TIMER
, 0, 0);
420 DWORD WINAPI
ProcessPageRefreshThread(void *lpParameter
)
425 /* Wait for an the event or application close */
426 if (GetMessage(&msg
, NULL
, 0, 0) <= 0)
429 if (msg
.message
== WM_TIMER
) {
433 if (IsWindowVisible(hProcessPage
))
434 InvalidateRect(hProcessPageListCtrl
, NULL
, FALSE
);
442 void UpdateProcesses()
447 LPPROCESS_PAGE_LIST_ITEM pData
;
449 SendMessage(hProcessPageListCtrl
, WM_SETREDRAW
, FALSE
, 0);
451 /* Remove old processes */
452 for (i
= 0; i
< ListView_GetItemCount(hProcessPageListCtrl
); i
++)
454 memset(&item
, 0, sizeof (LV_ITEM
));
455 item
.mask
= LVIF_PARAM
;
457 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
458 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
459 if (!ProcessRunning(pData
->ProcessId
))
461 (void)ListView_DeleteItem(hProcessPageListCtrl
, i
);
462 HeapFree(GetProcessHeap(), 0, pData
);
466 /* Check for difference in listview process and performance process counts */
467 if (ListView_GetItemCount(hProcessPageListCtrl
) != PerfDataGetProcessCount())
469 /* Add new processes by checking against the current items */
470 for (l
= 0; l
< PerfDataGetProcessCount(); l
++)
476 if (TaskManagerSettings
.SortColumn
!= -1)
478 (void)ListView_SortItems(hProcessPageListCtrl
, ProcessPageCompareFunc
, NULL
);
481 SendMessage(hProcessPageListCtrl
, WM_SETREDRAW
, TRUE
, 0);
483 /* Select first item if any */
484 if ((ListView_GetNextItem(hProcessPageListCtrl
, -1, LVNI_FOCUSED
| LVNI_SELECTED
) == -1) &&
485 (ListView_GetItemCount(hProcessPageListCtrl
) > 0) && !bProcessPageSelectionMade
)
487 ListView_SetItemState(hProcessPageListCtrl
, 0, LVIS_FOCUSED
| LVIS_SELECTED
, LVIS_FOCUSED
| LVIS_SELECTED
);
488 bProcessPageSelectionMade
= TRUE
;
493 bProcessPageSelectionMade = FALSE;
498 BOOL
ProcessRunning(ULONG ProcessId
)
503 if (ProcessId
== 0) {
507 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, FALSE
, ProcessId
);
508 if (hProcess
== NULL
) {
512 if (GetExitCodeProcess(hProcess
, &exitCode
)) {
513 CloseHandle(hProcess
);
514 return (exitCode
== STILL_ACTIVE
);
517 CloseHandle(hProcess
);
521 void AddProcess(ULONG Index
)
523 LPPROCESS_PAGE_LIST_ITEM pData
;
526 BOOL bAlreadyInList
= FALSE
;
529 pid
= PerfDataGetProcessId(Index
);
531 /* Check to see if it's already in our list */
532 for (i
=0; i
<ListView_GetItemCount(hProcessPageListCtrl
); i
++)
534 memset(&item
, 0, sizeof(LV_ITEM
));
535 item
.mask
= LVIF_PARAM
;
537 (void)ListView_GetItem(hProcessPageListCtrl
, &item
);
538 pData
= (LPPROCESS_PAGE_LIST_ITEM
)item
.lParam
;
539 if (pData
->ProcessId
== pid
)
541 bAlreadyInList
= TRUE
;
545 if (!bAlreadyInList
) /* Add */
547 pData
= (LPPROCESS_PAGE_LIST_ITEM
)HeapAlloc(GetProcessHeap(), 0, sizeof(PROCESS_PAGE_LIST_ITEM
));
548 pData
->ProcessId
= pid
;
550 /* Add the item to the list */
551 memset(&item
, 0, sizeof(LV_ITEM
));
552 item
.mask
= LVIF_TEXT
|LVIF_PARAM
;
553 item
.pszText
= LPSTR_TEXTCALLBACK
;
554 item
.iItem
= ListView_GetItemCount(hProcessPageListCtrl
);
555 item
.lParam
= (LPARAM
)pData
;
556 (void)ListView_InsertItem(hProcessPageListCtrl
, &item
);
560 BOOL
PerfDataGetText(ULONG Index
, ULONG ColumnIndex
, LPTSTR lpText
, ULONG nMaxCount
)
562 IO_COUNTERS iocounters
;
565 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IMAGENAME
)
566 PerfDataGetImageName(Index
, lpText
, nMaxCount
);
567 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PID
)
568 wsprintfW(lpText
, L
"%lu", PerfDataGetProcessId(Index
));
569 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USERNAME
)
570 PerfDataGetUserName(Index
, lpText
, nMaxCount
);
571 if (ColumnDataHints
[ColumnIndex
] == COLUMN_COMMANDLINE
)
572 PerfDataGetCommandLine(Index
, lpText
, nMaxCount
);
573 if (ColumnDataHints
[ColumnIndex
] == COLUMN_SESSIONID
)
574 wsprintfW(lpText
, L
"%lu", PerfDataGetSessionId(Index
));
575 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUUSAGE
)
576 wsprintfW(lpText
, L
"%02lu", PerfDataGetCPUUsage(Index
));
577 if (ColumnDataHints
[ColumnIndex
] == COLUMN_CPUTIME
)
583 time
= PerfDataGetCPUTime(Index
);
584 gethmsfromlargeint(time
, &dwHours
, &dwMinutes
, &dwSeconds
);
585 wsprintfW(lpText
, L
"%lu:%02lu:%02lu", dwHours
, dwMinutes
, dwSeconds
);
587 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGE
)
589 wsprintfW(lpText
, L
"%lu", PerfDataGetWorkingSetSizeBytes(Index
) / 1024);
590 CommaSeparateNumberString(lpText
, nMaxCount
);
591 wcscat(lpText
, L
" K");
593 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PEAKMEMORYUSAGE
)
595 wsprintfW(lpText
, L
"%lu", PerfDataGetPeakWorkingSetSizeBytes(Index
) / 1024);
596 CommaSeparateNumberString(lpText
, nMaxCount
);
597 wcscat(lpText
, L
" K");
599 if (ColumnDataHints
[ColumnIndex
] == COLUMN_MEMORYUSAGEDELTA
)
601 wsprintfW(lpText
, L
"%lu", PerfDataGetWorkingSetSizeDelta(Index
) / 1024);
602 CommaSeparateNumberString(lpText
, nMaxCount
);
603 wcscat(lpText
, L
" K");
605 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTS
)
607 wsprintfW(lpText
, L
"%lu", PerfDataGetPageFaultCount(Index
));
608 CommaSeparateNumberString(lpText
, nMaxCount
);
610 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEFAULTSDELTA
)
612 wsprintfW(lpText
, L
"%lu", PerfDataGetPageFaultCountDelta(Index
));
613 CommaSeparateNumberString(lpText
, nMaxCount
);
615 if (ColumnDataHints
[ColumnIndex
] == COLUMN_VIRTUALMEMORYSIZE
)
617 wsprintfW(lpText
, L
"%lu", PerfDataGetVirtualMemorySizeBytes(Index
) / 1024);
618 CommaSeparateNumberString(lpText
, nMaxCount
);
619 wcscat(lpText
, L
" K");
621 if (ColumnDataHints
[ColumnIndex
] == COLUMN_PAGEDPOOL
)
623 wsprintfW(lpText
, L
"%lu", PerfDataGetPagedPoolUsagePages(Index
) / 1024);
624 CommaSeparateNumberString(lpText
, nMaxCount
);
625 wcscat(lpText
, L
" K");
627 if (ColumnDataHints
[ColumnIndex
] == COLUMN_NONPAGEDPOOL
)
629 wsprintfW(lpText
, L
"%lu", PerfDataGetNonPagedPoolUsagePages(Index
) / 1024);
630 CommaSeparateNumberString(lpText
, nMaxCount
);
631 wcscat(lpText
, L
" K");
633 if (ColumnDataHints
[ColumnIndex
] == COLUMN_BASEPRIORITY
)
634 wsprintfW(lpText
, L
"%lu", PerfDataGetBasePriority(Index
));
635 if (ColumnDataHints
[ColumnIndex
] == COLUMN_HANDLECOUNT
)
637 wsprintfW(lpText
, L
"%lu", PerfDataGetHandleCount(Index
));
638 CommaSeparateNumberString(lpText
, nMaxCount
);
640 if (ColumnDataHints
[ColumnIndex
] == COLUMN_THREADCOUNT
)
642 wsprintfW(lpText
, L
"%lu", PerfDataGetThreadCount(Index
));
643 CommaSeparateNumberString(lpText
, nMaxCount
);
645 if (ColumnDataHints
[ColumnIndex
] == COLUMN_USEROBJECTS
)
647 wsprintfW(lpText
, L
"%lu", PerfDataGetUSERObjectCount(Index
));
648 CommaSeparateNumberString(lpText
, nMaxCount
);
650 if (ColumnDataHints
[ColumnIndex
] == COLUMN_GDIOBJECTS
)
652 wsprintfW(lpText
, L
"%lu", PerfDataGetGDIObjectCount(Index
));
653 CommaSeparateNumberString(lpText
, nMaxCount
);
655 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADS
)
657 PerfDataGetIOCounters(Index
, &iocounters
);
658 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadOperationCount); */
659 _ui64tow(iocounters
.ReadOperationCount
, lpText
, 10);
660 CommaSeparateNumberString(lpText
, nMaxCount
);
662 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITES
)
664 PerfDataGetIOCounters(Index
, &iocounters
);
665 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteOperationCount); */
666 _ui64tow(iocounters
.WriteOperationCount
, lpText
, 10);
667 CommaSeparateNumberString(lpText
, nMaxCount
);
669 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHER
)
671 PerfDataGetIOCounters(Index
, &iocounters
);
672 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherOperationCount); */
673 _ui64tow(iocounters
.OtherOperationCount
, lpText
, 10);
674 CommaSeparateNumberString(lpText
, nMaxCount
);
676 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOREADBYTES
)
678 PerfDataGetIOCounters(Index
, &iocounters
);
679 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.ReadTransferCount); */
680 _ui64tow(iocounters
.ReadTransferCount
, lpText
, 10);
681 CommaSeparateNumberString(lpText
, nMaxCount
);
683 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOWRITEBYTES
)
685 PerfDataGetIOCounters(Index
, &iocounters
);
686 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.WriteTransferCount); */
687 _ui64tow(iocounters
.WriteTransferCount
, lpText
, 10);
688 CommaSeparateNumberString(lpText
, nMaxCount
);
690 if (ColumnDataHints
[ColumnIndex
] == COLUMN_IOOTHERBYTES
)
692 PerfDataGetIOCounters(Index
, &iocounters
);
693 /* wsprintfW(pnmdi->item.pszText, L"%d", iocounters.OtherTransferCount); */
694 _ui64tow(iocounters
.OtherTransferCount
, lpText
, 10);
695 CommaSeparateNumberString(lpText
, nMaxCount
);
702 void gethmsfromlargeint(LARGE_INTEGER largeint
, DWORD
*dwHours
, DWORD
*dwMinutes
, DWORD
*dwSeconds
)
705 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000L);
706 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000L) / 600000000L);
707 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000L) % 600000000L) / 10000000L);
709 *dwHours
= (DWORD
)(largeint
.QuadPart
/ 36000000000LL);
710 *dwMinutes
= (DWORD
)((largeint
.QuadPart
% 36000000000LL) / 600000000LL);
711 *dwSeconds
= (DWORD
)(((largeint
.QuadPart
% 36000000000LL) % 600000000LL) / 10000000LL);
715 int largeintcmp(LARGE_INTEGER l1
, LARGE_INTEGER l2
)
725 gethmsfromlargeint(l1
, &dwHours1
, &dwMinutes1
, &dwSeconds1
);
726 gethmsfromlargeint(l2
, &dwHours2
, &dwMinutes2
, &dwSeconds2
);
727 ret
= CMP(dwHours1
, dwHours2
);
730 ret
= CMP(dwMinutes1
, dwMinutes2
);
733 ret
= CMP(dwSeconds1
, dwSeconds2
);
739 int CALLBACK
ProcessPageCompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
742 LPPROCESS_PAGE_LIST_ITEM Param1
;
743 LPPROCESS_PAGE_LIST_ITEM Param2
;
752 IO_COUNTERS iocounters1
;
753 IO_COUNTERS iocounters2
;
757 if (TaskManagerSettings
.SortAscending
) {
758 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
759 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
761 Param1
= (LPPROCESS_PAGE_LIST_ITEM
)lParam2
;
762 Param2
= (LPPROCESS_PAGE_LIST_ITEM
)lParam1
;
764 IndexParam1
= PerfDataGetProcessIndex(Param1
->ProcessId
);
765 IndexParam2
= PerfDataGetProcessIndex(Param2
->ProcessId
);
767 if (TaskManagerSettings
.SortColumn
== COLUMN_IMAGENAME
)
769 PerfDataGetImageName(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
770 PerfDataGetImageName(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
771 ret
= _wcsicmp(text1
, text2
);
773 else if (TaskManagerSettings
.SortColumn
== COLUMN_PID
)
775 l1
= Param1
->ProcessId
;
776 l2
= Param2
->ProcessId
;
779 else if (TaskManagerSettings
.SortColumn
== COLUMN_USERNAME
)
781 PerfDataGetUserName(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
782 PerfDataGetUserName(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
783 ret
= _wcsicmp(text1
, text2
);
785 else if (TaskManagerSettings
.SortColumn
== COLUMN_COMMANDLINE
)
787 PerfDataGetCommandLine(IndexParam1
, text1
, sizeof (text1
) / sizeof (*text1
));
788 PerfDataGetCommandLine(IndexParam2
, text2
, sizeof (text2
) / sizeof (*text2
));
789 ret
= _wcsicmp(text1
, text2
);
791 else if (TaskManagerSettings
.SortColumn
== COLUMN_SESSIONID
)
793 l1
= PerfDataGetSessionId(IndexParam1
);
794 l2
= PerfDataGetSessionId(IndexParam2
);
797 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUUSAGE
)
799 l1
= PerfDataGetCPUUsage(IndexParam1
);
800 l2
= PerfDataGetCPUUsage(IndexParam2
);
803 else if (TaskManagerSettings
.SortColumn
== COLUMN_CPUTIME
)
805 time1
= PerfDataGetCPUTime(IndexParam1
);
806 time2
= PerfDataGetCPUTime(IndexParam2
);
807 ret
= largeintcmp(time1
, time2
);
809 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGE
)
811 l1
= PerfDataGetWorkingSetSizeBytes(IndexParam1
);
812 l2
= PerfDataGetWorkingSetSizeBytes(IndexParam2
);
815 else if (TaskManagerSettings
.SortColumn
== COLUMN_PEAKMEMORYUSAGE
)
817 l1
= PerfDataGetPeakWorkingSetSizeBytes(IndexParam1
);
818 l2
= PerfDataGetPeakWorkingSetSizeBytes(IndexParam2
);
821 else if (TaskManagerSettings
.SortColumn
== COLUMN_MEMORYUSAGEDELTA
)
823 l1
= PerfDataGetWorkingSetSizeDelta(IndexParam1
);
824 l2
= PerfDataGetWorkingSetSizeDelta(IndexParam2
);
827 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTS
)
829 l1
= PerfDataGetPageFaultCount(IndexParam1
);
830 l2
= PerfDataGetPageFaultCount(IndexParam2
);
833 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEFAULTSDELTA
)
835 l1
= PerfDataGetPageFaultCountDelta(IndexParam1
);
836 l2
= PerfDataGetPageFaultCountDelta(IndexParam2
);
839 else if (TaskManagerSettings
.SortColumn
== COLUMN_VIRTUALMEMORYSIZE
)
841 l1
= PerfDataGetVirtualMemorySizeBytes(IndexParam1
);
842 l2
= PerfDataGetVirtualMemorySizeBytes(IndexParam2
);
845 else if (TaskManagerSettings
.SortColumn
== COLUMN_PAGEDPOOL
)
847 l1
= PerfDataGetPagedPoolUsagePages(IndexParam1
);
848 l2
= PerfDataGetPagedPoolUsagePages(IndexParam2
);
851 else if (TaskManagerSettings
.SortColumn
== COLUMN_NONPAGEDPOOL
)
853 l1
= PerfDataGetNonPagedPoolUsagePages(IndexParam1
);
854 l2
= PerfDataGetNonPagedPoolUsagePages(IndexParam2
);
857 else if (TaskManagerSettings
.SortColumn
== COLUMN_BASEPRIORITY
)
859 l1
= PerfDataGetBasePriority(IndexParam1
);
860 l2
= PerfDataGetBasePriority(IndexParam2
);
863 else if (TaskManagerSettings
.SortColumn
== COLUMN_HANDLECOUNT
)
865 l1
= PerfDataGetHandleCount(IndexParam1
);
866 l2
= PerfDataGetHandleCount(IndexParam2
);
869 else if (TaskManagerSettings
.SortColumn
== COLUMN_THREADCOUNT
)
871 l1
= PerfDataGetThreadCount(IndexParam1
);
872 l2
= PerfDataGetThreadCount(IndexParam2
);
875 else if (TaskManagerSettings
.SortColumn
== COLUMN_USEROBJECTS
)
877 l1
= PerfDataGetUSERObjectCount(IndexParam1
);
878 l2
= PerfDataGetUSERObjectCount(IndexParam2
);
881 else if (TaskManagerSettings
.SortColumn
== COLUMN_GDIOBJECTS
)
883 l1
= PerfDataGetGDIObjectCount(IndexParam1
);
884 l2
= PerfDataGetGDIObjectCount(IndexParam2
);
887 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADS
)
889 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
890 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
891 ull1
= iocounters1
.ReadOperationCount
;
892 ull2
= iocounters2
.ReadOperationCount
;
893 ret
= CMP(ull1
, ull2
);
895 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITES
)
897 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
898 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
899 ull1
= iocounters1
.WriteOperationCount
;
900 ull2
= iocounters2
.WriteOperationCount
;
901 ret
= CMP(ull1
, ull2
);
903 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHER
)
905 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
906 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
907 ull1
= iocounters1
.OtherOperationCount
;
908 ull2
= iocounters2
.OtherOperationCount
;
909 ret
= CMP(ull1
, ull2
);
911 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOREADBYTES
)
913 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
914 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
915 ull1
= iocounters1
.ReadTransferCount
;
916 ull2
= iocounters2
.ReadTransferCount
;
917 ret
= CMP(ull1
, ull2
);
919 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOWRITEBYTES
)
921 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
922 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
923 ull1
= iocounters1
.WriteTransferCount
;
924 ull2
= iocounters2
.WriteTransferCount
;
925 ret
= CMP(ull1
, ull2
);
927 else if (TaskManagerSettings
.SortColumn
== COLUMN_IOOTHERBYTES
)
929 PerfDataGetIOCounters(IndexParam1
, &iocounters1
);
930 PerfDataGetIOCounters(IndexParam2
, &iocounters2
);
931 ull1
= iocounters1
.OtherTransferCount
;
932 ull2
= iocounters2
.OtherTransferCount
;
933 ret
= CMP(ull1
, ull2
);