added handle statistics window

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3464 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2010-08-02 08:13:43 +00:00
parent 6f38ddd238
commit fe04dab216
11 changed files with 296 additions and 9 deletions
+1
View File
@@ -6,6 +6,7 @@ Process Hacker
* Can now unload 32-bit modules on 64-bit systems
* Tasks are shown in tooltips for taskeng.exe/taskhost.exe processes
* Run As can now start processes elevated
* Handle count by type
* CSV export
* Relative start times
* FIXED:
+19 -1
View File
@@ -1219,13 +1219,14 @@ BEGIN
RTEXT "Static",IDC_ZIOOTHER_V,184,57,63,8,SS_ENDELLIPSIS
RTEXT "Static",IDC_ZIOOTHERBYTES_V,184,67,63,8,SS_ENDELLIPSIS
RTEXT "Static",IDC_ZIOPRIORITY_V,184,77,63,8,SS_ENDELLIPSIS
GROUPBOX "Other",IDC_STATIC,131,92,122,43
GROUPBOX "Other",IDC_STATIC,131,92,122,60
LTEXT "Handles",IDC_STATIC,138,102,26,8
LTEXT "GDI Handles",IDC_STATIC,138,112,40,8
LTEXT "USER Handles",IDC_STATIC,138,122,46,8
RTEXT "Static",IDC_ZHANDLES_V,193,102,54,8,SS_ENDELLIPSIS
RTEXT "Static",IDC_ZGDIHANDLES_V,193,112,54,8,SS_ENDELLIPSIS
RTEXT "Static",IDC_ZUSERHANDLES_V,193,122,54,8,SS_ENDELLIPSIS
PUSHBUTTON "Details",IDC_DETAILS,137,133,50,14
END
IDD_OPTADVANCED DIALOGEX 0, 0, 250, 85
@@ -1457,6 +1458,15 @@ BEGIN
PUSHBUTTON "Cleanup",IDC_CLEANUP,7,239,50,14
END
IDD_HANDLESTATS DIALOGEX 0, 0, 219, 175
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Handle Statistics"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "Close",IDOK,162,154,50,14
CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,205,143
END
/////////////////////////////////////////////////////////////////////////////
//
@@ -1881,6 +1891,14 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 253
END
IDD_HANDLESTATS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 212
TOPMARGIN, 7
BOTTOMMARGIN, 168
END
END
#endif // APSTUDIO_INVOKED
@@ -720,6 +720,10 @@
RelativePath=".\hndlprv.c"
>
</File>
<File
RelativePath=".\hndlstat.c"
>
</File>
<File
RelativePath=".\infodlg.c"
>
+2 -2
View File
@@ -257,7 +257,7 @@ __assumeLocked VOID PhpRemoveHandleItem(
PhDereferenceObject(HandleItem);
}
NTSTATUS PhpEnumHandlesGeneric(
NTSTATUS PhEnumHandlesGeneric(
__in HANDLE ProcessId,
__in HANDLE ProcessHandle,
__out PSYSTEM_HANDLE_INFORMATION_EX *Handles,
@@ -399,7 +399,7 @@ VOID PhHandleProviderUpdate(
if (!handleProvider->ProcessHandle)
return;
if (!NT_SUCCESS(PhpEnumHandlesGeneric(
if (!NT_SUCCESS(PhEnumHandlesGeneric(
handleProvider->ProcessId,
handleProvider->ProcessHandle,
&handleInfo,
+235
View File
@@ -0,0 +1,235 @@
/*
* Process Hacker -
* handle statistics window
*
* Copyright (C) 2010 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include <phapp.h>
typedef struct _HANDLE_STATISTICS_ENTRY
{
PPH_STRING Name;
ULONG Count;
} HANDLE_STATISTICS_ENTRY, *PHANDLE_STATISTICS_ENTRY;
typedef struct _HANDLE_STATISTICS_CONTEXT
{
HANDLE ProcessId;
HANDLE ProcessHandle;
PSYSTEM_HANDLE_INFORMATION_EX Handles;
HANDLE_STATISTICS_ENTRY Entries[MAX_OBJECT_TYPE_NUMBER];
} HANDLE_STATISTICS_CONTEXT, *PHANDLE_STATISTICS_CONTEXT;
INT_PTR CALLBACK PhpHandleStatisticsDlgProc(
__in HWND hwndDlg,
__in UINT uMsg,
__in WPARAM wParam,
__in LPARAM lParam
);
VOID PhShowHandleStatisticsDialog(
__in HWND ParentWindowHandle,
__in HANDLE ProcessId
)
{
NTSTATUS status;
HANDLE_STATISTICS_CONTEXT context;
BOOLEAN filterNeeded;
ULONG i;
context.ProcessId = ProcessId;
if (!NT_SUCCESS(status = PhOpenProcess(
&context.ProcessHandle,
PROCESS_DUP_HANDLE,
ProcessId
)))
{
PhShowStatus(ParentWindowHandle, L"Unable to open the process", status, 0);
return;
}
status = PhEnumHandlesGeneric(
context.ProcessId,
context.ProcessHandle,
&context.Handles,
&filterNeeded
);
if (!NT_SUCCESS(status))
{
NtClose(context.ProcessHandle);
PhShowStatus(ParentWindowHandle, L"Unable to enumerate process handles", status, 0);
return;
}
memset(&context.Entries, 0, sizeof(context.Entries));
DialogBoxParam(
PhInstanceHandle,
MAKEINTRESOURCE(IDD_HANDLESTATS),
ParentWindowHandle,
PhpHandleStatisticsDlgProc,
(LPARAM)&context
);
for (i = 0; i < MAX_OBJECT_TYPE_NUMBER; i++)
{
if (context.Entries[i].Name)
PhDereferenceObject(context.Entries[i].Name);
}
PhFree(context.Handles);
NtClose(context.ProcessHandle);
}
static INT NTAPI PhpTypeCountCompareFunction(
__in PVOID Item1,
__in PVOID Item2,
__in PVOID Context
)
{
PHANDLE_STATISTICS_ENTRY entry1 = Item1;
PHANDLE_STATISTICS_ENTRY entry2 = Item2;
return uintcmp(entry1->Count, entry2->Count);
}
INT_PTR CALLBACK PhpHandleStatisticsDlgProc(
__in HWND hwndDlg,
__in UINT uMsg,
__in WPARAM wParam,
__in LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
PHANDLE_STATISTICS_CONTEXT context = (PHANDLE_STATISTICS_CONTEXT)lParam;
HANDLE processId;
ULONG_PTR i;
HWND lvHandle;
processId = context->ProcessId;
for (i = 0; i < context->Handles->NumberOfHandles; i++)
{
PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo;
PHANDLE_STATISTICS_ENTRY entry;
PPH_STRING typeName;
handleInfo = &context->Handles->Handles[i];
if (handleInfo->UniqueProcessId != (ULONG_PTR)processId)
continue;
if (handleInfo->ObjectTypeIndex >= MAX_OBJECT_TYPE_NUMBER)
continue;
entry = &context->Entries[handleInfo->ObjectTypeIndex];
if (!entry->Name)
{
typeName = NULL;
PhGetHandleInformation(
context->ProcessHandle,
(HANDLE)handleInfo->HandleValue,
handleInfo->ObjectTypeIndex,
NULL,
&typeName,
NULL,
NULL
);
entry->Name = typeName;
}
entry->Count++;
}
lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
PhSetListViewStyle(lvHandle, FALSE, TRUE);
PhSetControlTheme(lvHandle, L"explorer");
PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 140, L"Type");
PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Count");
PhSetExtendedListView(lvHandle);
ExtendedListView_SetCompareFunction(lvHandle, 1, PhpTypeCountCompareFunction);
for (i = 0; i < MAX_OBJECT_TYPE_NUMBER; i++)
{
PHANDLE_STATISTICS_ENTRY entry;
PPH_STRING unknownType;
PPH_STRING countString;
INT lvItemIndex;
entry = &context->Entries[i];
if (entry->Count == 0)
continue;
unknownType = NULL;
if (!entry->Name)
unknownType = PhFormatString(L"(unknown: %u)", i);
countString = PhFormatUInt64(entry->Count, TRUE);
lvItemIndex = PhAddListViewItem(
lvHandle,
MAXINT,
entry->Name ? entry->Name->Buffer : unknownType->Buffer,
entry
);
PhSetListViewSubItem(lvHandle, lvItemIndex, 1, countString->Buffer);
PhDereferenceObject(countString);
if (unknownType)
PhDereferenceObject(unknownType);
}
ExtendedListView_SortItems(lvHandle);
}
break;
case WM_DESTROY:
{
// Nothing
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDCANCEL:
case IDOK:
EndDialog(hwndDlg, IDOK);
break;
}
}
break;
case WM_NOTIFY:
{
PhHandleListViewNotifyForCopy(lParam, GetDlgItem(hwndDlg, IDC_LIST));
}
break;
}
return FALSE;
}
+7
View File
@@ -1210,6 +1210,13 @@ VOID PhShowHandleProperties(
__in PPH_HANDLE_ITEM HandleItem
);
// hndlstat
VOID PhShowHandleStatisticsDialog(
__in HWND ParentWindowHandle,
__in HANDLE ProcessId
);
// infodlg
VOID PhShowInformationDialog(
@@ -629,6 +629,13 @@ VOID PhDereferenceAllHandleItems(
__in PPH_HANDLE_PROVIDER HandleProvider
);
NTSTATUS PhEnumHandlesGeneric(
__in HANDLE ProcessId,
__in HANDLE ProcessHandle,
__out PSYSTEM_HANDLE_INFORMATION_EX *Handles,
__out PBOOLEAN FilterNeeded
);
VOID PhHandleProviderUpdate(
__in PVOID Object
);
+12
View File
@@ -1195,6 +1195,18 @@ INT_PTR CALLBACK PhpProcessStatisticsDlgProc(
}
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_DETAILS:
{
PhShowHandleStatisticsDialog(hwndDlg, processItem->ProcessId);
}
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
+4 -2
View File
@@ -101,6 +101,7 @@
#define IDD_MEMSTRING 185
#define IDD_OPTGRAPHS 186
#define IDD_PLUGINS 187
#define IDD_HANDLESTATS 188
#define IDC_TERMINATE 1003
#define IDC_FILEICON 1005
#define IDC_FILE 1006
@@ -192,6 +193,7 @@
#define IDC_CLEAR 1079
#define IDC_GOTO 1079
#define IDC_OPTIONS 1079
#define IDC_DETAILS 1079
#define IDC_EDITDEP 1080
#define IDC_VIEWPARENTPROCESS 1081
#define IDC_OPENFILENAME 1082
@@ -610,9 +612,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 188
#define _APS_NEXT_RESOURCE_VALUE 189
#define _APS_NEXT_COMMAND_VALUE 40232
#define _APS_NEXT_CONTROL_VALUE 1260
#define _APS_NEXT_CONTROL_VALUE 1261
#define _APS_NEXT_SYMED_VALUE 131
#endif
#endif
+3 -4
View File
@@ -55,8 +55,7 @@ HANDLE PhQueryObjectStartEvent = NULL;
HANDLE PhQueryObjectCompletedEvent = NULL;
PH_QUERY_OBJECT_CONTEXT PhQueryObjectContext;
#define MAX_OBJECT_TYPE_NUMBER 256
PPH_STRING PhObjectTypeNames[MAX_OBJECT_TYPE_NUMBER + 1];
PPH_STRING PhObjectTypeNames[MAX_OBJECT_TYPE_NUMBER];
PPH_GET_CLIENT_ID_NAME PhHandleGetClientIdName = PhStdGetClientIdName;
static PPH_STRING HkcuPrefix;
@@ -171,7 +170,7 @@ NTSTATUS PhpGetObjectTypeName(
// If the cache contains the object type name, use it. Otherwise,
// query the type name.
if (ObjectTypeNumber != -1 && ObjectTypeNumber <= MAX_OBJECT_TYPE_NUMBER)
if (ObjectTypeNumber != -1 && ObjectTypeNumber < MAX_OBJECT_TYPE_NUMBER)
typeName = PhObjectTypeNames[ObjectTypeNumber];
if (typeName)
@@ -928,7 +927,7 @@ NTSTATUS PhGetHandleInformation(
if (Handle == NULL || Handle == NtCurrentProcess() || Handle == NtCurrentThread())
return STATUS_INVALID_HANDLE;
if (ObjectTypeNumber != -1 && ObjectTypeNumber > MAX_OBJECT_TYPE_NUMBER)
if (ObjectTypeNumber != -1 && ObjectTypeNumber >= MAX_OBJECT_TYPE_NUMBER)
return STATUS_INVALID_PARAMETER_3;
// Duplicate the handle if we're not using KPH.
+2
View File
@@ -1074,6 +1074,8 @@ NTSTATUS PhEnumAccounts(
// hndlinfo
#define MAX_OBJECT_TYPE_NUMBER 257
VOID PhHandleInfoInitialization();
typedef PPH_STRING (NTAPI *PPH_GET_CLIENT_ID_NAME)(