Process Hacker
netstk.c
Go to the documentation of this file.
1 /*
2  * Process Hacker -
3  * network stack viewer
4  *
5  * Copyright (C) 2010 wj32
6  *
7  * This file is part of Process Hacker.
8  *
9  * Process Hacker is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Process Hacker 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
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <phapp.h>
24 #include <symprv.h>
25 
26 typedef struct NETWORK_STACK_CONTEXT
27 {
28  HWND ListViewHandle;
29  PPH_NETWORK_ITEM NetworkItem;
30  PPH_SYMBOL_PROVIDER SymbolProvider;
31  HANDLE LoadingProcessId;
33 
34 INT_PTR CALLBACK PhpNetworkStackDlgProc(
35  _In_ HWND hwndDlg,
36  _In_ UINT uMsg,
37  _In_ WPARAM wParam,
38  _In_ LPARAM lParam
39  );
40 
41 static RECT MinimumSize = { -1, -1, -1, -1 };
42 
43 static BOOLEAN LoadSymbolsEnumGenericModulesCallback(
44  _In_ PPH_MODULE_INFO Module,
45  _In_opt_ PVOID Context
46  )
47 {
48  PNETWORK_STACK_CONTEXT context = Context;
49  PPH_SYMBOL_PROVIDER symbolProvider = context->SymbolProvider;
50 
51  // If we're loading kernel module symbols for a process other than
52  // System, ignore modules which are in user space. This may happen
53  // in Windows 7.
54  if (
55  context->LoadingProcessId == SYSTEM_PROCESS_ID &&
56  context->NetworkItem->ProcessId != SYSTEM_PROCESS_ID &&
57  (ULONG_PTR)Module->BaseAddress <= PhSystemBasicInformation.MaximumUserModeAddress
58  )
59  return TRUE;
60 
62  symbolProvider,
63  Module->FileName->Buffer,
64  (ULONG64)Module->BaseAddress,
65  Module->Size
66  );
67 
68  return TRUE;
69 }
70 
72  _In_ HWND ParentWindowHandle,
73  _In_ PPH_NETWORK_ITEM NetworkItem
74  )
75 {
76  NETWORK_STACK_CONTEXT networkStackContext;
77 
78  networkStackContext.NetworkItem = NetworkItem;
79  networkStackContext.SymbolProvider = PhCreateSymbolProvider(NetworkItem->ProcessId);
80 
81  if (networkStackContext.SymbolProvider->IsRealHandle)
82  {
83  // Load symbols for the process.
84  networkStackContext.LoadingProcessId = NetworkItem->ProcessId;
86  NetworkItem->ProcessId,
87  networkStackContext.SymbolProvider->ProcessHandle,
88  0,
89  LoadSymbolsEnumGenericModulesCallback,
90  &networkStackContext
91  );
92  // Load symbols for kernel-mode.
93  networkStackContext.LoadingProcessId = SYSTEM_PROCESS_ID;
96  NULL,
97  0,
98  LoadSymbolsEnumGenericModulesCallback,
99  &networkStackContext
100  );
101  }
102  else
103  {
104  PhDereferenceObject(networkStackContext.SymbolProvider);
105  PhShowError(ParentWindowHandle, L"Unable to open the process.");
106  return;
107  }
108 
109  DialogBoxParam(
111  MAKEINTRESOURCE(IDD_NETSTACK),
112  ParentWindowHandle,
114  (LPARAM)&networkStackContext
115  );
116 
117  PhDereferenceObject(networkStackContext.SymbolProvider);
118 }
119 
120 static INT_PTR CALLBACK PhpNetworkStackDlgProc(
121  _In_ HWND hwndDlg,
122  _In_ UINT uMsg,
123  _In_ WPARAM wParam,
124  _In_ LPARAM lParam
125  )
126 {
127  switch (uMsg)
128  {
129  case WM_INITDIALOG:
130  {
131  PNETWORK_STACK_CONTEXT networkStackContext;
132  HWND lvHandle;
133  PPH_LAYOUT_MANAGER layoutManager;
134  PVOID address;
135  ULONG i;
136 
137  PhCenterWindow(hwndDlg, GetParent(hwndDlg));
138 
139  networkStackContext = (PNETWORK_STACK_CONTEXT)lParam;
140  SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)networkStackContext);
141 
142  lvHandle = GetDlgItem(hwndDlg, IDC_LIST);
143  PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 350, L"Name");
144  PhSetListViewStyle(lvHandle, FALSE, TRUE);
145  PhSetControlTheme(lvHandle, L"explorer");
146 
147  networkStackContext->ListViewHandle = lvHandle;
148 
149  layoutManager = PhAllocate(sizeof(PH_LAYOUT_MANAGER));
150  PhInitializeLayoutManager(layoutManager, hwndDlg);
151  SetProp(hwndDlg, L"LayoutManager", (HANDLE)layoutManager);
152 
153  PhAddLayoutItem(layoutManager, lvHandle, NULL,
154  PH_ANCHOR_ALL);
155  PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDOK),
157 
158  if (MinimumSize.left == -1)
159  {
160  RECT rect;
161 
162  rect.left = 0;
163  rect.top = 0;
164  rect.right = 190;
165  rect.bottom = 120;
166  MapDialogRect(hwndDlg, &rect);
167  MinimumSize = rect;
168  MinimumSize.left = 0;
169  }
170 
171  for (i = 0; i < PH_NETWORK_OWNER_INFO_SIZE; i++)
172  {
173  PPH_STRING name;
174 
175  address = *(PVOID *)&networkStackContext->NetworkItem->OwnerInfo[i];
176 
177  if ((ULONG_PTR)address < PAGE_SIZE) // stop at an invalid address
178  break;
179 
180  name = PhGetSymbolFromAddress(
181  networkStackContext->SymbolProvider,
182  (ULONG64)address,
183  NULL,
184  NULL,
185  NULL,
186  NULL
187  );
188  PhAddListViewItem(lvHandle, MAXINT, name->Buffer, NULL);
189  PhDereferenceObject(name);
190  }
191  }
192  break;
193  case WM_DESTROY:
194  {
195  PPH_LAYOUT_MANAGER layoutManager;
196  PNETWORK_STACK_CONTEXT networkStackContext;
197 
198  layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager");
199  PhDeleteLayoutManager(layoutManager);
200  PhFree(layoutManager);
201 
202  networkStackContext = (PNETWORK_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom());
203 
204  RemoveProp(hwndDlg, PhMakeContextAtom());
205  RemoveProp(hwndDlg, L"LayoutManager");
206  }
207  break;
208  case WM_COMMAND:
209  {
210  INT id = LOWORD(wParam);
211 
212  switch (id)
213  {
214  case IDCANCEL: // Esc and X button to close
215  case IDOK:
216  EndDialog(hwndDlg, IDOK);
217  break;
218  }
219  }
220  break;
221  case WM_SIZE:
222  {
223  PPH_LAYOUT_MANAGER layoutManager;
224 
225  layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager");
226  PhLayoutManagerLayout(layoutManager);
227  }
228  break;
229  case WM_SIZING:
230  {
231  PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom);
232  }
233  break;
234  }
235 
236  return FALSE;
237 }