Process Hacker
options.c
Go to the documentation of this file.
1 /*
2  * Process Hacker Extra Plugins -
3  * Network Adapters Plugin
4  *
5  * Copyright (C) 2015 dmex
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 "main.h"
24 
25 #define ITEM_CHECKED (INDEXTOSTATEIMAGEMASK(2))
26 #define ITEM_UNCHECKED (INDEXTOSTATEIMAGEMASK(1))
27 
28 static VOID FreeAdaptersEntry(
29  _In_ PPH_NETADAPTER_ENTRY Entry
30  )
31 {
32  if (Entry->InterfaceGuid)
33  PhDereferenceObject(Entry->InterfaceGuid);
34 
35  PhFree(Entry);
36 }
37 
38 static VOID ClearAdaptersList(
39  _Inout_ PPH_LIST FilterList
40  )
41 {
42  for (ULONG i = 0; i < FilterList->Count; i++)
43  {
44  FreeAdaptersEntry((PPH_NETADAPTER_ENTRY)FilterList->Items[i]);
45  }
46 
47  PhClearList(FilterList);
48 }
49 
50 static VOID CopyAdaptersList(
51  _Inout_ PPH_LIST Destination,
52  _In_ PPH_LIST Source
53  )
54 {
55  for (ULONG i = 0; i < Source->Count; i++)
56  {
57  PPH_NETADAPTER_ENTRY entry = (PPH_NETADAPTER_ENTRY)Source->Items[i];
58  PPH_NETADAPTER_ENTRY newEntry;
59 
60  newEntry = (PPH_NETADAPTER_ENTRY)PhAllocate(sizeof(PH_NETADAPTER_ENTRY));
61  memset(newEntry, 0, sizeof(PH_NETADAPTER_ENTRY));
62 
63  newEntry->InterfaceIndex = entry->InterfaceIndex;
64  newEntry->InterfaceLuid = entry->InterfaceLuid;
65  newEntry->InterfaceGuid = entry->InterfaceGuid;
66 
67  PhAddItemList(Destination, newEntry);
68  }
69 }
70 
72  _Inout_ PPH_LIST FilterList,
73  _In_ PPH_STRING String
74  )
75 {
76  PH_STRINGREF remaining = String->sr;
77 
78  while (remaining.Length != 0)
79  {
80  PPH_NETADAPTER_ENTRY entry = NULL;
81 
82  ULONG64 ifindex;
83  ULONG64 luid64;
84  PH_STRINGREF part1;
85  PH_STRINGREF part2;
86  PH_STRINGREF part3;
87 
88  entry = (PPH_NETADAPTER_ENTRY)PhAllocate(sizeof(PH_NETADAPTER_ENTRY));
89  memset(entry, 0, sizeof(PH_NETADAPTER_ENTRY));
90 
91  PhSplitStringRefAtChar(&remaining, ',', &part1, &remaining);
92  PhSplitStringRefAtChar(&remaining, ',', &part2, &remaining);
93  PhSplitStringRefAtChar(&remaining, ',', &part3, &remaining);
94 
95  if (PhStringToInteger64(&part1, 10, &ifindex))
96  {
97  entry->InterfaceIndex = (IF_INDEX)ifindex;
98  }
99  if (PhStringToInteger64(&part2, 10, &luid64))
100  {
101  entry->InterfaceLuid.Value = luid64;
102  }
103  if (part3.Buffer)
104  {
105  entry->InterfaceGuid = PhCreateString2(&part3);
106  }
107 
108  PhAddItemList(FilterList, entry);
109  }
110 }
111 
112 static PPH_STRING SaveAdaptersList(
113  _Inout_ PPH_LIST FilterList
114  )
115 {
116  PH_STRING_BUILDER stringBuilder;
117 
118  PhInitializeStringBuilder(&stringBuilder, 100);
119 
120  for (SIZE_T i = 0; i < FilterList->Count; i++)
121  {
122  PPH_NETADAPTER_ENTRY entry = (PPH_NETADAPTER_ENTRY)FilterList->Items[i];
123 
124  PhAppendFormatStringBuilder(&stringBuilder,
125  L"%lu,%I64u,%s,",
126  entry->InterfaceIndex, // This value is UNSAFE and may change after reboot.
127  entry->InterfaceLuid.Value, // This value is SAFE and does not change (Vista+).
128  entry->InterfaceGuid->Buffer
129  );
130  }
131 
132  if (stringBuilder.String->Length != 0)
133  PhRemoveEndStringBuilder(&stringBuilder, 1);
134 
135  return PhFinalStringBuilderString(&stringBuilder);
136 }
137 
138 static VOID AddNetworkAdapterToListView(
139  _In_ PPH_NETADAPTER_CONTEXT Context,
140  _In_ PIP_ADAPTER_ADDRESSES Adapter
141  )
142 {
143  PPH_NETADAPTER_ENTRY entry;
144 
145  entry = (PPH_NETADAPTER_ENTRY)PhAllocate(sizeof(PH_NETADAPTER_ENTRY));
146  memset(entry, 0, sizeof(PH_NETADAPTER_ENTRY));
147 
148  entry->InterfaceIndex = Adapter->IfIndex;
149  entry->InterfaceLuid = Adapter->Luid;
150  entry->InterfaceGuid = PhConvertMultiByteToUtf16(Adapter->AdapterName);
151 
152  INT index = PhAddListViewItem(
153  Context->ListViewHandle,
154  MAXINT,
155  Adapter->Description,
156  entry
157  );
158 
159  for (ULONG i = 0; i < Context->NetworkAdaptersListEdited->Count; i++)
160  {
161  PPH_NETADAPTER_ENTRY currentEntry = (PPH_NETADAPTER_ENTRY)Context->NetworkAdaptersListEdited->Items[i];
162 
164  {
165  if (entry->InterfaceLuid.Value == currentEntry->InterfaceLuid.Value)
166  {
167  ListView_SetItemState(Context->ListViewHandle, index, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
168  break;
169  }
170  }
171  else
172  {
173  if (entry->InterfaceIndex == currentEntry->InterfaceIndex)
174  {
175  ListView_SetItemState(Context->ListViewHandle, index, ITEM_CHECKED, LVIS_STATEIMAGEMASK);
176  break;
177  }
178  }
179  }
180 }
181 
182 static VOID FindNetworkAdapters(
183  _In_ PPH_NETADAPTER_CONTEXT Context
184  )
185 {
186  ULONG bufferLength = 0;
187  PVOID buffer = NULL;
188 
189  ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
190 
191  //if (WindowsVersion >= WINDOWS_VISTA)
192  // flags |= GAA_FLAG_INCLUDE_ALL_INTERFACES;
193 
194  __try
195  {
196  if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, NULL, &bufferLength) != ERROR_BUFFER_OVERFLOW)
197  __leave;
198 
199  buffer = PhAllocate(bufferLength);
200  memset(buffer, 0, bufferLength);
201 
202  if (GetAdaptersAddresses(AF_UNSPEC, flags, NULL, buffer, &bufferLength) == ERROR_SUCCESS)
203  {
204  PIP_ADAPTER_ADDRESSES addressesBuffer = buffer;
205 
206  while (addressesBuffer)
207  {
208  //if (addressesBuffer->IfType != IF_TYPE_SOFTWARE_LOOPBACK)
209  AddNetworkAdapterToListView(Context, addressesBuffer);
210  addressesBuffer = addressesBuffer->Next;
211  }
212  }
213  }
214  __finally
215  {
216  if (buffer)
217  {
218  PhFree(buffer);
219  }
220  }
221 }
222 
223 static INT_PTR CALLBACK OptionsDlgProc(
224  _In_ HWND hwndDlg,
225  _In_ UINT uMsg,
226  _In_ WPARAM wParam,
227  _In_ LPARAM lParam
228  )
229 {
230  PPH_NETADAPTER_CONTEXT context = NULL;
231 
232  if (uMsg == WM_INITDIALOG)
233  {
234  context = (PPH_NETADAPTER_CONTEXT)PhAllocate(sizeof(PH_NETADAPTER_CONTEXT));
235  memset(context, 0, sizeof(PH_NETADAPTER_CONTEXT));
236 
237  SetProp(hwndDlg, L"Context", (HANDLE)context);
238  }
239  else
240  {
241  context = (PPH_NETADAPTER_CONTEXT)GetProp(hwndDlg, L"Context");
242 
243  if (uMsg == WM_DESTROY)
244  {
245  PPH_STRING string;
246  PPH_LIST list;
247  ULONG index;
248  PVOID param;
249 
250  list = PhCreateList(2);
251  index = -1;
252 
253  while ((index = PhFindListViewItemByFlags(
254  context->ListViewHandle,
255  index,
256  LVNI_ALL
257  )) != -1)
258  {
259  BOOL checked = ListView_GetItemState(context->ListViewHandle, index, LVIS_STATEIMAGEMASK) == ITEM_CHECKED;
260 
261  if (checked)
262  {
263  if (PhGetListViewItemParam(context->ListViewHandle, index, &param))
264  {
265  PhAddItemList(list, param);
266  }
267  }
268  }
269 
270  ClearAdaptersList(NetworkAdaptersList);
271  CopyAdaptersList(NetworkAdaptersList, list);
273 
274  string = SaveAdaptersList(NetworkAdaptersList);
276  PhDereferenceObject(string);
277 
278  RemoveProp(hwndDlg, L"Context");
279  PhFree(context);
280  }
281  }
282 
283  if (context == NULL)
284  return FALSE;
285 
286  switch (uMsg)
287  {
288  case WM_INITDIALOG:
289  {
291  context->ListViewHandle = GetDlgItem(hwndDlg, IDC_NETADAPTERS_LISTVIEW);
292 
294  ListView_SetExtendedListViewStyleEx(context->ListViewHandle, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
295  PhSetControlTheme(context->ListViewHandle, L"explorer");
296  PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 420, L"Network Adapters");
298 
299  ClearAdaptersList(context->NetworkAdaptersListEdited);
300  CopyAdaptersList(context->NetworkAdaptersListEdited, NetworkAdaptersList);
301 
302  FindNetworkAdapters(context);
303  }
304  break;
305  case WM_COMMAND:
306  {
307  switch (LOWORD(wParam))
308  {
309  case IDCANCEL:
310  EndDialog(hwndDlg, IDCANCEL);
311  break;
312  case IDOK:
313  EndDialog(hwndDlg, IDOK);
314  break;
315  }
316  }
317  break;
318  }
319 
320  return FALSE;
321 }
322 
324  _In_ HWND ParentHandle
325  )
326 {
327  DialogBox(
329  MAKEINTRESOURCE(IDD_NETADAPTER_OPTIONS),
330  ParentHandle,
332  );
333 }