From 7fe2e8befcd2187486cac97482df49666a224b26 Mon Sep 17 00:00:00 2001 From: wj32 Date: Tue, 5 Jul 2011 12:22:29 +0000 Subject: [PATCH] converted network list to tree new git-svn-id: svn://svn.code.sf.net/p/processhacker/code@4297 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- 2.x/trunk/ProcessHacker/ProcessHacker.vcxproj | 1 + .../ProcessHacker.vcxproj.filters | 3 + 2.x/trunk/ProcessHacker/include/phapp.h | 5 +- 2.x/trunk/ProcessHacker/include/phplug.h | 3 +- 2.x/trunk/ProcessHacker/include/providers.h | 8 +- 2.x/trunk/ProcessHacker/include/uimodels.h | 80 ++ 2.x/trunk/ProcessHacker/main.c | 1 - 2.x/trunk/ProcessHacker/mainwnd.c | 429 ++-------- 2.x/trunk/ProcessHacker/modlist.c | 2 +- 2.x/trunk/ProcessHacker/netlist.c | 742 ++++++++++++++++++ 2.x/trunk/ProcessHacker/proctree.c | 1 - 2.x/trunk/ProcessHacker/resource.h | 3 +- 2.x/trunk/ProcessHacker/sdk/phapppub.h | 11 + 2.x/trunk/ProcessHacker/settings.c | 3 +- 2.x/trunk/ProcessHacker/srvlist.c | 3 +- 15 files changed, 924 insertions(+), 371 deletions(-) create mode 100644 2.x/trunk/ProcessHacker/netlist.c diff --git a/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj b/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj index 0220038e2..7e8604121 100644 --- a/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj +++ b/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj @@ -266,6 +266,7 @@ + diff --git a/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj.filters b/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj.filters index 1c1a9dc8a..608ee980b 100644 --- a/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj.filters +++ b/2.x/trunk/ProcessHacker/ProcessHacker.vcxproj.filters @@ -441,6 +441,9 @@ Process Hacker + + Process Hacker + diff --git a/2.x/trunk/ProcessHacker/include/phapp.h b/2.x/trunk/ProcessHacker/include/phapp.h index d066750bc..6cc77c069 100644 --- a/2.x/trunk/ProcessHacker/include/phapp.h +++ b/2.x/trunk/ProcessHacker/include/phapp.h @@ -26,7 +26,6 @@ extern PPH_STRING PhApplicationDirectory; extern PPH_STRING PhApplicationFileName; extern HFONT PhApplicationFont; -extern HFONT PhBoldListViewFont; extern HFONT PhBoldMessageFont; extern PPH_STRING PhCurrentUserName; extern HFONT PhIconTitleFont; @@ -470,6 +469,10 @@ VOID PhShowServiceContextMenu( __in POINT Location ); +VOID PhShowNetworkContextMenu( + __in POINT Location + ); + // plugins #ifndef PLUGINS_PRIVATE diff --git a/2.x/trunk/ProcessHacker/include/phplug.h b/2.x/trunk/ProcessHacker/include/phplug.h index d25af93f2..22ef94f99 100644 --- a/2.x/trunk/ProcessHacker/include/phplug.h +++ b/2.x/trunk/ProcessHacker/include/phplug.h @@ -28,7 +28,8 @@ typedef enum _PH_GENERAL_CALLBACK GeneralCallbackHandleMenuInitializing = 16, // PPH_PLUGIN_MENU_INFORMATION Data [properties thread] GeneralCallbackProcessTreeNewInitializing = 17, // PPH_PLUGIN_TREENEW_INFORMATION Data [main thread] GeneralCallbackServiceTreeNewInitializing = 18, // PPH_PLUGIN_TREENEW_INFORMATION Data [main thread] - GeneralCallbackModuleTreeNewInitializing = 19, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread] + GeneralCallbackNetworkTreeNewInitializing = 19, // PPH_PLUGIN_TREENEW_INFORMATION Data [main thread] + GeneralCallbackModuleTreeNewInitializing = 20, // PPH_PLUGIN_TREENEW_INFORMATION Data [properties thread] GeneralCallbackMaximum } PH_GENERAL_CALLBACK, *PPH_GENERAL_CALLBACK; diff --git a/2.x/trunk/ProcessHacker/include/providers.h b/2.x/trunk/ProcessHacker/include/providers.h index 715e08c42..7e5b56b47 100644 --- a/2.x/trunk/ProcessHacker/include/providers.h +++ b/2.x/trunk/ProcessHacker/include/providers.h @@ -402,10 +402,10 @@ VOID PhServiceProviderUpdate( #ifndef PH_NETPRV_PRIVATE extern PPH_OBJECT_TYPE PhNetworkItemType; -extern PH_CALLBACK PhNetworkItemAddedEvent; -extern PH_CALLBACK PhNetworkItemModifiedEvent; -extern PH_CALLBACK PhNetworkItemRemovedEvent; -extern PH_CALLBACK PhNetworkItemsUpdatedEvent; +PHAPPAPI extern PH_CALLBACK PhNetworkItemAddedEvent; +PHAPPAPI extern PH_CALLBACK PhNetworkItemModifiedEvent; +PHAPPAPI extern PH_CALLBACK PhNetworkItemRemovedEvent; +PHAPPAPI extern PH_CALLBACK PhNetworkItemsUpdatedEvent; extern BOOLEAN PhEnableNetworkProviderResolve; #endif diff --git a/2.x/trunk/ProcessHacker/include/uimodels.h b/2.x/trunk/ProcessHacker/include/uimodels.h index 9e4e71178..a31a885c1 100644 --- a/2.x/trunk/ProcessHacker/include/uimodels.h +++ b/2.x/trunk/ProcessHacker/include/uimodels.h @@ -432,6 +432,86 @@ VOID PhWriteServiceList( __in ULONG Mode ); +// netlist + +// Columns + +#define PHNETLC_PROCESS 0 +#define PHNETLC_LOCALADDRESS 1 +#define PHNETLC_LOCALPORT 2 +#define PHNETLC_REMOTEADDRESS 3 +#define PHNETLC_REMOTEPORT 4 +#define PHNETLC_PROTOCOL 5 +#define PHNETLC_STATE 6 +#define PHNETLC_OWNER 7 +#define PHNETLC_MAXIMUM 8 + +typedef struct _PH_NETWORK_NODE +{ + PH_TREENEW_NODE Node; + + PH_SH_STATE ShState; + + PPH_NETWORK_ITEM NetworkItem; + + PH_STRINGREF TextCache[PHNETLC_MAXIMUM]; + + PPH_STRING ProcessNameText; + PH_STRINGREF LocalAddressText; + PH_STRINGREF RemoteAddressText; + + PPH_STRING TooltipText; +} PH_NETWORK_NODE, *PPH_NETWORK_NODE; + +VOID PhNetworkTreeListInitialization(); + +VOID PhInitializeNetworkTreeList( + __in HWND hwnd + ); + +VOID PhLoadSettingsNetworkTreeList(); + +VOID PhSaveSettingsNetworkTreeList(); + +PPH_NETWORK_NODE PhAddNetworkNode( + __in PPH_NETWORK_ITEM NetworkItem, + __in ULONG RunId + ); + +PPH_NETWORK_NODE PhFindNetworkNode( + __in PPH_NETWORK_ITEM NetworkItem + ); + +VOID PhRemoveNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ); + +VOID PhUpdateNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ); + +VOID PhTickNetworkNodes(); + +PPH_NETWORK_ITEM PhGetSelectedNetworkItem(); + +VOID PhGetSelectedNetworkItems( + __out PPH_NETWORK_ITEM **NetworkItems, + __out PULONG NumberOfNetworkItems + ); + +VOID PhDeselectAllNetworkNodes(); + +VOID PhSelectAndEnsureVisibleNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ); + +VOID PhCopyNetworkList(); + +VOID PhWriteNetworkList( + __inout PPH_FILE_STREAM FileStream, + __in ULONG Mode + ); + // modlist // Columns diff --git a/2.x/trunk/ProcessHacker/main.c b/2.x/trunk/ProcessHacker/main.c index 03e75d895..5347acf64 100644 --- a/2.x/trunk/ProcessHacker/main.c +++ b/2.x/trunk/ProcessHacker/main.c @@ -47,7 +47,6 @@ VOID PhpEnablePrivileges(); PPH_STRING PhApplicationDirectory; PPH_STRING PhApplicationFileName; PHAPPAPI HFONT PhApplicationFont; -HFONT PhBoldListViewFont; HFONT PhBoldMessageFont; PPH_STRING PhCurrentUserName = NULL; HFONT PhIconTitleFont; diff --git a/2.x/trunk/ProcessHacker/mainwnd.c b/2.x/trunk/ProcessHacker/mainwnd.c index 12fc97dfb..e358990ec 100644 --- a/2.x/trunk/ProcessHacker/mainwnd.c +++ b/2.x/trunk/ProcessHacker/mainwnd.c @@ -73,14 +73,6 @@ VOID PhMainWndTabControlOnNotify( VOID PhMainWndTabControlOnSelectionChanged(); -VOID PhMainWndNetworkListViewOnNotify( - __in LPNMHDR Header - ); - -VOID PhMainWndNetworkListViewOnContextMenu( - __in LPARAM lParam - ); - VOID PhReloadSysParameters(); VOID PhpInitialLoadSettings(); @@ -154,20 +146,6 @@ VOID PhpGetSelectedProcesses( __out PULONG NumberOfProcesses ); -PPH_SERVICE_ITEM PhpGetSelectedService(); - -VOID PhpGetSelectedServices( - __out PPH_SERVICE_ITEM **Services, - __out PULONG NumberOfServices - ); - -PPH_NETWORK_ITEM PhpGetSelectedNetworkItem(); - -VOID PhpGetSelectedNetworkItems( - __out PPH_NETWORK_ITEM **NetworkItems, - __out PULONG NumberOfNetworkItems - ); - VOID PhpShowProcessProperties( __in PPH_PROCESS_ITEM ProcessItem ); @@ -212,7 +190,7 @@ VOID PhMainWndOnServicesUpdated(); VOID PhMainWndOnNetworkItemAdded( __in ULONG RunId, - __in PPH_NETWORK_ITEM NetworkItem + __in __assumeRefs(1) PPH_NETWORK_ITEM NetworkItem ); VOID PhMainWndOnNetworkItemModified( @@ -244,11 +222,12 @@ static INT MaxTabIndex; static PPH_LIST AdditionalTabPageList = NULL; static HWND ProcessTreeListHandle; static HWND ServiceTreeListHandle; -static HWND NetworkListViewHandle; +static HWND NetworkTreeListHandle; static HFONT CurrentCustomFont; static BOOLEAN NetworkFirstTime = TRUE; static BOOLEAN ServiceTreeListLoaded = FALSE; +static BOOLEAN NetworkTreeListLoaded = FALSE; static BOOLEAN UpdateAutomatically = TRUE; static PH_CALLBACK_REGISTRATION SymInitRegistration; @@ -275,8 +254,6 @@ static PH_CALLBACK_REGISTRATION NetworkItemModifiedRegistration; static PH_CALLBACK_REGISTRATION NetworkItemRemovedRegistration; static PH_CALLBACK_REGISTRATION NetworkItemsUpdatedRegistration; static BOOLEAN NetworkNeedsRedraw = FALSE; -static BOOLEAN NetworkNeedsSort = FALSE; -static PH_IMAGE_LIST_WRAPPER NetworkImageListWrapper; static PPH_PLUGIN_MENU_ITEM SelectedMenuItemPlugin; static ULONG SelectedRunAsMode; @@ -639,7 +616,7 @@ LRESULT CALLBACK PhMainWndProc( else if (selectedTab == ServicesTabIndex) PhWriteServiceList(fileStream, mode); else if (selectedTab == NetworkTabIndex) - lines = PhGetListViewLines(NetworkListViewHandle, mode); + lines = PhGetListViewLines(NetworkTreeListHandle, mode); if (lines) { @@ -1382,7 +1359,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_GOTOPROCESS: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); PPH_PROCESS_NODE processNode; if (serviceItem) @@ -1398,7 +1375,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_START: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); if (serviceItem) { @@ -1410,7 +1387,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_CONTINUE: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); if (serviceItem) { @@ -1422,7 +1399,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_PAUSE: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); if (serviceItem) { @@ -1434,7 +1411,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_STOP: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); if (serviceItem) { @@ -1446,7 +1423,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_DELETE: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); if (serviceItem) { @@ -1461,7 +1438,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_SERVICE_PROPERTIES: { - PPH_SERVICE_ITEM serviceItem = PhpGetSelectedService(); + PPH_SERVICE_ITEM serviceItem = PhGetSelectedServiceItem(); if (serviceItem) { @@ -1480,7 +1457,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_NETWORK_GOTOPROCESS: { - PPH_NETWORK_ITEM networkItem = PhpGetSelectedNetworkItem(); + PPH_NETWORK_ITEM networkItem = PhGetSelectedNetworkItem(); PPH_PROCESS_NODE processNode; if (networkItem) @@ -1496,7 +1473,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_NETWORK_VIEWSTACK: { - PPH_NETWORK_ITEM networkItem = PhpGetSelectedNetworkItem(); + PPH_NETWORK_ITEM networkItem = PhGetSelectedNetworkItem(); if (networkItem) { @@ -1511,11 +1488,11 @@ LRESULT CALLBACK PhMainWndProc( PPH_NETWORK_ITEM *networkItems; ULONG numberOfNetworkItems; - PhpGetSelectedNetworkItems(&networkItems, &numberOfNetworkItems); + PhGetSelectedNetworkItems(&networkItems, &numberOfNetworkItems); PhReferenceObjects(networkItems, numberOfNetworkItems); if (PhUiCloseConnections(hWnd, networkItems, numberOfNetworkItems)) - PhSetStateAllListViewItems(NetworkListViewHandle, 0, LVIS_SELECTED); + PhSetStateAllListViewItems(NetworkTreeListHandle, 0, LVIS_SELECTED); PhDereferenceObjects(networkItems, numberOfNetworkItems); PhFree(networkItems); @@ -1523,7 +1500,7 @@ LRESULT CALLBACK PhMainWndProc( break; case ID_NETWORK_COPY: { - PhCopyListView(NetworkListViewHandle); + PhCopyListView(NetworkTreeListHandle); } break; case ID_TAB_NEXT: @@ -1673,7 +1650,7 @@ LRESULT CALLBACK PhMainWndProc( else if (selectedIndex == ServicesTabIndex) SetFocus(ServiceTreeListHandle); else if (selectedIndex == NetworkTabIndex) - SetFocus(NetworkListViewHandle); + SetFocus(NetworkTreeListHandle); } break; case WM_NOTIFY: @@ -1684,10 +1661,6 @@ LRESULT CALLBACK PhMainWndProc( { PhMainWndTabControlOnNotify(header); } - else if (header->hwndFrom == NetworkListViewHandle) - { - PhMainWndNetworkListViewOnNotify(header); - } else if (header->code == RFN_VALIDATE) { LPNMRUNFILEDLG runFileDlg = (LPNMRUNFILEDLG)header; @@ -1752,14 +1725,6 @@ LRESULT CALLBACK PhMainWndProc( } } break; - case WM_CONTEXTMENU: - { - if ((HWND)wParam == NetworkListViewHandle) - { - PhMainWndNetworkListViewOnContextMenu(lParam); - } - } - break; case WM_WTSSESSION_CHANGE: { if (wParam == WTS_SESSION_LOGON || wParam == WTS_SESSION_LOGOFF) @@ -1906,7 +1871,7 @@ LRESULT CALLBACK PhMainWndProc( else if (index == ServicesTabIndex) SetFocus(ServiceTreeListHandle); else if (index == NetworkTabIndex) - SetFocus(NetworkListViewHandle); + SetFocus(NetworkTreeListHandle); } break; case WM_PH_GET_LAYOUT_PADDING: @@ -1945,12 +1910,12 @@ LRESULT CALLBACK PhMainWndProc( { INT lvItemIndex; - PhSetStateAllListViewItems(NetworkListViewHandle, 0, LVIS_SELECTED); - lvItemIndex = PhFindListViewItemByParam(NetworkListViewHandle, -1, (PVOID)lParam); + PhSetStateAllListViewItems(NetworkTreeListHandle, 0, LVIS_SELECTED); + lvItemIndex = PhFindListViewItemByParam(NetworkTreeListHandle, -1, (PVOID)lParam); if (lvItemIndex != -1) { - ListView_SetItemState(NetworkListViewHandle, lvItemIndex, + ListView_SetItemState(NetworkTreeListHandle, lvItemIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } } @@ -1980,7 +1945,7 @@ LRESULT CALLBACK PhMainWndProc( SendMessage(ProcessTreeListHandle, WM_SETFONT, (WPARAM)newFont, TRUE); SendMessage(ServiceTreeListHandle, WM_SETFONT, (WPARAM)newFont, TRUE); - SendMessage(NetworkListViewHandle, WM_SETFONT, (WPARAM)newFont, TRUE); + SendMessage(NetworkTreeListHandle, WM_SETFONT, (WPARAM)newFont, TRUE); } } @@ -2072,7 +2037,6 @@ LRESULT CALLBACK PhMainWndProc( PPH_NETWORK_ITEM networkItem = (PPH_NETWORK_ITEM)lParam; PhMainWndOnNetworkItemAdded(runId, networkItem); - PhDereferenceObject(networkItem); } break; case WM_PH_NETWORK_ITEM_MODIFIED: @@ -2092,34 +2056,11 @@ LRESULT CALLBACK PhMainWndProc( break; } - REFLECT_MESSAGE(NetworkListViewHandle, uMsg, wParam, lParam); + REFLECT_MESSAGE(NetworkTreeListHandle, uMsg, wParam, lParam); return DefWindowProc(hWnd, uMsg, wParam, lParam); } -VOID PhpReloadListViewFont() -{ - HFONT fontHandle; - LOGFONT font; - - if (NetworkListViewHandle && (fontHandle = (HFONT)SendMessage(NetworkListViewHandle, WM_GETFONT, 0, 0))) - { - if (GetObject(fontHandle, sizeof(LOGFONT), &font)) - { - font.lfWeight = FW_BOLD; - fontHandle = CreateFontIndirect(&font); - - if (fontHandle) - { - if (PhBoldListViewFont) - DeleteObject(PhBoldListViewFont); - - PhBoldListViewFont = fontHandle; - } - } - } -} - VOID PhReloadSysParameters() { PhSysWindowColor = GetSysColor(COLOR_WINDOW); @@ -2130,8 +2071,6 @@ VOID PhReloadSysParameters() DeleteObject(PhBoldMessageFont); PhInitializeFont(PhMainWndHandle); SendMessage(TabControlHandle, WM_SETFONT, (WPARAM)PhApplicationFont, FALSE); - - PhpReloadListViewFont(); } VOID PhpInitialLoadSettings() @@ -2245,8 +2184,7 @@ VOID PhpInitialLoadSettings() PhDereferenceObject(customFont); PhLoadSettingsProcessTreeList(); - // Service list settings are loaded on demand. - PhLoadListViewColumnsFromSetting(L"NetworkListViewColumns", NetworkListViewHandle); + // Service and network list settings are loaded on demand. } VOID PhMainSymInitHandler( @@ -2336,7 +2274,8 @@ VOID PhpSaveAllSettings() PhSaveSettingsProcessTreeList(); if (ServiceTreeListLoaded) PhSaveSettingsServiceTreeList(); - PhSaveListViewColumnsToSetting(L"NetworkListViewColumns", NetworkListViewHandle); + if (NetworkTreeListLoaded) + PhSaveSettingsNetworkTreeList(); PhSetIntegerSetting(L"IconMask", NotifyIconMask); PhSetIntegerSetting(L"IconNotifyMask", NotifyIconNotifyMask); @@ -2435,6 +2374,16 @@ VOID PhpNeedServiceTreeList() } } +VOID PhpNeedNetworkTreeList() +{ + if (!NetworkTreeListLoaded) + { + NetworkTreeListLoaded = TRUE; + + PhLoadSettingsNetworkTreeList(); + } +} + BOOLEAN PhpProcessComputerCommand( __in ULONG Id ) @@ -3037,38 +2986,6 @@ VOID PhpShowProcessProperties( } } -PPH_SERVICE_ITEM PhpGetSelectedService() -{ - return PhGetSelectedServiceItem(); -} - -VOID PhpGetSelectedServices( - __out PPH_SERVICE_ITEM **Services, - __out PULONG NumberOfServices - ) -{ - PhGetSelectedServiceItems(Services, NumberOfServices); -} - -PPH_NETWORK_ITEM PhpGetSelectedNetworkItem() -{ - return PhGetSelectedListViewItemParam( - NetworkListViewHandle - ); -} - -VOID PhpGetSelectedNetworkItems( - __out PPH_NETWORK_ITEM **NetworkItems, - __out PULONG NumberOfNetworkItems - ) -{ - PhGetSelectedListViewItemParams( - NetworkListViewHandle, - NetworkItems, - NumberOfNetworkItems - ); -} - static VOID NTAPI ProcessAddedHandler( __in_opt PVOID Parameter, __in_opt PVOID Context @@ -3280,24 +3197,20 @@ VOID PhMainWndOnCreate() ); BringWindowToTop(ServiceTreeListHandle); - NetworkListViewHandle = PhCreateListViewControl(PhMainWndHandle, ID_MAINWND_NETWORKLV); - PhSetListViewStyle(NetworkListViewHandle, TRUE, TRUE); - SendMessage(ListView_GetToolTips(NetworkListViewHandle), TTM_SETDELAYTIME, TTDT_AUTOPOP, 0x7fff); - BringWindowToTop(NetworkListViewHandle); - PhpReloadListViewFont(); - - PhSetControlTheme(NetworkListViewHandle, L"explorer"); - - PhAddListViewColumn(NetworkListViewHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Process"); - PhAddListViewColumn(NetworkListViewHandle, 1, 1, 1, LVCFMT_LEFT, 120, L"Local Address"); - PhAddListViewColumn(NetworkListViewHandle, 2, 2, 2, LVCFMT_RIGHT, 50, L"Local Port"); - PhAddListViewColumn(NetworkListViewHandle, 3, 3, 3, LVCFMT_LEFT, 120, L"Remote Address"); - PhAddListViewColumn(NetworkListViewHandle, 4, 4, 4, LVCFMT_RIGHT, 50, L"Remote Port"); - PhAddListViewColumn(NetworkListViewHandle, 5, 5, 5, LVCFMT_LEFT, 45, L"Protocol"); - PhAddListViewColumn(NetworkListViewHandle, 6, 6, 6, LVCFMT_LEFT, 70, L"State"); - - if (WINDOWS_HAS_SERVICE_TAGS) - PhAddListViewColumn(NetworkListViewHandle, 7, 7, 7, LVCFMT_LEFT, 80, L"Owner"); + NetworkTreeListHandle = CreateWindow( + PH_TREENEW_CLASSNAME, + L"", + WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_BORDER | TN_STYLE_ICONS | TN_STYLE_DOUBLE_BUFFERED, + 0, + 0, + 3, + 3, + PhMainWndHandle, + (HMENU)ID_MAINWND_NETWORKTL, + PhLibImageBase, + NULL + ); + BringWindowToTop(NetworkTreeListHandle); PhProcessTreeListInitialization(); PhInitializeProcessTreeList(ProcessTreeListHandle); @@ -3305,8 +3218,8 @@ VOID PhMainWndOnCreate() PhServiceTreeListInitialization(); PhInitializeServiceTreeList(ServiceTreeListHandle); - PhSetExtendedListViewWithSettings(NetworkListViewHandle); - ExtendedListView_SetStateHighlighting(NetworkListViewHandle, TRUE); + PhNetworkTreeListInitialization(); + PhInitializeNetworkTreeList(NetworkTreeListHandle); PhRegisterCallback( &PhProcessAddedEvent, @@ -3579,7 +3492,7 @@ VOID PhMainWndTabControlOnLayout( } else if (selectedIndex == NetworkTabIndex) { - *deferHandle = DeferWindowPos(*deferHandle, NetworkListViewHandle, NULL, + *deferHandle = DeferWindowPos(*deferHandle, NetworkTreeListHandle, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); } @@ -3641,6 +3554,8 @@ VOID PhMainWndTabControlOnSelectionChanged() if (selectedIndex == NetworkTabIndex) { + PhpNeedNetworkTreeList(); + PhSetEnabledProvider(&NetworkProviderRegistration, UpdateAutomatically); if (UpdateAutomatically || NetworkFirstTime) @@ -3656,7 +3571,7 @@ VOID PhMainWndTabControlOnSelectionChanged() ShowWindow(ProcessTreeListHandle, selectedIndex == ProcessesTabIndex ? SW_SHOW : SW_HIDE); ShowWindow(ServiceTreeListHandle, selectedIndex == ServicesTabIndex ? SW_SHOW : SW_HIDE); - ShowWindow(NetworkListViewHandle, selectedIndex == NetworkTabIndex ? SW_SHOW : SW_HIDE); + ShowWindow(NetworkTreeListHandle, selectedIndex == NetworkTabIndex ? SW_SHOW : SW_HIDE); // Additional tabs @@ -4124,7 +4039,7 @@ VOID PhShowServiceContextMenu( PPH_SERVICE_ITEM *services; ULONG numberOfServices; - PhpGetSelectedServices(&services, &numberOfServices); + PhGetSelectedServiceItems(&services, &numberOfServices); if (numberOfServices != 0) { @@ -4228,75 +4143,14 @@ VOID PhpInitializeNetworkMenu( } } -VOID PhMainWndNetworkListViewOnNotify( - __in LPNMHDR Header +VOID PhShowNetworkContextMenu( + __in POINT Location ) { - switch (Header->code) - { - case NM_DBLCLK: - { - SendMessage(PhMainWndHandle, WM_COMMAND, ID_NETWORK_GOTOPROCESS, 0); - } - break; - case LVN_KEYDOWN: - { - LPNMLVKEYDOWN keyDown = (LPNMLVKEYDOWN)Header; - - switch (keyDown->wVKey) - { - case 'C': - if (GetKeyState(VK_CONTROL) < 0) - SendMessage(PhMainWndHandle, WM_COMMAND, ID_NETWORK_COPY, 0); - break; - case VK_RETURN: - SendMessage(PhMainWndHandle, WM_COMMAND, ID_NETWORK_GOTOPROCESS, 0); - break; - } - } - break; - case LVN_GETINFOTIP: - { - LPNMLVGETINFOTIP getInfoTip = (LPNMLVGETINFOTIP)Header; - PPH_NETWORK_ITEM networkItem; - - if (getInfoTip->iSubItem == 0 && PhGetListViewItemParam( - NetworkListViewHandle, - getInfoTip->iItem, - &networkItem - )) - { - PPH_PROCESS_ITEM processItem; - PPH_STRING tip; - - if (processItem = PhReferenceProcessItem(networkItem->ProcessId)) - { - tip = PhGetProcessTooltipText(processItem); - PhCopyListViewInfoTip(getInfoTip, &tip->sr); - PhDereferenceObject(tip); - PhDereferenceObject(processItem); - } - } - } - break; - } -} - -VOID PhMainWndNetworkListViewOnContextMenu( - __in LPARAM lParam - ) -{ - POINT point; PPH_NETWORK_ITEM *networkItems; ULONG numberOfNetworkItems; - point.x = (SHORT)LOWORD(lParam); - point.y = (SHORT)HIWORD(lParam); - - if (point.x == -1 && point.y == -1) - PhGetListViewContextMenuPoint(NetworkListViewHandle, &point); - - PhpGetSelectedNetworkItems(&networkItems, &numberOfNetworkItems); + PhGetSelectedNetworkItems(&networkItems, &numberOfNetworkItems); if (numberOfNetworkItems != 0) { @@ -4326,8 +4180,8 @@ VOID PhMainWndNetworkListViewOnContextMenu( PhMainWndHandle, PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, - point.x, - point.y + Location.x, + Location.y ); if (item) @@ -4661,189 +4515,50 @@ VOID PhMainWndOnServicesUpdated() } } -PWSTR PhpGetNetworkItemProcessName( - __in PPH_NETWORK_ITEM NetworkItem - ) -{ - PPH_STRING string; - PH_FORMAT format[4]; - - if (!NetworkItem->ProcessId) - return L"Waiting Connections"; - - PhInitFormatS(&format[1], L" ("); - PhInitFormatU(&format[2], (ULONG)NetworkItem->ProcessId); - PhInitFormatC(&format[3], ')'); - - if (NetworkItem->ProcessName) - PhInitFormatSR(&format[0], NetworkItem->ProcessName->sr); - else - PhInitFormatS(&format[0], L"Unknown Process"); - - string = PhFormat(format, 4, 96); - PhaDereferenceObject(string); - - return string->Buffer; -} - -VOID PhpSetNetworkItemImageIndex( - __in INT ItemIndex, - __in PPH_NETWORK_ITEM NetworkItem - ) -{ - INT imageIndex; - - if (NetworkItem->ProcessIconValid && NetworkItem->ProcessIcon) - { - imageIndex = PhImageListWrapperAddIcon(&NetworkImageListWrapper, NetworkItem->ProcessIcon); - } - else - { - imageIndex = 0; - } - - PhSetListViewItemImageIndex(NetworkListViewHandle, ItemIndex, imageIndex); -} - VOID PhMainWndOnNetworkItemAdded( __in ULONG RunId, - __in PPH_NETWORK_ITEM NetworkItem + __in __assumeRefs(1) PPH_NETWORK_ITEM NetworkItem ) { - INT lvItemIndex; + PPH_NETWORK_NODE networkNode; if (!NetworkNeedsRedraw) { - ExtendedListView_SetRedraw(NetworkListViewHandle, FALSE); + TreeNew_SetRedraw(NetworkTreeListHandle, FALSE); NetworkNeedsRedraw = TRUE; } - // Add a reference for the pointer being stored in the list view item. - PhReferenceObject(NetworkItem); - - if (RunId == 1) ExtendedListView_SetStateHighlighting(NetworkListViewHandle, FALSE); - lvItemIndex = PhAddListViewItem( - NetworkListViewHandle, - MAXINT, - PhpGetNetworkItemProcessName(NetworkItem), - NetworkItem - ); - if (RunId == 1) ExtendedListView_SetStateHighlighting(NetworkListViewHandle, TRUE); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 1, - PhGetStringOrDefault(NetworkItem->LocalHostString, NetworkItem->LocalAddressString)); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 2, NetworkItem->LocalPortString); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 3, - PhGetStringOrDefault(NetworkItem->RemoteHostString, NetworkItem->RemoteAddressString)); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 4, NetworkItem->RemotePortString); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 5, PhGetProtocolTypeName(NetworkItem->ProtocolType)); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 6, - (NetworkItem->ProtocolType & PH_TCP_PROTOCOL_TYPE) ? PhGetTcpStateName(NetworkItem->State) : NULL); - - if (WINDOWS_HAS_SERVICE_TAGS) - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 7, PhGetString(NetworkItem->OwnerName)); - - if (!NetworkImageListWrapper.Handle) - { - HICON icon; - - PhGetStockApplicationIcon(&icon, NULL); - PhInitializeImageListWrapper(&NetworkImageListWrapper, PhSmallIconSize.X, PhSmallIconSize.Y, ILC_COLOR32 | ILC_MASK); - PhImageListWrapperAddIcon(&NetworkImageListWrapper, icon); - ListView_SetImageList(NetworkListViewHandle, NetworkImageListWrapper.Handle, LVSIL_SMALL); - } - - PhpSetNetworkItemImageIndex(lvItemIndex, NetworkItem); - - NetworkNeedsSort = TRUE; + networkNode = PhAddNetworkNode(NetworkItem, RunId); + PhDereferenceObject(NetworkItem); } VOID PhMainWndOnNetworkItemModified( __in PPH_NETWORK_ITEM NetworkItem ) { - INT lvItemIndex; - INT imageIndex; - - if (!NetworkNeedsRedraw) - { - ExtendedListView_SetRedraw(NetworkListViewHandle, FALSE); - NetworkNeedsRedraw = TRUE; - } - - lvItemIndex = PhFindListViewItemByParam(NetworkListViewHandle, -1, NetworkItem); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 0, - PhpGetNetworkItemProcessName(NetworkItem)); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 1, - PhGetStringOrDefault(NetworkItem->LocalHostString, NetworkItem->LocalAddressString)); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 3, - PhGetStringOrDefault(NetworkItem->RemoteHostString, NetworkItem->RemoteAddressString)); - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 6, - (NetworkItem->ProtocolType & PH_TCP_PROTOCOL_TYPE) ? PhGetTcpStateName(NetworkItem->State) : NULL); - - if (WINDOWS_HAS_SERVICE_TAGS) - PhSetListViewSubItem(NetworkListViewHandle, lvItemIndex, 7, PhGetString(NetworkItem->OwnerName)); - - // Only set a new icon if we didn't have a proper one before. - if (PhGetListViewItemImageIndex( - NetworkListViewHandle, - lvItemIndex, - &imageIndex - ) && imageIndex == 0) - { - PhpSetNetworkItemImageIndex(lvItemIndex, NetworkItem); - } - - NetworkNeedsSort = TRUE; + PhUpdateNetworkNode(PhFindNetworkNode(NetworkItem)); } VOID PhMainWndOnNetworkItemRemoved( __in PPH_NETWORK_ITEM NetworkItem ) { - INT lvItemIndex; - INT imageIndex; - if (!NetworkNeedsRedraw) { - ExtendedListView_SetRedraw(NetworkListViewHandle, FALSE); + TreeNew_SetRedraw(NetworkTreeListHandle, FALSE); NetworkNeedsRedraw = TRUE; } - lvItemIndex = PhFindListViewItemByParam(NetworkListViewHandle, -1, NetworkItem); - - if (PhGetListViewItemImageIndex( - NetworkListViewHandle, - lvItemIndex, - &imageIndex - ) && imageIndex != 0) - { - PhImageListWrapperRemove(&NetworkImageListWrapper, imageIndex); - // Set to a generic icon so we don't get random icons popping up due to - // the delay caused by state highlighting. - PhSetListViewItemImageIndex(NetworkListViewHandle, lvItemIndex, 0); - } - - PhRemoveListViewItem( - NetworkListViewHandle, - lvItemIndex - ); - // Remove the reference we added in PhMainWndOnNetworkItemAdded. - PhDereferenceObject(NetworkItem); + PhRemoveNetworkNode(PhFindNetworkNode(NetworkItem)); } VOID PhMainWndOnNetworkItemsUpdated() { - ExtendedListView_Tick(NetworkListViewHandle); - - if (NetworkNeedsSort) - { - ExtendedListView_SortItems(NetworkListViewHandle); - NetworkNeedsSort = FALSE; - } + PhTickNetworkNodes(); if (NetworkNeedsRedraw) { - ExtendedListView_SetRedraw(NetworkListViewHandle, TRUE); + TreeNew_SetRedraw(NetworkTreeListHandle, TRUE); NetworkNeedsRedraw = FALSE; } } diff --git a/2.x/trunk/ProcessHacker/modlist.c b/2.x/trunk/ProcessHacker/modlist.c index db1a2d4c4..04bb60433 100644 --- a/2.x/trunk/ProcessHacker/modlist.c +++ b/2.x/trunk/ProcessHacker/modlist.c @@ -661,7 +661,7 @@ BOOLEAN NTAPI PhpModuleTreeNewCallback( } } - getNodeFont->Font = context->BoldFont ? context->BoldFont : PhBoldListViewFont; + getNodeFont->Font = context->BoldFont ? context->BoldFont : NULL; getNodeFont->Flags = TN_CACHE; return TRUE; } diff --git a/2.x/trunk/ProcessHacker/netlist.c b/2.x/trunk/ProcessHacker/netlist.c new file mode 100644 index 000000000..41a9d4e94 --- /dev/null +++ b/2.x/trunk/ProcessHacker/netlist.c @@ -0,0 +1,742 @@ +/* + * Process Hacker - + * network list + * + * Copyright (C) 2011 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 . + */ + +#include +#include +#include +#include + +BOOLEAN PhpNetworkNodeHashtableCompareFunction( + __in PVOID Entry1, + __in PVOID Entry2 + ); + +ULONG PhpNetworkNodeHashtableHashFunction( + __in PVOID Entry + ); + +VOID PhpRemoveNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ); + +LONG PhpNetworkTreeNewPostSortFunction( + __in LONG Result, + __in PVOID Node1, + __in PVOID Node2, + __in PH_SORT_ORDER SortOrder + ); + +BOOLEAN NTAPI PhpNetworkTreeNewCallback( + __in HWND hwnd, + __in PH_TREENEW_MESSAGE Message, + __in_opt PVOID Parameter1, + __in_opt PVOID Parameter2, + __in_opt PVOID Context + ); + +PPH_STRING PhpGetNetworkItemProcessName( + __in PPH_NETWORK_ITEM NetworkItem + ); + +VOID PhpUpdateNetworkNodeAddressStrings( + __in PPH_NETWORK_NODE NetworkNode + ); + +static HWND NetworkTreeListHandle; +static ULONG NetworkTreeListSortColumn; +static PH_SORT_ORDER NetworkTreeListSortOrder; +static PH_CM_MANAGER NetworkTreeListCm; + +static PPH_HASHTABLE NetworkNodeHashtable; // hashtable of all nodes +static PPH_LIST NetworkNodeList; // list of all nodes + +BOOLEAN PhNetworkTreeListStateHighlighting = TRUE; +static PPH_POINTER_LIST NetworkNodeStateList = NULL; // list of nodes which need to be processed + +VOID PhNetworkTreeListInitialization() +{ + NetworkNodeHashtable = PhCreateHashtable( + sizeof(PPH_NETWORK_NODE), + PhpNetworkNodeHashtableCompareFunction, + PhpNetworkNodeHashtableHashFunction, + 100 + ); + NetworkNodeList = PhCreateList(100); +} + +BOOLEAN PhpNetworkNodeHashtableCompareFunction( + __in PVOID Entry1, + __in PVOID Entry2 + ) +{ + PPH_NETWORK_NODE networkNode1 = *(PPH_NETWORK_NODE *)Entry1; + PPH_NETWORK_NODE networkNode2 = *(PPH_NETWORK_NODE *)Entry2; + + return networkNode1->NetworkItem == networkNode2->NetworkItem; +} + +ULONG PhpNetworkNodeHashtableHashFunction( + __in PVOID Entry + ) +{ +#ifdef _M_IX86 + return PhHashInt32((ULONG)(*(PPH_NETWORK_NODE *)Entry)->NetworkItem); +#else + return PhHashInt64((ULONG64)(*(PPH_NETWORK_NODE *)Entry)->NetworkItem); +#endif +} + +VOID PhInitializeNetworkTreeList( + __in HWND hwnd + ) +{ + PH_PLUGIN_TREENEW_INFORMATION treeNewInfo; + + NetworkTreeListHandle = hwnd; + PhSetControlTheme(NetworkTreeListHandle, L"explorer"); + SendMessage(TreeNew_GetTooltips(NetworkTreeListHandle), TTM_SETMAXTIPWIDTH, 0, MAXSHORT); + SendMessage(TreeNew_GetTooltips(NetworkTreeListHandle), TTM_SETDELAYTIME, TTDT_AUTOPOP, 0x7fff); + + TreeNew_SetCallback(hwnd, PhpNetworkTreeNewCallback, NULL); + + TreeNew_SetRedraw(hwnd, FALSE); + + // Default columns + PhAddTreeNewColumn(hwnd, PHNETLC_PROCESS, TRUE, L"Name", 100, PH_ALIGN_LEFT, 0, 0); + PhAddTreeNewColumn(hwnd, PHNETLC_LOCALADDRESS, TRUE, L"Local Address", 120, PH_ALIGN_LEFT, 1, 0); + PhAddTreeNewColumn(hwnd, PHNETLC_LOCALPORT, TRUE, L"Local Port", 50, PH_ALIGN_RIGHT, 2, DT_RIGHT); + PhAddTreeNewColumn(hwnd, PHNETLC_REMOTEADDRESS, TRUE, L"Remote Address", 120, PH_ALIGN_LEFT, 3, 0); + PhAddTreeNewColumn(hwnd, PHNETLC_REMOTEPORT, TRUE, L"Remote Port", 50, PH_ALIGN_RIGHT, 4, DT_RIGHT); + PhAddTreeNewColumn(hwnd, PHNETLC_PROTOCOL, TRUE, L"Protocol", 45, PH_ALIGN_LEFT, 5, 0); + PhAddTreeNewColumn(hwnd, PHNETLC_STATE, TRUE, L"State", 70, PH_ALIGN_LEFT, 6, 0); + PhAddTreeNewColumn(hwnd, PHNETLC_OWNER, WINDOWS_HAS_SERVICE_TAGS, L"Owner", 80, PH_ALIGN_LEFT, 7, 0); + + TreeNew_SetRedraw(hwnd, TRUE); + + TreeNew_SetSort(hwnd, 0, AscendingSortOrder); + + PhCmInitializeManager(&NetworkTreeListCm, hwnd, PHNETLC_MAXIMUM, PhpNetworkTreeNewPostSortFunction); + + if (PhPluginsEnabled) + { + treeNewInfo.TreeNewHandle = hwnd; + treeNewInfo.CmData = &NetworkTreeListCm; + PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackNetworkTreeNewInitializing), &treeNewInfo); + } +} + +VOID PhLoadSettingsNetworkTreeList() +{ + PPH_STRING settings; + PPH_STRING sortSettings; + + settings = PhGetStringSetting(L"NetworkTreeListColumns"); + sortSettings = PhGetStringSetting(L"NetworkTreeListSort"); + PhCmLoadSettingsEx(NetworkTreeListHandle, &NetworkTreeListCm, &settings->sr, &sortSettings->sr); + PhDereferenceObject(settings); + PhDereferenceObject(sortSettings); +} + +VOID PhSaveSettingsNetworkTreeList() +{ + PPH_STRING settings; + PPH_STRING sortSettings; + + settings = PhCmSaveSettingsEx(NetworkTreeListHandle, &NetworkTreeListCm, &sortSettings); + PhSetStringSetting2(L"NetworkTreeListColumns", &settings->sr); + PhSetStringSetting2(L"NetworkTreeListSort", &sortSettings->sr); + PhDereferenceObject(settings); + PhDereferenceObject(sortSettings); +} + +PPH_NETWORK_NODE PhAddNetworkNode( + __in PPH_NETWORK_ITEM NetworkItem, + __in ULONG RunId + ) +{ + PPH_NETWORK_NODE networkNode; + + networkNode = PhAllocate(sizeof(PH_NETWORK_NODE)); + memset(networkNode, 0, sizeof(PH_NETWORK_NODE)); + PhInitializeTreeNewNode(&networkNode->Node); + + if (PhNetworkTreeListStateHighlighting && RunId != 1) + { + PhChangeShStateTn( + &networkNode->Node, + &networkNode->ShState, + &NetworkNodeStateList, + NewItemState, + PhCsColorNew, + NULL + ); + } + + networkNode->NetworkItem = NetworkItem; + PhReferenceObject(NetworkItem); + + memset(networkNode->TextCache, 0, sizeof(PH_STRINGREF) * PHNETLC_MAXIMUM); + networkNode->Node.TextCache = networkNode->TextCache; + networkNode->Node.TextCacheSize = PHNETLC_MAXIMUM; + + networkNode->ProcessNameText = PhpGetNetworkItemProcessName(NetworkItem); + PhpUpdateNetworkNodeAddressStrings(networkNode); + + PhAddEntryHashtable(NetworkNodeHashtable, &networkNode); + PhAddItemList(NetworkNodeList, networkNode); + + TreeNew_NodesStructured(NetworkTreeListHandle); + + return networkNode; +} + +PPH_NETWORK_NODE PhFindNetworkNode( + __in PPH_NETWORK_ITEM NetworkItem + ) +{ + PH_NETWORK_NODE lookupNetworkNode; + PPH_NETWORK_NODE lookupNetworkNodePtr = &lookupNetworkNode; + PPH_NETWORK_NODE *networkNode; + + lookupNetworkNode.NetworkItem = NetworkItem; + + networkNode = (PPH_NETWORK_NODE *)PhFindEntryHashtable( + NetworkNodeHashtable, + &lookupNetworkNodePtr + ); + + if (networkNode) + return *networkNode; + else + return NULL; +} + +VOID PhRemoveNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ) +{ + if (PhNetworkTreeListStateHighlighting) + { + PhChangeShStateTn( + &NetworkNode->Node, + &NetworkNode->ShState, + &NetworkNodeStateList, + RemovingItemState, + PhCsColorRemoved, + NetworkTreeListHandle + ); + } + else + { + PhpRemoveNetworkNode(NetworkNode); + } +} + +VOID PhpRemoveNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ) +{ + ULONG index; + + // Remove from hashtable/list and cleanup. + + PhRemoveEntryHashtable(NetworkNodeHashtable, &NetworkNode); + + if ((index = PhFindItemList(NetworkNodeList, NetworkNode)) != -1) + PhRemoveItemList(NetworkNodeList, index); + + if (NetworkNode->ProcessNameText) PhDereferenceObject(NetworkNode->ProcessNameText); + if (NetworkNode->TooltipText) PhDereferenceObject(NetworkNode->TooltipText); + + PhDereferenceObject(NetworkNode->NetworkItem); + + PhFree(NetworkNode); + + TreeNew_NodesStructured(NetworkTreeListHandle); +} + +VOID PhUpdateNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ) +{ + memset(NetworkNode->TextCache, 0, sizeof(PH_STRINGREF) * PHNETLC_MAXIMUM); + PhpUpdateNetworkNodeAddressStrings(NetworkNode); + PhSwapReference(&NetworkNode->TooltipText, NULL); + + PhInvalidateTreeNewNode(&NetworkNode->Node, TN_CACHE_ICON); + TreeNew_NodesStructured(NetworkTreeListHandle); +} + +VOID PhTickNetworkNodes() +{ + PH_TICK_SH_STATE_TN(PH_NETWORK_NODE, ShState, NetworkNodeStateList, PhpRemoveNetworkNode, PhCsHighlightingDuration, NetworkTreeListHandle, TRUE, NULL); +} + +#define SORT_FUNCTION(Column) PhpNetworkTreeNewCompare##Column + +#define BEGIN_SORT_FUNCTION(Column) static int __cdecl PhpNetworkTreeNewCompare##Column( \ + __in const void *_elem1, \ + __in const void *_elem2 \ + ) \ +{ \ + PPH_NETWORK_NODE node1 = *(PPH_NETWORK_NODE *)_elem1; \ + PPH_NETWORK_NODE node2 = *(PPH_NETWORK_NODE *)_elem2; \ + PPH_NETWORK_ITEM networkItem1 = node1->NetworkItem; \ + PPH_NETWORK_ITEM networkItem2 = node2->NetworkItem; \ + int sortResult = 0; + +#define END_SORT_FUNCTION \ + /* if (sortResult == 0) */ \ + /* sortResult = PhCompareString(networkItem1->Name, networkItem2->Name, TRUE); */ \ + \ + return PhModifySort(sortResult, NetworkTreeListSortOrder); \ +} + +LONG PhpNetworkTreeNewPostSortFunction( + __in LONG Result, + __in PVOID Node1, + __in PVOID Node2, + __in PH_SORT_ORDER SortOrder + ) +{ + return PhModifySort(Result, SortOrder); +} + +BEGIN_SORT_FUNCTION(Process) +{ + sortResult = PhCompareString(node1->ProcessNameText, node2->ProcessNameText, TRUE); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(LocalAddress) +{ + sortResult = PhCompareStringRef(&node1->LocalAddressText, &node2->LocalAddressText, TRUE); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(LocalPort) +{ + sortResult = uintcmp(networkItem1->LocalEndpoint.Port, networkItem2->LocalEndpoint.Port); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(RemoteAddress) +{ + sortResult = PhCompareStringRef(&node1->RemoteAddressText, &node2->RemoteAddressText, TRUE); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(RemotePort) +{ + sortResult = uintcmp(networkItem1->RemoteEndpoint.Port, networkItem2->RemoteEndpoint.Port); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(Protocol) +{ + sortResult = uintcmp(networkItem1->ProtocolType, networkItem2->ProtocolType); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(State) +{ + sortResult = uintcmp(networkItem1->State, networkItem2->State); +} +END_SORT_FUNCTION + +BEGIN_SORT_FUNCTION(Owner) +{ + sortResult = PhCompareStringWithNull(networkItem1->OwnerName, networkItem2->OwnerName, TRUE); +} +END_SORT_FUNCTION + +BOOLEAN NTAPI PhpNetworkTreeNewCallback( + __in HWND hwnd, + __in PH_TREENEW_MESSAGE Message, + __in_opt PVOID Parameter1, + __in_opt PVOID Parameter2, + __in_opt PVOID Context + ) +{ + PPH_NETWORK_NODE node; + + if (PhCmForwardMessage(hwnd, Message, Parameter1, Parameter2, &NetworkTreeListCm)) + return TRUE; + + switch (Message) + { + case TreeNewGetChildren: + { + PPH_TREENEW_GET_CHILDREN getChildren = Parameter1; + + if (!getChildren->Node) + { + static PVOID sortFunctions[] = + { + SORT_FUNCTION(Process), + SORT_FUNCTION(LocalAddress), + SORT_FUNCTION(LocalPort), + SORT_FUNCTION(RemoteAddress), + SORT_FUNCTION(RemotePort), + SORT_FUNCTION(Protocol), + SORT_FUNCTION(State), + SORT_FUNCTION(Owner) + }; + int (__cdecl *sortFunction)(const void *, const void *); + + if (!PhCmForwardSort( + (PPH_TREENEW_NODE *)NetworkNodeList->Items, + NetworkNodeList->Count, + NetworkTreeListSortColumn, + NetworkTreeListSortOrder, + &NetworkTreeListCm + )) + { + if (NetworkTreeListSortColumn < PHNETLC_MAXIMUM) + sortFunction = sortFunctions[NetworkTreeListSortColumn]; + else + sortFunction = NULL; + + if (sortFunction) + { + qsort(NetworkNodeList->Items, NetworkNodeList->Count, sizeof(PVOID), sortFunction); + } + } + + getChildren->Children = (PPH_TREENEW_NODE *)NetworkNodeList->Items; + getChildren->NumberOfChildren = NetworkNodeList->Count; + } + } + return TRUE; + case TreeNewIsLeaf: + { + PPH_TREENEW_IS_LEAF isLeaf = Parameter1; + + isLeaf->IsLeaf = TRUE; + } + return TRUE; + case TreeNewGetCellText: + { + PPH_TREENEW_GET_CELL_TEXT getCellText = Parameter1; + PPH_NETWORK_ITEM networkItem; + + node = (PPH_NETWORK_NODE)getCellText->Node; + networkItem = node->NetworkItem; + + switch (getCellText->Id) + { + case PHNETLC_PROCESS: + getCellText->Text = node->ProcessNameText->sr; + break; + case PHNETLC_LOCALADDRESS: + getCellText->Text = node->LocalAddressText; + break; + case PHNETLC_LOCALPORT: + PhInitializeStringRef(&getCellText->Text, networkItem->LocalPortString); + break; + case PHNETLC_REMOTEADDRESS: + getCellText->Text = node->RemoteAddressText; + break; + case PHNETLC_REMOTEPORT: + PhInitializeStringRef(&getCellText->Text, networkItem->RemotePortString); + break; + case PHNETLC_PROTOCOL: + PhInitializeStringRef(&getCellText->Text, PhGetProtocolTypeName(networkItem->ProtocolType)); + break; + case PHNETLC_STATE: + if (networkItem->ProtocolType & PH_TCP_PROTOCOL_TYPE) + PhInitializeStringRef(&getCellText->Text, PhGetTcpStateName(networkItem->State)); + else + PhInitializeEmptyStringRef(&getCellText->Text); + break; + case PHNETLC_OWNER: + if (WINDOWS_HAS_SERVICE_TAGS) + getCellText->Text = PhGetStringRef(networkItem->OwnerName); + else + PhInitializeStringRef(&getCellText->Text, L"N/A"); // make sure the user knows this column doesn't work on XP + break; + default: + return FALSE; + } + + getCellText->Flags = TN_CACHE; + } + return TRUE; + case TreeNewGetNodeIcon: + { + PPH_TREENEW_GET_NODE_ICON getNodeIcon = Parameter1; + + node = (PPH_NETWORK_NODE)getNodeIcon->Node; + + if (node->NetworkItem->ProcessIconValid) + { + // TODO: Check if the icon handle is actually valid, since the process item + // might get destroyed while the network node is still valid. + getNodeIcon->Icon = node->NetworkItem->ProcessIcon; + } + else + { + PhGetStockApplicationIcon(&getNodeIcon->Icon, NULL); + } + + getNodeIcon->Flags = TN_CACHE; + } + return TRUE; + case TreeNewGetCellTooltip: + { + PPH_TREENEW_GET_CELL_TOOLTIP getCellTooltip = Parameter1; + PPH_PROCESS_ITEM processItem; + + node = (PPH_NETWORK_NODE)getCellTooltip->Node; + + if (getCellTooltip->Column->Id != 0) + return FALSE; + + if (!node->TooltipText) + { + if (processItem = PhReferenceProcessItem(node->NetworkItem->ProcessId)) + { + node->TooltipText = PhGetProcessTooltipText(processItem); + PhDereferenceObject(processItem); + } + } + + if (!PhIsNullOrEmptyString(node->TooltipText)) + { + getCellTooltip->Text = node->TooltipText->sr; + getCellTooltip->Unfolding = FALSE; + } + else + { + return FALSE; + } + } + return TRUE; + case TreeNewSortChanged: + { + TreeNew_GetSort(hwnd, &NetworkTreeListSortColumn, &NetworkTreeListSortOrder); + // Force a rebuild to sort the items. + TreeNew_NodesStructured(hwnd); + } + return TRUE; + case TreeNewKeyDown: + { + PPH_TREENEW_KEY_EVENT keyEvent = Parameter1; + + switch (keyEvent->VirtualKey) + { + case 'C': + if (GetKeyState(VK_CONTROL) < 0) + SendMessage(PhMainWndHandle, WM_COMMAND, ID_NETWORK_COPY, 0); + break; + case VK_RETURN: + SendMessage(PhMainWndHandle, WM_COMMAND, ID_NETWORK_GOTOPROCESS, 0); + break; + } + } + return TRUE; + case TreeNewHeaderRightClick: + { + HMENU menu; + HMENU subMenu; + POINT point; + + menu = LoadMenu(PhInstanceHandle, MAKEINTRESOURCE(IDR_GENERICHEADER)); + subMenu = GetSubMenu(menu, 0); + GetCursorPos(&point); + + if ((UINT)TrackPopupMenu( + subMenu, + TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, + point.x, + point.y, + 0, + hwnd, + NULL + ) == ID_HEADER_CHOOSECOLUMNS) + { + PhShowChooseColumnsDialog(hwnd, hwnd, PH_CONTROL_TYPE_TREE_NEW); + + // Make sure the column we're sorting by is actually visible, + // and if not, sort by the default column. + if (NetworkTreeListSortOrder != NoSortOrder) + { + PH_TREENEW_COLUMN column; + + TreeNew_GetColumn(NetworkTreeListHandle, NetworkTreeListSortColumn, &column); + + if (!column.Visible) + TreeNew_SetSort(NetworkTreeListHandle, 0, AscendingSortOrder); + } + } + + DestroyMenu(menu); + } + return TRUE; + case TreeNewLeftDoubleClick: + { + SendMessage(PhMainWndHandle, WM_COMMAND, ID_NETWORK_GOTOPROCESS, 0); + } + return TRUE; + case TreeNewContextMenu: + { + PPH_TREENEW_MOUSE_EVENT mouseEvent = Parameter1; + + PhShowNetworkContextMenu(mouseEvent->Location); + } + return TRUE; + } + + return FALSE; +} + +PPH_STRING PhpGetNetworkItemProcessName( + __in PPH_NETWORK_ITEM NetworkItem + ) +{ + PH_FORMAT format[4]; + + if (!NetworkItem->ProcessId) + return PhCreateString(L"Waiting Connections"); + + PhInitFormatS(&format[1], L" ("); + PhInitFormatU(&format[2], (ULONG)NetworkItem->ProcessId); + PhInitFormatC(&format[3], ')'); + + if (NetworkItem->ProcessName) + PhInitFormatSR(&format[0], NetworkItem->ProcessName->sr); + else + PhInitFormatS(&format[0], L"Unknown Process"); + + return PhFormat(format, 4, 96); +} + +VOID PhpUpdateNetworkNodeAddressStrings( + __in PPH_NETWORK_NODE NetworkNode + ) +{ + if (NetworkNode->NetworkItem->LocalHostString) + NetworkNode->LocalAddressText = NetworkNode->NetworkItem->LocalHostString->sr; + else + PhInitializeStringRef(&NetworkNode->LocalAddressText, NetworkNode->NetworkItem->LocalAddressString); + + if (NetworkNode->NetworkItem->RemoteHostString) + NetworkNode->RemoteAddressText = NetworkNode->NetworkItem->RemoteHostString->sr; + else + PhInitializeStringRef(&NetworkNode->RemoteAddressText, NetworkNode->NetworkItem->RemoteAddressString); +} + +PPH_NETWORK_ITEM PhGetSelectedNetworkItem() +{ + PPH_NETWORK_ITEM networkItem = NULL; + ULONG i; + + for (i = 0; i < NetworkNodeList->Count; i++) + { + PPH_NETWORK_NODE node = NetworkNodeList->Items[i]; + + if (node->Node.Selected) + { + networkItem = node->NetworkItem; + break; + } + } + + return networkItem; +} + +VOID PhGetSelectedNetworkItems( + __out PPH_NETWORK_ITEM **NetworkItems, + __out PULONG NumberOfNetworkItems + ) +{ + PPH_LIST list; + ULONG i; + + list = PhCreateList(2); + + for (i = 0; i < NetworkNodeList->Count; i++) + { + PPH_NETWORK_NODE node = NetworkNodeList->Items[i]; + + if (node->Node.Selected) + { + PhAddItemList(list, node->NetworkItem); + } + } + + *NetworkItems = PhAllocateCopy(list->Items, sizeof(PVOID) * list->Count); + *NumberOfNetworkItems = list->Count; + + PhDereferenceObject(list); +} + +VOID PhDeselectAllNetworkNodes() +{ + TreeNew_DeselectRange(NetworkTreeListHandle, 0, -1); +} + +VOID PhSelectAndEnsureVisibleNetworkNode( + __in PPH_NETWORK_NODE NetworkNode + ) +{ + PhDeselectAllNetworkNodes(); + + if (!NetworkNode->Node.Visible) + return; + + TreeNew_SetFocusNode(NetworkTreeListHandle, &NetworkNode->Node); + TreeNew_SetMarkNode(NetworkTreeListHandle, &NetworkNode->Node); + TreeNew_EnsureVisible(NetworkTreeListHandle, &NetworkNode->Node); +} + +VOID PhCopyNetworkList() +{ + PPH_FULL_STRING text; + + text = PhGetTreeNewText(NetworkTreeListHandle, PHNETLC_MAXIMUM); + PhSetClipboardStringEx(NetworkTreeListHandle, text->Buffer, text->Length); + PhDereferenceObject(text); +} + +VOID PhWriteNetworkList( + __inout PPH_FILE_STREAM FileStream, + __in ULONG Mode + ) +{ + PPH_LIST lines; + ULONG i; + + lines = PhGetGenericTreeNewLines(NetworkTreeListHandle, Mode); + + for (i = 0; i < lines->Count; i++) + { + PPH_STRING line; + + line = lines->Items[i]; + PhWriteStringAsAnsiFileStream(FileStream, &line->sr); + PhDereferenceObject(line); + PhWriteStringAsAnsiFileStream2(FileStream, L"\r\n"); + } + + PhDereferenceObject(lines); +} diff --git a/2.x/trunk/ProcessHacker/proctree.c b/2.x/trunk/ProcessHacker/proctree.c index 5f98579bb..035101eb7 100644 --- a/2.x/trunk/ProcessHacker/proctree.c +++ b/2.x/trunk/ProcessHacker/proctree.c @@ -1269,7 +1269,6 @@ BOOLEAN NTAPI PhpProcessTreeNewCallback( if (sortFunction) { - // Don't use PhSortList to avoid overhead. qsort(ProcessNodeList->Items, ProcessNodeList->Count, sizeof(PVOID), sortFunction); } } diff --git a/2.x/trunk/ProcessHacker/resource.h b/2.x/trunk/ProcessHacker/resource.h index 448fbebbb..9a0aabe85 100644 --- a/2.x/trunk/ProcessHacker/resource.h +++ b/2.x/trunk/ProcessHacker/resource.h @@ -437,11 +437,10 @@ #define IDC_ZPRIVATEWS_V 1289 #define IDC_ZSHAREABLEWS_V 1290 #define IDC_ZSHAREDWS_V 1291 -#define IDC_CHECK2 1292 #define IDC_ENABLEINSTANTTOOLTIPS 1292 #define ID_MAINWND_PROCESSTL 2001 #define ID_MAINWND_SERVICETL 2002 -#define ID_MAINWND_NETWORKLV 2003 +#define ID_MAINWND_NETWORKTL 2003 #define ID_MAINWND_PROCESSLV 2004 #define ID_HACKER_EXIT 40001 #define ID_USERS 40002 diff --git a/2.x/trunk/ProcessHacker/sdk/phapppub.h b/2.x/trunk/ProcessHacker/sdk/phapppub.h index 0212f57ba..abdf148f1 100644 --- a/2.x/trunk/ProcessHacker/sdk/phapppub.h +++ b/2.x/trunk/ProcessHacker/sdk/phapppub.h @@ -61,6 +61,17 @@ typedef struct _PH_SERVICE_NODE // Other members are not exposed. } PH_SERVICE_NODE, *PPH_SERVICE_NODE; +typedef struct _PH_NETWORK_NODE +{ + PH_TREENEW_NODE Node; + + PH_SH_STATE ShState; + + PPH_NETWORK_ITEM NetworkItem; + + // Other members are not exposed. +} PH_NETWORK_NODE, *PPH_NETWORK_NODE; + typedef struct _PH_MODULE_NODE { PH_TREENEW_NODE Node; diff --git a/2.x/trunk/ProcessHacker/settings.c b/2.x/trunk/ProcessHacker/settings.c index 3f82ae7f0..4aa121506 100644 --- a/2.x/trunk/ProcessHacker/settings.c +++ b/2.x/trunk/ProcessHacker/settings.c @@ -123,7 +123,8 @@ VOID PhSettingsInitialization() PhpAddStringSetting(L"MemoryReadWriteAddressChoices", L""); PhpAddStringSetting(L"ModuleTreeListColumns", L""); PhpAddStringSetting(L"ModuleTreeListSort", L"0,0"); // 0, NoSortOrder - PhpAddStringSetting(L"NetworkListViewColumns", L""); + PhpAddStringSetting(L"NetworkTreeListColumns", L""); + PhpAddStringSetting(L"NetworkTreeListSort", L"0,1"); // 0, AscendingSortOrder PhpAddIntegerSetting(L"NoPurgeProcessRecords", L"0"); PhpAddStringSetting(L"PluginsDirectory", L"plugins"); PhpAddStringSetting(L"ProcessServiceListViewColumns", L""); diff --git a/2.x/trunk/ProcessHacker/srvlist.c b/2.x/trunk/ProcessHacker/srvlist.c index fd8492456..89fdd1d88 100644 --- a/2.x/trunk/ProcessHacker/srvlist.c +++ b/2.x/trunk/ProcessHacker/srvlist.c @@ -284,7 +284,7 @@ VOID PhUpdateServiceNode( PhSwapReference(&ServiceNode->TooltipText, NULL); ServiceNode->ValidMask = 0; - PhInvalidateTreeNewNode(&ServiceNode->Node, TN_CACHE_COLOR | TN_CACHE_ICON); + PhInvalidateTreeNewNode(&ServiceNode->Node, TN_CACHE_ICON); TreeNew_NodesStructured(ServiceTreeListHandle); } @@ -459,7 +459,6 @@ BOOLEAN NTAPI PhpServiceTreeNewCallback( if (sortFunction) { - // Don't use PhSortList to avoid overhead. qsort(ServiceNodeList->Items, ServiceNodeList->Count, sizeof(PVOID), sortFunction); } }