/* * Process Hacker - * network stack viewer * * 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 . */ #include #include typedef struct NETWORK_STACK_CONTEXT { HWND ListViewHandle; PPH_NETWORK_ITEM NetworkItem; PPH_SYMBOL_PROVIDER SymbolProvider; HANDLE LoadingProcessId; } NETWORK_STACK_CONTEXT, *PNETWORK_STACK_CONTEXT; INT_PTR CALLBACK PhpNetworkStackDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ); static RECT MinimumSize = { -1, -1, -1, -1 }; static BOOLEAN LoadSymbolsEnumGenericModulesCallback( _In_ PPH_MODULE_INFO Module, _In_opt_ PVOID Context ) { PNETWORK_STACK_CONTEXT context = Context; PPH_SYMBOL_PROVIDER symbolProvider = context->SymbolProvider; // If we're loading kernel module symbols for a process other than // System, ignore modules which are in user space. This may happen // in Windows 7. if ( context->LoadingProcessId == SYSTEM_PROCESS_ID && context->NetworkItem->ProcessId != SYSTEM_PROCESS_ID && (ULONG_PTR)Module->BaseAddress <= PhSystemBasicInformation.MaximumUserModeAddress ) return TRUE; PhLoadModuleSymbolProvider( symbolProvider, Module->FileName->Buffer, (ULONG64)Module->BaseAddress, Module->Size ); return TRUE; } VOID PhShowNetworkStackDialog( _In_ HWND ParentWindowHandle, _In_ PPH_NETWORK_ITEM NetworkItem ) { NETWORK_STACK_CONTEXT networkStackContext; networkStackContext.NetworkItem = NetworkItem; networkStackContext.SymbolProvider = PhCreateSymbolProvider(NetworkItem->ProcessId); if (networkStackContext.SymbolProvider->IsRealHandle) { // Load symbols for the process. networkStackContext.LoadingProcessId = NetworkItem->ProcessId; PhEnumGenericModules( NetworkItem->ProcessId, networkStackContext.SymbolProvider->ProcessHandle, 0, LoadSymbolsEnumGenericModulesCallback, &networkStackContext ); // Load symbols for kernel-mode. networkStackContext.LoadingProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, LoadSymbolsEnumGenericModulesCallback, &networkStackContext ); } else { PhDereferenceObject(networkStackContext.SymbolProvider); PhShowError(ParentWindowHandle, L"Unable to open the process."); return; } DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_NETSTACK), ParentWindowHandle, PhpNetworkStackDlgProc, (LPARAM)&networkStackContext ); PhDereferenceObject(networkStackContext.SymbolProvider); } static INT_PTR CALLBACK PhpNetworkStackDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PNETWORK_STACK_CONTEXT networkStackContext; HWND lvHandle; PPH_LAYOUT_MANAGER layoutManager; PVOID address; ULONG i; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); networkStackContext = (PNETWORK_STACK_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)networkStackContext); lvHandle = GetDlgItem(hwndDlg, IDC_LIST); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 350, L"Name"); PhSetListViewStyle(lvHandle, FALSE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); networkStackContext->ListViewHandle = lvHandle; layoutManager = PhAllocate(sizeof(PH_LAYOUT_MANAGER)); PhInitializeLayoutManager(layoutManager, hwndDlg); SetProp(hwndDlg, L"LayoutManager", (HANDLE)layoutManager); PhAddLayoutItem(layoutManager, lvHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 190; rect.bottom = 120; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } for (i = 0; i < PH_NETWORK_OWNER_INFO_SIZE; i++) { PPH_STRING name; address = *(PVOID *)&networkStackContext->NetworkItem->OwnerInfo[i]; if ((ULONG_PTR)address < PAGE_SIZE) // stop at an invalid address break; name = PhGetSymbolFromAddress( networkStackContext->SymbolProvider, (ULONG64)address, NULL, NULL, NULL, NULL ); PhAddListViewItem(lvHandle, MAXINT, name->Buffer, NULL); PhDereferenceObject(name); } } break; case WM_DESTROY: { PPH_LAYOUT_MANAGER layoutManager; PNETWORK_STACK_CONTEXT networkStackContext; layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager"); PhDeleteLayoutManager(layoutManager); PhFree(layoutManager); networkStackContext = (PNETWORK_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); RemoveProp(hwndDlg, PhMakeContextAtom()); RemoveProp(hwndDlg, L"LayoutManager"); } break; case WM_COMMAND: { INT id = LOWORD(wParam); switch (id) { case IDCANCEL: // Esc and X button to close case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; case WM_SIZE: { PPH_LAYOUT_MANAGER layoutManager; layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager"); PhLayoutManagerLayout(layoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; } return FALSE; }