1 #include "precomp.h"
2 
3 #include <winnls.h>
4 #include <winsock.h>
5 #include <iphlpapi.h>
6 #include <dhcpcsdk.h>
7 #include <dhcpcapi.h>
8 
9 typedef struct
10 {
11     DWORD EnableSecurityFilters;
12     LPWSTR szTCPAllowedPorts;       // KEY: Tcpip\Parameter\{InstanceGuid}\TCPAllowedPorts
13     LPWSTR szUDPAllowedPorts;       // KEY: Tcpip\Parameter\{InstanceGuid}\UDPAllowedPorts
14     LPWSTR szRawIPAllowedProtocols; // KEY: Tcpip\Parameter\{InstanceGuid}\RawIPAllowedProtocols
15     DWORD IPSize;
16     DWORD TCPSize;
17     DWORD UDPSize;
18 } TcpFilterSettings;
19 
20 // KEY: Tcpip\Parameter\{InstanceGuid}\IpAddress | DhcpIpAddress
21 // KEY: Tcpip\Parameter\{InstanceGuid}\SubnetMask | DhcpSubnetMask
22 // KEY: Tcpip\Parameter\{InstanceGuid}\DefaultGateway | DhcpDefaultGateway
23 // KEY: Tcpip\Parameter\{InstanceGuid}\NameServer | DhcpNameServer
24 // KEY: Services\NetBT\Parameters\Interfaces\Tcpip_{INSTANCE_GUID}
25 
26 typedef struct
27 {
28     DWORD RegisterAdapterName;
29     DWORD RegistrationEnabled;
30     DWORD UseDomainNameDevolution;
31     WCHAR szDomain[100];
32     LPWSTR szSearchList;
33 } TcpipAdvancedDNSDlgSettings;
34 
35 typedef struct tagIP_ADDR
36 {
37     DWORD IpAddress;
38     union
39     {
40         DWORD Subnetmask;
41         USHORT Metric;
42     } u;
43     ULONG NTEContext;
44     struct tagIP_ADDR *Next;
45 } IP_ADDR;
46 
47 typedef enum
48 {
49     METRIC = 1,
50     SUBMASK = 2,
51     IPADDR = 3
52 } COPY_TYPE;
53 
54 typedef struct
55 {
56     IP_ADDR *Ip;
57     IP_ADDR *Ns;
58     IP_ADDR *Gw;
59 
60     UINT DhcpEnabled;
61     UINT AutoconfigActive;
62     DWORD Index;
63     TcpFilterSettings *pFilter;
64     TcpipAdvancedDNSDlgSettings *pDNS;
65 } TcpipSettings;
66 
67 typedef struct
68 {
69     const INetCfgComponentPropertyUi *lpVtbl;
70     const INetCfgComponentControl *lpVtblCompControl;
71     LONG ref;
72     IUnknown *pUnknown;
73     INetCfg *pNCfg;
74     INetCfgComponent *pNComp;
75     TcpipSettings *pCurrentConfig;
76     CLSID NetCfgInstanceId;
77 } TcpipConfNotifyImpl, *LPTcpipConfNotifyImpl;
78 
79 typedef struct
80 {
81     BOOL bAdd;
82     HWND hDlgCtrl;
83     WCHAR szIP[16];
84     UINT Metric;
85 } TcpipGwSettings;
86 
87 typedef struct
88 {
89     BOOL bAdd;
90     HWND hDlgCtrl;
91     WCHAR szIP[16];
92     WCHAR szMask[16];
93 } TcpipIpSettings;
94 
95 typedef struct
96 {
97     BOOL bAdd;
98     HWND hDlgCtrl;
99     WCHAR szIP[16];
100 } TcpipDnsSettings;
101 
102 typedef struct
103 {
104     BOOL bAdd;
105     HWND hDlgCtrl;
106     LPWSTR Suffix;
107 } TcpipSuffixSettings;
108 
109 typedef struct
110 {
111     HWND hDlgCtrl;
112     UINT ResId;
113     UINT MaxNum;
114 } TcpipPortSettings;
115 
116 static __inline LPTcpipConfNotifyImpl impl_from_INetCfgComponentControl(INetCfgComponentControl *iface)
117 {
118     return (TcpipConfNotifyImpl*)((char *)iface - FIELD_OFFSET(TcpipConfNotifyImpl, lpVtblCompControl));
119 }
120 
121 INT GetSelectedItem(HWND hDlgCtrl);
122 HRESULT InitializeTcpipBasicDlgCtrls(HWND hwndDlg, TcpipSettings * pCurSettings);
123 VOID InsertColumnToListView(HWND hDlgCtrl, UINT ResId, UINT SubItem, UINT Size);
124 INT_PTR StoreTcpipBasicSettings(HWND hwndDlg, TcpipConfNotifyImpl * This, BOOL bApply);
125 HRESULT Initialize(TcpipConfNotifyImpl * This);
126 UINT GetIpAddressFromStringW(WCHAR *szBuffer);
127 
128 VOID
129 DisplayError(UINT ResTxt, UINT ResTitle, UINT Type)
130 {
131     WCHAR szBuffer[300];
132     WCHAR szTitle[100];
133 
134     if (LoadStringW(netcfgx_hInstance, ResTxt, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
135         szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
136     else
137         szBuffer[0] = L'\0';
138 
139     if (LoadStringW(netcfgx_hInstance, ResTitle, szTitle, sizeof(szTitle)/sizeof(WCHAR)))
140         szTitle[(sizeof(szTitle)/sizeof(WCHAR))-1] = L'\0';
141     else
142         szTitle[0] = L'\0';
143 
144     MessageBoxW(NULL, szBuffer, szTitle, Type);
145 }
146 
147 
148 /***************************************************************
149  * TCP/IP Filter Dialog
150  *
151  */
152 
153 INT_PTR
154 CALLBACK
155 TcpipFilterPortDlg(
156     HWND hwndDlg,
157     UINT uMsg,
158     WPARAM wParam,
159     LPARAM lParam
160 )
161 {
162     TcpipPortSettings * pPort;
163     UINT Num;
164     LVFINDINFOW find;
165     LVITEMW li;
166     WCHAR szBuffer[100];
167 
168     switch(uMsg)
169     {
170         case WM_INITDIALOG:
171             pPort = (TcpipPortSettings*)lParam;
172             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPort);
173             if (LoadStringW(netcfgx_hInstance, pPort->ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
174             {
175                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
176                 SendDlgItemMessageW(hwndDlg, IDC_PORT_DESC, WM_SETTEXT, 0, (LPARAM)szBuffer);
177             }
178 
179             if (pPort->MaxNum == 65536)
180                 SendDlgItemMessageW(hwndDlg, IDC_PORT_VAL, EM_LIMITTEXT, 5, 0);
181             else
182                 SendDlgItemMessageW(hwndDlg, IDC_PORT_VAL, EM_LIMITTEXT, 3, 0);
183 
184             return TRUE;
185         case WM_COMMAND:
186             if (LOWORD(wParam) == IDCANCEL)
187             {
188                 EndDialog(hwndDlg, FALSE);
189                 break;
190             }
191             else if (LOWORD(wParam) == IDC_OK)
192             {
193                 pPort = (TcpipPortSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
194                 Num = GetDlgItemInt(hwndDlg, IDC_PORT_VAL, NULL, TRUE);
195                 if (Num > pPort->MaxNum || Num == 0)
196                 {
197                     if (pPort->MaxNum == 65536)
198                         DisplayError(IDS_PORT_RANGE, IDS_TCPIP, MB_ICONWARNING);
199                     else
200                         DisplayError(IDS_PROT_RANGE, IDS_TCPIP, MB_ICONWARNING);
201 
202                     SetFocus(GetDlgItem(hwndDlg, IDC_PORT_VAL));
203                     break;
204                 }
205                 if (GetWindowTextW(GetDlgItem(hwndDlg, IDC_PORT_VAL), szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
206                 {
207                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
208                     ZeroMemory(&find, sizeof(LVFINDINFOW));
209                     find.flags = LVFI_STRING;
210                     find.psz = szBuffer;
211                     if (SendMessageW(pPort->hDlgCtrl, LVM_FINDITEMW, (WPARAM)-1, (LPARAM)&find) == -1)
212                     {
213                         ZeroMemory(&li, sizeof(LVITEMW));
214                         li.mask = LVIF_TEXT;
215                         li.iItem = ListView_GetItemCount(pPort->hDlgCtrl);
216                         li.pszText = szBuffer;
217                         SendMessageW(pPort->hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
218                         EndDialog(hwndDlg, TRUE);
219                         break;
220                     }
221                     DisplayError(IDS_DUP_NUMBER, IDS_PROT_RANGE, MB_ICONWARNING);
222                     SetFocus(GetDlgItem(hwndDlg, IDC_PORT_VAL));
223                     break;
224                 }
225            }
226     }
227     return FALSE;
228 }
229 
230 VOID
231 InitFilterListBox(LPWSTR pData, HWND hwndDlg, HWND hDlgCtrl, UINT AllowButton, UINT RestrictButton, UINT AddButton, UINT DelButton)
232 {
233     LVITEMW li;
234     LPWSTR pCur;
235     INT iItem;
236 
237     if (!pData || !_wtoi(pData))
238     {
239         CheckDlgButton(hwndDlg, AllowButton, BST_CHECKED);
240         EnableWindow(GetDlgItem(hwndDlg, AddButton), FALSE);
241         EnableWindow(GetDlgItem(hwndDlg, DelButton), FALSE);
242         return;
243     }
244 
245     pCur = pData;
246     memset(&li, 0x0, sizeof(LVITEMW));
247     li.mask = LVIF_TEXT;
248     iItem = 0;
249 
250     while(pCur[0])
251     {
252         li.pszText = pCur;
253         li.iItem = iItem;
254         SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
255         iItem++;
256         pCur += wcslen(pCur) + 1;
257     }
258 
259     if (!iItem)
260         CheckDlgButton(hwndDlg, AllowButton, BST_CHECKED);
261     else
262         CheckDlgButton(hwndDlg, RestrictButton, BST_CHECKED);
263 }
264 
265 LPWSTR
266 CreateFilterList(
267     HWND hDlgCtrl,
268     LPDWORD Size)
269 {
270     INT iCount, iIndex;
271     LVITEMW li;
272     LPWSTR pData, pCur;
273     DWORD dwSize;
274     WCHAR szBuffer[10];
275 
276     iCount = ListView_GetItemCount(hDlgCtrl);
277     if (!iCount)
278     {
279         pData = (LPWSTR)CoTaskMemAlloc(3 * sizeof(WCHAR));
280         if (!pData)
281             return NULL;
282         pData[0] = L'0';
283         pData[1] = L'\0';
284         pData[2] = L'\0';
285         *Size = 3 * sizeof(WCHAR);
286         return pData;
287     }
288 
289     pData = CoTaskMemAlloc((6 * iCount + 1) * sizeof(WCHAR));
290     if (!pData)
291         return NULL;
292 
293     pCur = pData;
294     dwSize = 0;
295     for(iIndex = 0; iIndex < iCount; iIndex++)
296     {
297         ZeroMemory(&li, sizeof(LVITEMW));
298         li.mask = LVIF_TEXT;
299         li.iItem = iIndex;
300         li.pszText = szBuffer;
301         li.cchTextMax = sizeof(szBuffer) /sizeof(WCHAR);
302         if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
303         {
304             wcscpy(pCur, szBuffer);
305             dwSize += wcslen(szBuffer) + 1;
306             pCur += wcslen(szBuffer) + 1;
307         }
308     }
309     pCur[0] = L'\0';
310     *Size = (dwSize+1) * sizeof(WCHAR);
311     return pData;
312 }
313 
314 TcpFilterSettings *
315 StoreTcpipFilterSettings(
316     HWND hwndDlg)
317 {
318     TcpFilterSettings * pFilter;
319 
320     pFilter = CoTaskMemAlloc(sizeof(TcpFilterSettings));
321     if (!pFilter)
322         return NULL;
323 
324     if (IsDlgButtonChecked(hwndDlg, IDC_USE_FILTER) == BST_CHECKED)
325         pFilter->EnableSecurityFilters = TRUE;
326     else
327         pFilter->EnableSecurityFilters = FALSE;
328 
329     pFilter->szTCPAllowedPorts = CreateFilterList(GetDlgItem(hwndDlg, IDC_TCP_LIST), &pFilter->TCPSize);
330     pFilter->szUDPAllowedPorts = CreateFilterList(GetDlgItem(hwndDlg, IDC_UDP_LIST), &pFilter->UDPSize);
331     pFilter->szRawIPAllowedProtocols = CreateFilterList(GetDlgItem(hwndDlg, IDC_IP_LIST), &pFilter->IPSize);
332 
333     return pFilter;
334 }
335 
336 static
337 VOID
338 AddItem(
339     HWND hwndDlg,
340     HWND hDlgCtrl,
341     UINT MaxItem,
342     UINT ResId)
343 {
344     TcpipPortSettings Port;
345 
346     Port.MaxNum = MaxItem;
347     Port.hDlgCtrl = hDlgCtrl;
348     Port.ResId = ResId;
349 
350     DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIP_PORT_DLG), hwndDlg, TcpipFilterPortDlg, (LPARAM)&Port);
351 }
352 
353 static
354 VOID
355 DelItem(
356     HWND hDlgCtrl)
357 {
358     INT iIndex = GetSelectedItem(hDlgCtrl);
359 
360     if (iIndex != -1)
361     {
362         (void)ListView_DeleteItem(hDlgCtrl, iIndex);
363         return;
364     }
365     DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONWARNING);
366 }
367 
368 INT_PTR
369 CALLBACK
370 TcpipFilterSettingsDlg(
371     HWND hwndDlg,
372     UINT uMsg,
373     WPARAM wParam,
374     LPARAM lParam
375 )
376 {
377     TcpipConfNotifyImpl *pContext;
378     TcpFilterSettings *pFilter;
379 
380     switch(uMsg)
381     {
382         case WM_INITDIALOG:
383             pContext = (TcpipConfNotifyImpl*)lParam;
384             InsertColumnToListView(GetDlgItem(hwndDlg, IDC_TCP_LIST), IDS_TCP_PORTS, 0, 100);
385             InsertColumnToListView(GetDlgItem(hwndDlg, IDC_UDP_LIST), IDS_UDP_PORTS, 0, 100);
386             InsertColumnToListView(GetDlgItem(hwndDlg, IDC_IP_LIST), IDS_IP_PROTO, 0, 100);
387             if (pContext->pCurrentConfig->pFilter)
388             {
389                 InitFilterListBox(pContext->pCurrentConfig->pFilter->szTCPAllowedPorts, hwndDlg, GetDlgItem(hwndDlg, IDC_TCP_LIST), IDC_TCP_ALLOW_ALL, IDC_TCP_RESTRICT, IDC_TCP_ADD, IDC_TCP_DEL);
390                 InitFilterListBox(pContext->pCurrentConfig->pFilter->szUDPAllowedPorts, hwndDlg, GetDlgItem(hwndDlg, IDC_UDP_LIST), IDC_UDP_ALLOW_ALL, IDC_UDP_RESTRICT, IDC_UDP_ADD, IDC_UDP_DEL);
391                 InitFilterListBox(pContext->pCurrentConfig->pFilter->szRawIPAllowedProtocols, hwndDlg, GetDlgItem(hwndDlg, IDC_IP_LIST), IDC_IP_ALLOW_ALL, IDC_IP_RESTRICT, IDC_IP_ADD, IDC_IP_DEL);
392                 if (pContext->pCurrentConfig->pFilter->EnableSecurityFilters)
393                     CheckDlgButton(hwndDlg, IDC_USE_FILTER, BST_CHECKED);
394              }
395             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext);
396             return TRUE;
397         case WM_COMMAND:
398             if (HIWORD(wParam) == BN_CLICKED)
399             {
400                 switch (LOWORD(wParam))
401                 {
402                     case IDC_TCP_ALLOW_ALL:
403                         if (IsDlgButtonChecked(hwndDlg, IDC_TCP_ALLOW_ALL) == BST_CHECKED)
404                         {
405                             CheckDlgButton(hwndDlg, IDC_TCP_RESTRICT, BST_UNCHECKED);
406                             EnableWindow(GetDlgItem(hwndDlg, IDC_TCP_LIST), FALSE);
407                             EnableWindow(GetDlgItem(hwndDlg, IDC_TCP_ADD), FALSE);
408                             EnableWindow(GetDlgItem(hwndDlg, IDC_TCP_DEL), FALSE);
409                         }
410                         break;
411                     case IDC_TCP_RESTRICT:
412                         if (IsDlgButtonChecked(hwndDlg, IDC_TCP_RESTRICT) == BST_CHECKED)
413                         {
414                             CheckDlgButton(hwndDlg, IDC_TCP_ALLOW_ALL, BST_UNCHECKED);
415                             EnableWindow(GetDlgItem(hwndDlg, IDC_TCP_LIST), TRUE);
416                             EnableWindow(GetDlgItem(hwndDlg, IDC_TCP_ADD), TRUE);
417                             EnableWindow(GetDlgItem(hwndDlg, IDC_TCP_DEL), TRUE);
418                         }
419                         break;
420                     case IDC_UDP_ALLOW_ALL:
421                         if (IsDlgButtonChecked(hwndDlg, IDC_UDP_ALLOW_ALL) == BST_CHECKED)
422                         {
423                             CheckDlgButton(hwndDlg, IDC_UDP_RESTRICT, BST_UNCHECKED);
424                             EnableWindow(GetDlgItem(hwndDlg, IDC_UDP_LIST), FALSE);
425                             EnableWindow(GetDlgItem(hwndDlg, IDC_UDP_ADD), FALSE);
426                             EnableWindow(GetDlgItem(hwndDlg, IDC_UDP_DEL), FALSE);
427                         }
428                         break;
429                     case IDC_UDP_RESTRICT:
430                         if (IsDlgButtonChecked(hwndDlg, IDC_UDP_RESTRICT) == BST_CHECKED)
431                         {
432                             CheckDlgButton(hwndDlg, IDC_UDP_ALLOW_ALL, BST_UNCHECKED);
433                             EnableWindow(GetDlgItem(hwndDlg, IDC_UDP_LIST), TRUE);
434                             EnableWindow(GetDlgItem(hwndDlg, IDC_UDP_ADD), TRUE);
435                             EnableWindow(GetDlgItem(hwndDlg, IDC_UDP_DEL), TRUE);
436                         }
437                         break;
438                     case IDC_IP_ALLOW_ALL:
439                         if (IsDlgButtonChecked(hwndDlg, IDC_IP_ALLOW_ALL) == BST_CHECKED)
440                         {
441                             CheckDlgButton(hwndDlg, IDC_IP_RESTRICT, BST_UNCHECKED);
442                             EnableWindow(GetDlgItem(hwndDlg, IDC_IP_LIST), FALSE);
443                             EnableWindow(GetDlgItem(hwndDlg, IDC_IP_ADD), FALSE);
444                             EnableWindow(GetDlgItem(hwndDlg, IDC_IP_DEL), FALSE);
445                         }
446                         break;
447                     case IDC_IP_RESTRICT:
448                         if (IsDlgButtonChecked(hwndDlg, IDC_IP_RESTRICT) == BST_CHECKED)
449                         {
450                             CheckDlgButton(hwndDlg, IDC_IP_ALLOW_ALL, BST_UNCHECKED);
451                             EnableWindow(GetDlgItem(hwndDlg, IDC_IP_LIST), TRUE);
452                             EnableWindow(GetDlgItem(hwndDlg, IDC_IP_ADD), TRUE);
453                             EnableWindow(GetDlgItem(hwndDlg, IDC_IP_DEL), TRUE);
454                         }
455                         break;
456                     case IDC_USE_FILTER:
457                         if (IsDlgButtonChecked(hwndDlg, IDC_USE_FILTER) == BST_UNCHECKED)
458                             DisplayError(IDS_DISABLE_FILTER, IDS_TCPIP, MB_OK);
459 
460                         break;
461                 }
462             }
463             switch(LOWORD(wParam))
464             {
465                 case IDC_OK:
466                     pContext = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
467                     pFilter = StoreTcpipFilterSettings(hwndDlg);
468                     if (pFilter)
469                     {
470                         if (pContext->pCurrentConfig->pFilter)
471                         {
472                             CoTaskMemFree(pContext->pCurrentConfig->pFilter->szTCPAllowedPorts);
473                             CoTaskMemFree(pContext->pCurrentConfig->pFilter->szUDPAllowedPorts);
474                             CoTaskMemFree(pContext->pCurrentConfig->pFilter->szRawIPAllowedProtocols);
475                             CoTaskMemFree(pContext->pCurrentConfig->pFilter);
476                         }
477                         pContext->pCurrentConfig->pFilter = pFilter;
478                     }
479                     EndDialog(hwndDlg, (INT_PTR)TRUE);
480                     break;
481                 case IDCANCEL:
482                     EndDialog(hwndDlg, FALSE);
483                     break;
484                 case IDC_TCP_ADD:
485                     AddItem(hwndDlg, GetDlgItem(hwndDlg, IDC_TCP_LIST), 65536, IDS_TCP_PORTS);
486                     break;
487                 case IDC_TCP_DEL:
488                     DelItem(GetDlgItem(hwndDlg, IDC_TCP_LIST));
489                     break;
490                 case IDC_UDP_ADD:
491                     AddItem(hwndDlg, GetDlgItem(hwndDlg, IDC_UDP_LIST), 65536, IDS_UDP_PORTS);
492                     break;
493                 case IDC_UDP_DEL:
494                     DelItem(GetDlgItem(hwndDlg, IDC_UDP_LIST));
495                     break;
496                 case IDC_IP_ADD:
497                     AddItem(hwndDlg, GetDlgItem(hwndDlg, IDC_IP_LIST), 256, IDS_IP_PROTO);
498                     break;
499                 case IDC_IP_DEL:
500                     DelItem(GetDlgItem(hwndDlg, IDC_IP_LIST));
501                     break;
502                 default:
503                     break;
504             }
505         default:
506             break;
507     }
508 
509     return FALSE;
510 }
511 
512 
513 HPROPSHEETPAGE
514 InitializePropertySheetPage(LPWSTR resname, DLGPROC dlgproc, LPARAM lParam, LPWSTR szTitle)
515 {
516     PROPSHEETPAGEW ppage;
517 
518     memset(&ppage, 0x0, sizeof(PROPSHEETPAGEW));
519     ppage.dwSize = sizeof(PROPSHEETPAGEW);
520     ppage.dwFlags = PSP_DEFAULT;
521     ppage.u.pszTemplate = resname;
522     ppage.pfnDlgProc = dlgproc;
523     ppage.lParam = lParam;
524     ppage.hInstance = netcfgx_hInstance;
525     if (szTitle)
526     {
527         ppage.dwFlags |= PSP_USETITLE;
528         ppage.pszTitle = szTitle;
529     }
530     return CreatePropertySheetPageW(&ppage);
531 }
532 
533 /***************************************************************
534  * TCP/IP Advanced Option Dialog
535  *
536  */
537 
538 VOID
539 InitializeTcpipAdvancedOptDlg(
540     HWND hwndDlg,
541     TcpipConfNotifyImpl * This)
542 {
543     WCHAR szText[500];
544     /* store context */
545     SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
546 
547     if (LoadStringW(netcfgx_hInstance, IDS_TCPFILTER, szText, sizeof(szText)/sizeof(WCHAR)))
548     {
549         szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
550         if (SendDlgItemMessageW(hwndDlg, IDC_OPTLIST, LB_ADDSTRING, 0, (LPARAM)szText) != LB_ERR)
551             SendDlgItemMessageW(hwndDlg, IDC_OPTLIST, LB_SETCURSEL, 0, 0);
552     }
553 
554     if (LoadStringW(netcfgx_hInstance, IDS_TCPFILTERDESC, szText, sizeof(szText)/sizeof(WCHAR)))
555     {
556         szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
557         SendDlgItemMessageW(hwndDlg, IDC_OPTDESC, WM_SETTEXT, 0, (LPARAM)szText);
558     }
559 }
560 
561 
562 
563 INT_PTR
564 CALLBACK
565 TcpipAdvancedOptDlg(
566     HWND hwndDlg,
567     UINT uMsg,
568     WPARAM wParam,
569     LPARAM lParam
570 )
571 {
572     TcpipConfNotifyImpl * This;
573     LPPROPSHEETPAGE page;
574 
575     switch(uMsg)
576     {
577         case WM_INITDIALOG:
578             page = (LPPROPSHEETPAGE)lParam;
579             This = (TcpipConfNotifyImpl*)page->lParam;
580             InitializeTcpipAdvancedOptDlg(hwndDlg, This);
581             return TRUE;
582         case WM_COMMAND:
583             if (LOWORD(wParam) == IDC_OPTPROP)
584             {
585                 DialogBoxParamW(netcfgx_hInstance,
586                                 MAKEINTRESOURCEW(IDD_TCPIP_FILTER_DLG),
587                                 GetParent(hwndDlg),
588                                 TcpipFilterSettingsDlg,
589                                 (LPARAM)GetWindowLongPtr(hwndDlg, DWLP_USER));
590                 break;
591             }
592     }
593     return FALSE;
594 }
595 
596 VOID
597 InsertColumnToListView(
598     HWND hDlgCtrl,
599     UINT ResId,
600     UINT SubItem,
601     UINT Size)
602 {
603     WCHAR szBuffer[200];
604     LVCOLUMNW lc;
605 
606     if (!LoadStringW(netcfgx_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
607         return;
608 
609     memset(&lc, 0, sizeof(LV_COLUMN) );
610     lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
611     lc.iSubItem   = SubItem;
612     lc.fmt = LVCFMT_FIXED_WIDTH;
613     lc.cx         = Size;
614     lc.cchTextMax = wcslen(szBuffer);
615     lc.pszText    = szBuffer;
616 
617     (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, SubItem, (LPARAM)&lc);
618 }
619 
620 VOID
621 InsertIpAddressToListView(
622     HWND hDlgCtrl,
623     IP_ADDR * pAddr,
624     BOOL bSubMask)
625 {
626     WCHAR szBuffer[70];
627     DWORD dwIpAddr;
628     UINT itemCount = 0;
629     LVITEMW li;
630 
631     while(pAddr)
632     {
633         ZeroMemory(&li, sizeof(li));
634         li.mask = LVIF_TEXT;
635         li.iItem = itemCount;
636         li.iSubItem = 0;
637         dwIpAddr = pAddr->IpAddress;
638         swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
639                  FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
640 
641         li.pszText = szBuffer;
642         li.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
643         if (li.iItem  != -1)
644         {
645             if (bSubMask)
646             {
647                 dwIpAddr = pAddr->u.Subnetmask;
648                 swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
649                          FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
650             }
651             else
652             {
653                 if (pAddr->u.Metric)
654                     swprintf(szBuffer, L"%u", pAddr->u.Metric);
655                 else
656                     LoadStringW(netcfgx_hInstance, IDS_AUTOMATIC, szBuffer, sizeof(szBuffer)/sizeof(WCHAR));
657             }
658 
659             li.mask = LVIF_TEXT;
660             li.iSubItem = 1;
661             li.pszText = szBuffer;
662             SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
663         }
664         itemCount++;
665         pAddr = pAddr->Next;
666     }
667 }
668 
669 VOID
670 InitializeTcpipAdvancedIpDlg(
671     HWND hwndDlg,
672     TcpipConfNotifyImpl * This)
673 {
674     RECT rect;
675     LVITEMW li;
676     WCHAR szBuffer[100];
677 
678     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_IPLIST), IDS_IPADDR, 0, 100);
679     GetClientRect(GetDlgItem(hwndDlg, IDC_IPLIST), &rect);
680     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_IPLIST), IDS_SUBMASK, 1, (rect.right - rect.left - 100));
681 
682     if (This->pCurrentConfig->DhcpEnabled)
683     {
684         if (LoadStringW(netcfgx_hInstance, IDS_DHCPACTIVE, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
685         {
686             ZeroMemory(&li, sizeof(LVITEMW));
687             li.mask = LVIF_TEXT;
688             li.pszText = szBuffer;
689             SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_INSERTITEMW, 0, (LPARAM)&li);
690         }
691         EnableWindow(GetDlgItem(hwndDlg, IDC_IPADD), FALSE);
692     }
693     else
694     {
695         InsertIpAddressToListView(GetDlgItem(hwndDlg, IDC_IPLIST), This->pCurrentConfig->Ip, TRUE);
696     }
697 
698     EnableWindow(GetDlgItem(hwndDlg, IDC_IPMOD), FALSE);
699     EnableWindow(GetDlgItem(hwndDlg, IDC_IPDEL), FALSE);
700 
701     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_GWLIST), IDS_GATEWAY, 0, 100);
702     GetClientRect(GetDlgItem(hwndDlg, IDC_IPLIST), &rect);
703     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_GWLIST), IDS_METRIC, 1, (rect.right - rect.left - 100));
704 
705     InsertIpAddressToListView(GetDlgItem(hwndDlg, IDC_GWLIST), This->pCurrentConfig->Gw, FALSE);
706 
707     EnableWindow(GetDlgItem(hwndDlg, IDC_GWMOD), FALSE);
708     EnableWindow(GetDlgItem(hwndDlg, IDC_GWDEL), FALSE);
709 
710     SendDlgItemMessageW(hwndDlg, IDC_METRIC, EM_LIMITTEXT, 4, 0);
711 }
712 
713 INT_PTR
714 CALLBACK
715 TcpipAdvGwDlg(
716     HWND hwndDlg,
717     UINT uMsg,
718     WPARAM wParam,
719     LPARAM lParam
720 )
721 {
722     WCHAR szBuffer[70];
723     TcpipGwSettings *pGwSettings;
724     DWORD dwIpAddr;
725     LPNMIPADDRESS lpnmipa;
726     LVFINDINFOW find;
727 
728     switch(uMsg)
729     {
730         case WM_INITDIALOG:
731             pGwSettings = (TcpipGwSettings *)lParam;
732             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
733 
734             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
735             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
736             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
737             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
738 
739             if (pGwSettings->bAdd)
740             {
741                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
742                 {
743                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
744                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
745                 }
746                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), FALSE);
747                 CheckDlgButton(hwndDlg, IDC_USEMETRIC, BST_CHECKED);
748             }
749             else
750             {
751                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
752                 {
753                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
754                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
755                 }
756 
757                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)GetIpAddressFromStringW(pGwSettings->szIP));
758 
759                 if (pGwSettings->Metric)
760                 {
761                     SetDlgItemInt(hwndDlg, IDC_METRIC, pGwSettings->Metric, FALSE);
762                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), TRUE);
763                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), TRUE);
764                 }
765                 else
766                 {
767                     CheckDlgButton(hwndDlg, IDC_USEMETRIC, BST_CHECKED);
768                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), FALSE);
769                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), FALSE);
770                 }
771             }
772             return TRUE;
773         case WM_COMMAND:
774             if (LOWORD(wParam) == IDC_USEMETRIC)
775             {
776                 if (IsDlgButtonChecked(hwndDlg, IDC_USEMETRIC) == BST_CHECKED)
777                 {
778                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), FALSE);
779                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), FALSE);
780                     SendDlgItemMessageW(hwndDlg, IDC_METRIC, WM_SETTEXT, 0, (LPARAM)L"");
781                 }
782                 else
783                 {
784                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), TRUE);
785                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), TRUE);
786                 }
787                 break;
788             }
789             else if (LOWORD(wParam) == IDCANCEL)
790             {
791                 EndDialog(hwndDlg, FALSE);
792                 break;
793             }
794             else if (LOWORD(wParam) == IDC_OK)
795             {
796                 if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
797                 {
798                     pGwSettings = (TcpipGwSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
799                     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_GETTEXT, 16, (LPARAM)pGwSettings->szIP);
800 
801                     ZeroMemory(&find, sizeof(LVFINDINFOW));
802                     find.flags = LVFI_STRING;
803                     find.psz = pGwSettings->szIP;
804 
805                     if (IsDlgButtonChecked(hwndDlg, IDC_USEMETRIC) == BST_UNCHECKED)
806                         pGwSettings->Metric = GetDlgItemInt(hwndDlg, IDC_METRIC, NULL, FALSE);
807                     else
808                         pGwSettings->Metric = 0;
809 
810 
811                     if (SendMessageW(pGwSettings->hDlgCtrl, LVM_FINDITEMW, (WPARAM)-1, (LPARAM)&find) == -1)
812                     {
813                         EndDialog(hwndDlg, TRUE);
814                         break;
815                     }
816                     if (!pGwSettings->bAdd)
817                     {
818                         EndDialog(hwndDlg, FALSE);
819                         break;
820                     }
821                     DisplayError(IDS_DUP_GW, IDS_TCPIP, MB_ICONINFORMATION);
822                 }
823                 break;
824             }
825             break;
826         case WM_NOTIFY:
827             lpnmipa = (LPNMIPADDRESS) lParam;
828             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
829             {
830                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
831                 {
832                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
833                         EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
834                 }
835             }
836             break;
837     }
838     return FALSE;
839 }
840 
841 BOOL
842 GetGWListEntry(HWND hDlgCtrl, INT Index, TcpipGwSettings * pGwSettings)
843 {
844     LVITEMW li;
845     WCHAR szBuffer[30];
846     BOOL bRet;
847 
848     ZeroMemory(&li, sizeof(LVITEMW));
849     li.mask = LVIF_TEXT;
850     li.cchTextMax = 16;
851     li.pszText = pGwSettings->szIP;
852     li.iItem = Index;
853 
854     if (!SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
855         return FALSE;
856     li.pszText = szBuffer;
857     li.cchTextMax = 30;
858     li.iSubItem = 1;
859 
860     bRet = SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li);
861     if (bRet)
862     {
863         pGwSettings->Metric = _wtoi(szBuffer);
864     }
865 
866     return bRet;
867 }
868 
869 INT_PTR
870 CALLBACK
871 TcpipAddIpDlg(
872     HWND hwndDlg,
873     UINT uMsg,
874     WPARAM wParam,
875     LPARAM lParam
876 )
877 {
878     LPNMIPADDRESS lpnmipa;
879     DWORD dwIpAddr;
880     TcpipIpSettings *pIpSettings;
881     WCHAR szBuffer[50];
882     LVFINDINFOW find;
883     LRESULT lResult;
884 
885     switch(uMsg)
886     {
887         case WM_INITDIALOG:
888             pIpSettings = (TcpipIpSettings*)lParam;
889             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
890 
891             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
892             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
893             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
894             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
895             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 0, MAKEIPRANGE(0, 255));
896             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
897             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
898             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
899 
900             if (pIpSettings->bAdd)
901             {
902                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
903                 {
904                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
905                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
906                 }
907                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), FALSE);
908             }
909             else
910             {
911                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
912                 {
913                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
914                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
915                 }
916 
917                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)GetIpAddressFromStringW(pIpSettings->szIP));
918                 SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)GetIpAddressFromStringW(pIpSettings->szMask));
919             }
920             return TRUE;
921         case WM_NOTIFY:
922             lpnmipa = (LPNMIPADDRESS) lParam;
923             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
924             {
925                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
926                 {
927                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
928                     {
929                         if (dwIpAddr <= MAKEIPADDRESS(127, 255, 255, 255))
930                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 0, 0, 0));
931                         else if (dwIpAddr <= MAKEIPADDRESS(191, 255, 255, 255))
932                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 0, 0));
933                         else if (dwIpAddr <= MAKEIPADDRESS(223, 255, 255, 255))
934                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 255, 0));
935                         EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
936                      }
937                 }
938             }
939             break;
940         case WM_COMMAND:
941             if (LOWORD(wParam) == IDC_OK)
942             {
943                 pIpSettings = (TcpipIpSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
944                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_GETTEXT, 16, (LPARAM)pIpSettings->szIP);
945                 SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, WM_GETTEXT, 16, (LPARAM)pIpSettings->szMask);
946 
947                 ZeroMemory(&find, sizeof(LVFINDINFOW));
948                 find.flags = LVFI_STRING;
949                 find.psz = pIpSettings->szIP;
950                 lResult = SendMessageW(pIpSettings->hDlgCtrl, LVM_FINDITEMW, (WPARAM)-1, (LPARAM)&find);
951 
952                 if (lResult == -1)
953                 {
954                     EndDialog(hwndDlg, TRUE);
955                     break;
956                 }
957                 else if (!pIpSettings->bAdd)
958                 {
959                     EndDialog(hwndDlg, FALSE);
960                     break;
961                 }
962                 DisplayError(IDS_DUP_IPADDR, IDS_TCPIP, MB_ICONINFORMATION);
963                 break;
964             }
965             else if (LOWORD(wParam) == IDCANCEL)
966             {
967                 EndDialog(hwndDlg, FALSE);
968             }
969             break;
970     }
971     return FALSE;
972 }
973 
974 BOOL
975 VerifyDNSSuffix(
976     LPWSTR szName)
977 {
978     UINT Index;
979     UINT Length = wcslen(szName);
980 
981     for(Index = 0; Index < Length; Index++)
982         if (iswalnum(szName[Index]) == 0 && szName[Index] != '.' && szName[Index] != '-')
983             return FALSE;
984 
985     return TRUE;
986 }
987 
988 INT_PTR
989 CALLBACK
990 TcpipAddSuffixDlg(
991     HWND hwndDlg,
992     UINT uMsg,
993     WPARAM wParam,
994     LPARAM lParam
995 )
996 {
997     WCHAR szBuffer[100];
998     TcpipSuffixSettings * pSettings;
999     LRESULT lLength;
1000 
1001     switch(uMsg)
1002     {
1003         case WM_INITDIALOG:
1004             pSettings = (TcpipSuffixSettings*)lParam;
1005             if (!pSettings->bAdd)
1006             {
1007                 SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_SETTEXT, 0, (LPARAM)pSettings->Suffix);
1008                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1009                 {
1010                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1011                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1012                 }
1013                 CoTaskMemFree(pSettings->Suffix);
1014                 pSettings->Suffix = NULL;
1015             }
1016             else
1017             {
1018                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1019                 {
1020                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1021                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1022                 }
1023             }
1024             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSettings);
1025             return TRUE;
1026         case WM_COMMAND:
1027            if (LOWORD(wParam) == IDCANCEL)
1028            {
1029                EndDialog(hwndDlg, FALSE);
1030                break;
1031            }
1032            else if (LOWORD(wParam) == IDC_OK)
1033            {
1034                lLength = SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_GETTEXTLENGTH, 0, 0);
1035                if (lLength)
1036                {
1037                    pSettings = (TcpipSuffixSettings*) GetWindowLongPtr(hwndDlg, DWLP_USER);
1038                    pSettings->Suffix = (LPWSTR)CoTaskMemAlloc((lLength + 1)* sizeof(WCHAR));
1039                    if (pSettings->Suffix)
1040                    {
1041                        SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_GETTEXT, lLength + 1, (LPARAM)pSettings->Suffix);
1042                        if (SendMessageW(pSettings->hDlgCtrl, LB_FINDSTRING, 0, (LPARAM)pSettings->Suffix) != LB_ERR)
1043                        {
1044                            DisplayError(IDS_DUP_SUFFIX, IDS_TCPIP, MB_ICONWARNING);
1045                            CoTaskMemFree(pSettings->Suffix);
1046                            break;
1047                        }
1048 
1049                        if (!VerifyDNSSuffix(pSettings->Suffix))
1050                        {
1051                            DisplayError(IDS_DOMAIN_SUFFIX, IDS_TCPIP, MB_ICONWARNING);
1052                            CoTaskMemFree(pSettings->Suffix);
1053                            break;
1054                        }
1055                        EndDialog(hwndDlg, TRUE);
1056                    }
1057                }
1058                break;
1059            }
1060     }
1061     return FALSE;
1062 }
1063 
1064 
1065 INT
1066 GetSelectedItem(HWND hDlgCtrl)
1067 {
1068     LVITEMW li;
1069     UINT iItemCount, iIndex;
1070 
1071     iItemCount = ListView_GetItemCount(hDlgCtrl);
1072     if (!iItemCount)
1073         return -1;
1074 
1075     for (iIndex = 0; iIndex < iItemCount; iIndex++)
1076     {
1077         ZeroMemory(&li, sizeof(LVITEMW));
1078         li.mask = LVIF_STATE;
1079         li.stateMask = (UINT)-1;
1080         li.iItem = iIndex;
1081         if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
1082         {
1083             if (li.state & LVIS_SELECTED)
1084                 return iIndex;
1085         }
1086     }
1087     return -1;
1088 }
1089 
1090 
1091 BOOL
1092 GetIPListEntry(HWND hDlgCtrl, INT Index, TcpipIpSettings * pIpSettings)
1093 {
1094     LVITEMW li;
1095 
1096     ZeroMemory(&li, sizeof(LVITEMW));
1097     li.mask = LVIF_TEXT;
1098     li.cchTextMax = 16;
1099     li.pszText = pIpSettings->szIP;
1100     li.iItem = Index;
1101 
1102     if (!SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
1103         return FALSE;
1104 
1105     ZeroMemory(&li, sizeof(LVITEMW));
1106     li.mask = LVIF_TEXT;
1107     li.cchTextMax = 16;
1108     li.pszText = pIpSettings->szMask;
1109     li.iSubItem = 1;
1110     li.iItem = Index;
1111 
1112     return SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li);
1113 }
1114 
1115 VOID
1116 DeleteItemFromList(HWND hDlgCtrl)
1117 {
1118     LVITEMW li;
1119 
1120     memset(&li, 0x0, sizeof(LVITEMW));
1121     li.iItem = GetSelectedItem(hDlgCtrl);
1122     if (li.iItem < 0)
1123     {
1124         DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONINFORMATION);
1125         SetFocus(hDlgCtrl);
1126     }
1127     else
1128     {
1129         (void)ListView_DeleteItem(hDlgCtrl, li.iItem);
1130     }
1131 }
1132 
1133 UINT
1134 GetIpAddressFromStringW(
1135     WCHAR * szBuffer)
1136 {
1137     DWORD dwIpAddr = 0;
1138     INT Val;
1139     UINT Index = 3;
1140     LPWSTR pLast = szBuffer;
1141     LPWSTR pNext = szBuffer;
1142 
1143 
1144     while((pNext = wcschr(pNext, L'.')))
1145     {
1146         pNext[0] = L'\0';
1147         Val = _wtoi(pLast);
1148         dwIpAddr |= (Val << Index * 8);
1149         Index--;
1150         pNext++;
1151         pLast = pNext;
1152     }
1153     dwIpAddr |= _wtoi(pLast);
1154 
1155     return dwIpAddr;
1156 }
1157 
1158 UINT
1159 GetIpAddressFromStringA(
1160     char * sBuffer)
1161 {
1162     WCHAR szIp[16];
1163 
1164     if (MultiByteToWideChar(CP_ACP, 0, sBuffer, -1, szIp, 16))
1165     {
1166         szIp[15] = L'\0';
1167        return GetIpAddressFromStringW(szIp);
1168     }
1169     return (UINT)-1;
1170 }
1171 
1172 
1173 VOID
1174 FreeIPAddr(IP_ADDR *pAddr)
1175 {
1176     IP_ADDR *pNext;
1177 
1178     if (!pAddr)
1179         return;
1180 
1181     while(pAddr)
1182     {
1183         pNext = pAddr->Next;
1184         CoTaskMemFree(pAddr);
1185         pAddr = pNext;
1186     }
1187 }
1188 
1189 BOOL
1190 GetListViewItem(HWND hDlgCtrl, UINT Index, UINT SubIndex, WCHAR * szBuffer, UINT BufferSize)
1191 {
1192     LVITEMW li;
1193 
1194     ZeroMemory(&li, sizeof(LVITEMW));
1195     li.mask = LVIF_TEXT;
1196     li.pszText = szBuffer;
1197     li.iItem = Index;
1198     li.iSubItem = SubIndex;
1199     li.cchTextMax = BufferSize;
1200     return SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li);
1201 }
1202 
1203 VOID
1204 StoreIPSettings(
1205     HWND hDlgCtrl,
1206     TcpipConfNotifyImpl * This,
1207     BOOL bSubmask)
1208 {
1209     WCHAR szBuffer[30];
1210 
1211     INT iIndex, iCount;
1212     IP_ADDR *pCur, *pLast;
1213 
1214     iCount = ListView_GetItemCount(hDlgCtrl);
1215     if (!iCount)
1216     {
1217         return;
1218     }
1219 
1220     pLast = NULL;
1221     for(iIndex = 0; iIndex < iCount; iIndex++)
1222     {
1223         if (GetListViewItem(hDlgCtrl, iIndex, 0, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1224         {
1225             pCur = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
1226             if (!pCur)
1227                 break;
1228             ZeroMemory(pCur, sizeof(IP_ADDR));
1229 
1230             szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1231             pCur->IpAddress = GetIpAddressFromStringW(szBuffer);
1232 
1233             if (GetListViewItem(hDlgCtrl, iIndex, 1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR) ))
1234             {
1235                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1236                 if (bSubmask)
1237                     pCur->u.Subnetmask = GetIpAddressFromStringW(szBuffer);
1238                 else
1239                     pCur->u.Metric  = _wtoi(szBuffer);
1240             }
1241 
1242             if (!pLast)
1243             {
1244                 if (bSubmask)
1245                     This->pCurrentConfig->Ip = pCur;
1246                 else
1247                     This->pCurrentConfig->Gw = pCur;
1248             }
1249             else
1250             {
1251                 pLast->Next = pCur;
1252             }
1253 
1254             pLast = pCur;
1255         }
1256     }
1257 }
1258 
1259 
1260 INT_PTR
1261 CALLBACK
1262 TcpipAdvancedIpDlg(
1263     HWND hwndDlg,
1264     UINT uMsg,
1265     WPARAM wParam,
1266     LPARAM lParam
1267 )
1268 {
1269     TcpipConfNotifyImpl * This;
1270     LPPROPSHEETPAGE page;
1271     INT_PTR res;
1272     WCHAR szBuffer[200];
1273     LPPSHNOTIFY lppsn;
1274     TcpipGwSettings Gw;
1275     TcpipIpSettings Ip;
1276 
1277     LVITEMW li;
1278 
1279     switch(uMsg)
1280     {
1281         case WM_INITDIALOG:
1282             page = (LPPROPSHEETPAGE)lParam;
1283             This = (TcpipConfNotifyImpl*)page->lParam;
1284             InitializeTcpipAdvancedIpDlg(hwndDlg, This);
1285             SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)This);
1286             return TRUE;
1287         case WM_NOTIFY:
1288             lppsn = (LPPSHNOTIFY) lParam;
1289             if (lppsn->hdr.code == LVN_ITEMCHANGED)
1290             {
1291                 LPNMLISTVIEW lplv = (LPNMLISTVIEW)lParam;
1292                 BOOL bEnable;
1293 
1294                 if (lplv->hdr.idFrom == IDC_IPLIST)
1295                 {
1296                     This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1297 
1298                     bEnable = ((lplv->uNewState & LVIS_SELECTED) != 0) &&
1299                               (!This->pCurrentConfig->DhcpEnabled);
1300 
1301                     EnableWindow(GetDlgItem(hwndDlg, IDC_IPMOD), bEnable);
1302                     EnableWindow(GetDlgItem(hwndDlg, IDC_IPDEL), bEnable);
1303                 }
1304                 else if (lplv->hdr.idFrom == IDC_GWLIST)
1305                 {
1306                     bEnable = ((lplv->uNewState & LVIS_SELECTED) != 0);
1307 
1308                     EnableWindow(GetDlgItem(hwndDlg, IDC_GWMOD), bEnable);
1309                     EnableWindow(GetDlgItem(hwndDlg, IDC_GWDEL), bEnable);
1310                 }
1311             }
1312             else if (lppsn->hdr.code == PSN_KILLACTIVE)
1313             {
1314                 This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1315                 if (!This->pCurrentConfig->DhcpEnabled && ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_IPLIST)) == 0)
1316                 {
1317                     DisplayError(IDS_NO_IPADDR_SET, IDS_TCPIP, MB_ICONWARNING);
1318                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
1319                     return TRUE;
1320                 }
1321             }
1322             else if (lppsn->hdr.code == PSN_APPLY)
1323             {
1324                 This = (TcpipConfNotifyImpl*) GetWindowLongPtr(hwndDlg, DWLP_USER);
1325                 FreeIPAddr(This->pCurrentConfig->Gw);
1326                 This->pCurrentConfig->Gw = NULL;
1327                 FreeIPAddr(This->pCurrentConfig->Ip);
1328                 This->pCurrentConfig->Ip = NULL;
1329                 StoreIPSettings(GetDlgItem(hwndDlg, IDC_IPLIST), This, TRUE);
1330                 StoreIPSettings(GetDlgItem(hwndDlg, IDC_GWLIST), This, FALSE);
1331                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
1332                 return TRUE;
1333             }
1334             break;
1335         case WM_COMMAND:
1336             if (LOWORD(wParam) == IDC_AUTOMETRIC)
1337             {
1338                 if (IsDlgButtonChecked(hwndDlg, IDC_AUTOMETRIC) == BST_CHECKED)
1339                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), FALSE);
1340                 else
1341                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), TRUE);
1342             }
1343             else if (LOWORD(wParam) == IDC_IPADD)
1344             {
1345                 Ip.bAdd = TRUE;
1346                 Ip.hDlgCtrl = GetDlgItem(hwndDlg, IDC_IPLIST);
1347                 res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPADDIP_DLG), hwndDlg, TcpipAddIpDlg, (LPARAM)&Ip);
1348                 if (res)
1349                 {
1350                     memset(&li, 0x0, sizeof(LVITEMW));
1351                     li.mask = LVIF_TEXT | LVIF_PARAM;
1352                     li.iItem = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_IPLIST));
1353                     li.pszText = Ip.szIP;
1354                     li.iItem = SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_INSERTITEMW, 0, (LPARAM)&li);
1355                     if (li.iItem  != -1)
1356                     {
1357                         li.mask = LVIF_TEXT;
1358                         li.iSubItem = 1;
1359                         li.pszText = Ip.szMask;
1360                         SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1361                     }
1362                 }
1363             }
1364             else if (LOWORD(wParam) == IDC_IPMOD)
1365             {
1366                 memset(&li, 0x0, sizeof(LVITEMW));
1367                 li.iItem = GetSelectedItem(GetDlgItem(hwndDlg, IDC_IPLIST));
1368                 if (li.iItem < 0)
1369                 {
1370                     /* no item selected */
1371                     DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONINFORMATION);
1372                     SetFocus(GetDlgItem(hwndDlg, IDC_IPLIST));
1373                     break;
1374                 }
1375                 Ip.bAdd = FALSE;
1376                 Ip.hDlgCtrl = GetDlgItem(hwndDlg, IDC_IPLIST);
1377                 if (GetIPListEntry(GetDlgItem(hwndDlg, IDC_IPLIST), li.iItem, &Ip))
1378                 {
1379                     res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPADDIP_DLG), hwndDlg, TcpipAddIpDlg, (LPARAM)&Ip);
1380                     if (res)
1381                     {
1382                             li.mask = LVIF_TEXT;
1383                             li.pszText = Ip.szIP;
1384                             SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1385                             li.pszText = Ip.szMask;
1386                             li.iSubItem = 1;
1387                             SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1388                     }
1389                 }
1390             }
1391             else if (LOWORD(wParam) == IDC_IPDEL)
1392             {
1393                 DeleteItemFromList(GetDlgItem(hwndDlg, IDC_IPLIST));
1394                 break;
1395             }
1396             else if (LOWORD(wParam) == IDC_GWADD)
1397             {
1398                 Gw.bAdd = TRUE;
1399                 Gw.hDlgCtrl = GetDlgItem(hwndDlg, IDC_GWLIST);
1400                 res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPGW_DLG), hwndDlg, TcpipAdvGwDlg, (LPARAM)&Gw);
1401                 if (res)
1402                 {
1403                     memset(&li, 0x0, sizeof(LVITEMW));
1404                     li.mask = LVIF_TEXT;
1405                     li.iItem = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_GWLIST));
1406                     li.pszText = Gw.szIP;
1407                     li.iItem = SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_INSERTITEMW, 0, (LPARAM)&li);
1408                     if (li.iItem >= 0)
1409                     {
1410                         if (Gw.Metric)
1411                         {
1412                             swprintf(szBuffer, L"%u", Gw.Metric);
1413                             li.iSubItem = 1;
1414                             li.pszText = szBuffer;
1415                             SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1416                         }
1417                         else
1418                         {
1419                             if (LoadStringW(netcfgx_hInstance, IDS_AUTOMATIC, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1420                             {
1421                                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1422                                 li.iSubItem = 1;
1423                                 li.pszText = szBuffer;
1424                                 SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1425                             }
1426                         }
1427                     }
1428                 }
1429                 break;
1430             }
1431             else if (LOWORD(wParam) == IDC_GWMOD)
1432             {
1433                 memset(&li, 0x0, sizeof(LVITEMW));
1434                 li.iItem = GetSelectedItem(GetDlgItem(hwndDlg, IDC_GWLIST));
1435                 if (li.iItem < 0)
1436                 {
1437                     /* no item selected */
1438                     DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONINFORMATION);
1439                     SetFocus(GetDlgItem(hwndDlg, IDC_GWLIST));
1440                     break;
1441                 }
1442                 if (GetGWListEntry(GetDlgItem(hwndDlg, IDC_GWLIST), li.iItem, &Gw))
1443                 {
1444                     Gw.bAdd = FALSE;
1445                     Gw.hDlgCtrl = GetDlgItem(hwndDlg, IDC_GWLIST);
1446                     res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPGW_DLG), hwndDlg, TcpipAdvGwDlg, (LPARAM)&Gw);
1447                     if (res)
1448                     {
1449                         li.mask = LVIF_TEXT;
1450                         li.pszText = Gw.szIP;
1451                         (void)SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1452                         if (Gw.Metric)
1453                         {
1454                             swprintf(szBuffer, L"%u", Gw.Metric);
1455                             li.iSubItem = 1;
1456                             li.pszText = szBuffer;
1457                             SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1458                         }
1459                         else
1460                         {
1461                             if (LoadStringW(netcfgx_hInstance, IDS_AUTOMATIC, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1462                             {
1463                                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1464                                 li.iSubItem = 1;
1465                                 li.pszText = szBuffer;
1466                                 SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1467                             }
1468                         }
1469                     }
1470                 }
1471                 break;
1472             }
1473             else if (LOWORD(wParam) == IDC_GWDEL)
1474             {
1475                 DeleteItemFromList(GetDlgItem(hwndDlg, IDC_GWLIST));
1476                 break;
1477             }
1478     }
1479     return FALSE;
1480 }
1481 
1482 INT_PTR
1483 CALLBACK
1484 TcpipAddDNSDlg(
1485     HWND hwndDlg,
1486     UINT uMsg,
1487     WPARAM wParam,
1488     LPARAM lParam
1489 )
1490 {
1491     TcpipDnsSettings * pSettings;
1492     WCHAR szBuffer[100];
1493     DWORD dwIpAddr;
1494     LPNMIPADDRESS lpnmipa;
1495 
1496     switch(uMsg)
1497     {
1498         case WM_INITDIALOG:
1499             pSettings = (TcpipDnsSettings*)lParam;
1500             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
1501             if (!pSettings->bAdd)
1502             {
1503                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1504                 {
1505                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1506                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1507                 }
1508                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_SETTEXT, 0, (LPARAM)pSettings->szIP);
1509                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
1510             }
1511             else
1512             {
1513                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1514                 {
1515                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1516                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1517                 }
1518                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), FALSE);
1519             }
1520             return TRUE;
1521         case WM_COMMAND:
1522             if (LOWORD(wParam) == IDCANCEL)
1523             {
1524                 EndDialog(hwndDlg, FALSE);
1525                 break;
1526             }
1527             else if (LOWORD(wParam) == IDC_OK)
1528             {
1529                 pSettings = (TcpipDnsSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1530                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_GETTEXT, 16, (LPARAM)pSettings->szIP);
1531                 if (SendMessageW(pSettings->hDlgCtrl, LB_FINDSTRING, 0, (LPARAM)pSettings->szIP) == LB_ERR)
1532                 {
1533                     if (pSettings->bAdd)
1534                         SendMessageW(pSettings->hDlgCtrl, LB_ADDSTRING, 0, (LPARAM)pSettings->szIP);
1535                     EndDialog(hwndDlg, TRUE);
1536                     break;
1537                 }
1538                 if (!pSettings->bAdd)
1539                 {
1540                     EndDialog(hwndDlg, FALSE);
1541                     break;
1542                 }
1543                 DisplayError(IDS_DUP_SUFFIX, IDS_TCPIP, MB_ICONERROR);
1544                 break;
1545             }
1546             break;
1547         case WM_NOTIFY:
1548             lpnmipa = (LPNMIPADDRESS) lParam;
1549             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
1550             {
1551                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
1552                 {
1553                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
1554                         EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
1555                 }
1556             }
1557             break;
1558     }
1559     return FALSE;
1560 }
1561 
1562 
1563 
1564 VOID
1565 InitializeTcpipAdvancedDNSDlg(
1566     HWND hwndDlg,
1567     TcpipConfNotifyImpl * This)
1568 {
1569     WCHAR szBuffer[200];
1570     LPWSTR pFirst, pSep, pList;
1571     IP_ADDR * pAddr;
1572     DWORD dwIpAddr;
1573 
1574     /* insert DNS addresses */
1575     pAddr = This->pCurrentConfig->Ns;
1576     while(pAddr)
1577     {
1578         dwIpAddr = pAddr->IpAddress;
1579         swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
1580                  FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
1581 
1582         SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_ADDSTRING, 0, (LPARAM)szBuffer);
1583         pAddr = pAddr->Next;
1584     }
1585     SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_SETCURSEL, 0, 0);
1586 
1587     if (!This->pCurrentConfig->pDNS)
1588         return;
1589 
1590     if (This->pCurrentConfig->pDNS->RegisterAdapterName)
1591         CheckDlgButton(hwndDlg, IDC_REGSUFFIX, BST_CHECKED);
1592     else
1593         EnableWindow(GetDlgItem(hwndDlg, IDC_USESUFFIX), FALSE);
1594 
1595     if (This->pCurrentConfig->pDNS->RegistrationEnabled)
1596         CheckDlgButton(hwndDlg, IDC_USESUFFIX, BST_CHECKED);
1597 
1598     if (This->pCurrentConfig->pDNS->szDomain[0])
1599         SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_SETTEXT, 0, (LPARAM)szBuffer);
1600 
1601     if (This->pCurrentConfig->pDNS->UseDomainNameDevolution)
1602         CheckDlgButton(hwndDlg, IDC_TOPPRIMSUFFIX, BST_CHECKED);
1603 
1604     if (!This->pCurrentConfig->pDNS->szSearchList || (wcslen(This->pCurrentConfig->pDNS->szSearchList) == 0))
1605     {
1606         CheckDlgButton(hwndDlg, IDC_PRIMSUFFIX, BST_CHECKED);
1607         EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXADD), FALSE);
1608 
1609         return;
1610     }
1611 
1612     pList = This->pCurrentConfig->pDNS->szSearchList;
1613     if (wcslen(pList))
1614     {
1615         pFirst = pList;
1616         do
1617         {
1618             pSep = wcschr(pFirst, L',');
1619             if (pSep)
1620             {
1621                 pSep[0] = L'\0';
1622                 SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_ADDSTRING, 0, (LPARAM)pFirst);
1623                 pFirst = pSep + 1;
1624                 pSep[0] = L',';
1625             }
1626             else
1627             {
1628                 SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_ADDSTRING, 0, (LPARAM)pFirst);
1629                 break;
1630             }
1631         }while(TRUE);
1632 
1633         EnableWindow(GetDlgItem(hwndDlg, IDC_TOPPRIMSUFFIX), FALSE);
1634         CheckDlgButton(hwndDlg, IDC_SELSUFFIX, BST_CHECKED);
1635         SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_SETCURSEL, 0, 0);
1636     }
1637 }
1638 
1639 VOID
1640 ToggleUpDown(HWND hwndDlg, HWND hDlgCtrl, UINT UpButton, UINT DownButton, UINT ModButton, UINT DelButton)
1641 {
1642     LRESULT lResult, lCount;
1643 
1644     lResult = SendMessageW(hDlgCtrl, LB_GETCURSEL, 0, 0);
1645     lCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1646     if (lResult != LB_ERR)
1647     {
1648         if (lResult == 0)
1649             EnableWindow(GetDlgItem(hwndDlg, UpButton), FALSE);
1650         else
1651              EnableWindow(GetDlgItem(hwndDlg, UpButton), TRUE);
1652 
1653         if (lResult < lCount -1)
1654              EnableWindow(GetDlgItem(hwndDlg, DownButton), TRUE);
1655         else
1656              EnableWindow(GetDlgItem(hwndDlg, DownButton), FALSE);
1657     }
1658 
1659     if (lCount)
1660     {
1661         EnableWindow(GetDlgItem(hwndDlg, ModButton), TRUE);
1662         EnableWindow(GetDlgItem(hwndDlg, DelButton), TRUE);
1663     }
1664     else
1665     {
1666         EnableWindow(GetDlgItem(hwndDlg, ModButton), FALSE);
1667         EnableWindow(GetDlgItem(hwndDlg, DelButton), FALSE);
1668         EnableWindow(GetDlgItem(hwndDlg, UpButton), FALSE);
1669         EnableWindow(GetDlgItem(hwndDlg, DownButton), FALSE);
1670     }
1671 }
1672 
1673 VOID
1674 MoveItem(
1675     HWND hDlgCtrl,
1676     INT pos)
1677 {
1678     WCHAR szBuffer[100];
1679     LRESULT lResult;
1680 
1681     lResult = SendMessageW(hDlgCtrl, LB_GETCURSEL, 0, 0);
1682     if (lResult != LB_ERR)
1683     {
1684         if (SendMessageW(hDlgCtrl, LB_GETTEXTLEN, (WPARAM)lResult, 0) < sizeof(szBuffer)/sizeof(WCHAR) - 1)
1685         {
1686             if (SendMessageW(hDlgCtrl, LB_GETTEXT, (WPARAM)lResult, (LPARAM)szBuffer) != LB_ERR)
1687             {
1688                 SendMessageW(hDlgCtrl, LB_DELETESTRING, (WPARAM)lResult, 0);
1689                 SendMessageW(hDlgCtrl, LB_INSERTSTRING, (WPARAM)lResult + pos, (LPARAM)szBuffer);
1690                 SendMessageW(hDlgCtrl, LB_SETCURSEL, (WPARAM)lResult + pos, 0);
1691             }
1692         }
1693     }
1694 }
1695 VOID
1696 RemoveItem(
1697     HWND hDlgCtrl)
1698 {
1699     LRESULT lResult, lCount;
1700 
1701     lResult = SendMessageW(hDlgCtrl, LB_GETCURSEL, 0, 0);
1702     if (lResult != LB_ERR)
1703     {
1704         SendMessageW(hDlgCtrl, LB_DELETESTRING, (WPARAM)lResult, 0);
1705         lCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1706         if (lResult + 1 < lCount)
1707             SendMessageW(hDlgCtrl, LB_SETCURSEL, (WPARAM)lResult, 0);
1708         else
1709             SendMessageW(hDlgCtrl, LB_SETCURSEL, (WPARAM)lCount-1, 0);
1710     }
1711 }
1712 
1713 LPWSTR
1714 GetListViewEntries(
1715     HWND hDlgCtrl)
1716 {
1717     DWORD dwSize;
1718     INT iCount, iIndex;
1719     INT_PTR lResult;
1720     LPWSTR pszSearchList, pItem;
1721 
1722     iCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1723     if (!iCount || iCount == LB_ERR)
1724         return NULL; //BUGBUG
1725 
1726     dwSize = 0;
1727 
1728     for (iIndex = 0; iIndex < iCount; iIndex++)
1729     {
1730         lResult = SendMessageW(hDlgCtrl, LB_GETTEXTLEN, iIndex, 0);
1731         if (lResult == LB_ERR)
1732             return NULL;
1733 
1734         dwSize += lResult + 1;
1735     }
1736 
1737     pszSearchList = (LPWSTR)CoTaskMemAlloc((dwSize + 1) * sizeof(WCHAR));
1738     if (!pszSearchList)
1739         return NULL;
1740 
1741     pItem = pszSearchList;
1742     for (iIndex = 0; iIndex < iCount; iIndex++)
1743     {
1744         lResult = SendMessageW(hDlgCtrl, LB_GETTEXT, iIndex, (LPARAM)pItem);
1745         if (lResult == LB_ERR)
1746         {
1747             CoTaskMemFree(pszSearchList);
1748             return NULL;
1749         }
1750         dwSize -= lResult + 1;
1751         pItem += wcslen(pItem);
1752         if (iIndex != iCount -1)
1753         {
1754             pItem[0] = L',';
1755             pItem++;
1756         }
1757     }
1758     pItem[0] = L'\0';
1759     return pszSearchList;
1760 }
1761 
1762 VOID
1763 StoreDNSSettings(
1764     HWND hDlgCtrl,
1765     TcpipConfNotifyImpl *This)
1766 {
1767     INT iCount, iIndex;
1768     WCHAR Ip[16];
1769     IP_ADDR *pCur, *pLast;
1770 
1771     FreeIPAddr(This->pCurrentConfig->Ns);
1772     This->pCurrentConfig->Ns = NULL;
1773 
1774     iCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1775     if (!iCount || iCount == LB_ERR)
1776     {
1777         return;
1778     }
1779 
1780     pLast = NULL;
1781     for(iIndex = 0; iIndex < iCount; iIndex++)
1782     {
1783         if (SendMessageW(hDlgCtrl, LB_GETTEXT, iIndex, (LPARAM)Ip) == LB_ERR)
1784             break;
1785 
1786         pCur = CoTaskMemAlloc(sizeof(IP_ADDR));
1787         if (!pCur)
1788             break;
1789         ZeroMemory(pCur, sizeof(IP_ADDR));
1790         pCur->IpAddress = GetIpAddressFromStringW(Ip);
1791 
1792         if (!pLast)
1793             This->pCurrentConfig->Ns = pCur;
1794         else
1795             pLast->Next = pCur;
1796 
1797         pLast = pCur;
1798         pCur = pCur->Next;
1799     }
1800     This->pCurrentConfig->AutoconfigActive = FALSE;
1801 }
1802 
1803 INT_PTR
1804 CALLBACK
1805 TcpipAdvancedDnsDlg(
1806     HWND hwndDlg,
1807     UINT uMsg,
1808     WPARAM wParam,
1809     LPARAM lParam
1810 )
1811 {
1812     TcpipConfNotifyImpl * This;
1813     LPPROPSHEETPAGE page;
1814     TcpipDnsSettings Dns;
1815     LRESULT lIndex, lLength;
1816     TcpipSuffixSettings Suffix;
1817     LPPSHNOTIFY lppsn;
1818     WCHAR szSuffix[100];
1819     WCHAR szFormat[200];
1820     WCHAR szBuffer[300];
1821 
1822 
1823     switch(uMsg)
1824     {
1825         case WM_INITDIALOG:
1826             page = (LPPROPSHEETPAGE)lParam;
1827             This = (TcpipConfNotifyImpl*)page->lParam;
1828             SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)This);
1829             InitializeTcpipAdvancedDNSDlg(hwndDlg, This);
1830             ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1831             ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1832             return TRUE;
1833         case WM_NOTIFY:
1834             lppsn = (LPPSHNOTIFY) lParam;
1835             if (lppsn->hdr.code == PSN_KILLACTIVE)
1836             {
1837                 if (IsDlgButtonChecked(hwndDlg, IDC_SELSUFFIX) == BST_CHECKED &&
1838                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_GETCOUNT, 0, 0) == 0)
1839                 {
1840                     DisplayError(IDS_NO_SUFFIX, IDS_TCPIP, MB_ICONWARNING);
1841                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
1842                     return TRUE;
1843                 }
1844                 if (SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_GETTEXT, sizeof(szSuffix)/sizeof(WCHAR), (LPARAM)szSuffix))
1845                 {
1846                     szSuffix[(sizeof(szSuffix)/sizeof(WCHAR))-1] = L'\0';
1847                     if (VerifyDNSSuffix(szSuffix) == FALSE)
1848                     {
1849                         if (LoadStringW(netcfgx_hInstance, IDS_DNS_SUFFIX, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
1850                         {
1851                             szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
1852                             swprintf(szBuffer, szFormat, szSuffix);
1853                             if (LoadStringW(netcfgx_hInstance, IDS_TCPIP, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
1854                                 szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
1855                             else
1856                                 szFormat[0] = L'\0';
1857 
1858                             MessageBoxW(hwndDlg, szBuffer, szFormat, MB_ICONWARNING);
1859                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
1860                             SetFocus(GetDlgItem(hwndDlg, IDC_SUFFIX));
1861                             return TRUE;
1862                         }
1863                     }
1864                 }
1865             }
1866             else if (lppsn->hdr.code == PSN_APPLY)
1867             {
1868                  This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1869                  if (!This->pCurrentConfig->pDNS)
1870                    break;
1871 
1872                  StoreDNSSettings(GetDlgItem(hwndDlg, IDC_DNSADDRLIST), This);
1873                  if (IsDlgButtonChecked(hwndDlg, IDC_PRIMSUFFIX) == BST_CHECKED)
1874                  {
1875                      CoTaskMemFree(This->pCurrentConfig->pDNS->szSearchList);
1876                      This->pCurrentConfig->pDNS->szSearchList = NULL;
1877                      if (IsDlgButtonChecked(hwndDlg, IDC_TOPPRIMSUFFIX) == BST_CHECKED)
1878                          This->pCurrentConfig->pDNS->UseDomainNameDevolution = TRUE;
1879                      else
1880                          This->pCurrentConfig->pDNS->UseDomainNameDevolution = FALSE;
1881                  }
1882                  else
1883                  {
1884                      CoTaskMemFree(This->pCurrentConfig->pDNS->szSearchList);
1885                      This->pCurrentConfig->pDNS->szSearchList = NULL;
1886                      This->pCurrentConfig->pDNS->UseDomainNameDevolution = FALSE;
1887                      This->pCurrentConfig->pDNS->szSearchList = GetListViewEntries(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1888                  }
1889 
1890                  if (IsDlgButtonChecked(hwndDlg, IDC_REGSUFFIX) == BST_CHECKED)
1891                  {
1892                      This->pCurrentConfig->pDNS->RegisterAdapterName = TRUE;
1893                      if (IsDlgButtonChecked(hwndDlg, IDC_USESUFFIX) == BST_CHECKED)
1894                          This->pCurrentConfig->pDNS->RegistrationEnabled = TRUE;
1895                      else
1896                          This->pCurrentConfig->pDNS->RegistrationEnabled = FALSE;
1897                  }
1898                  else
1899                  {
1900                      This->pCurrentConfig->pDNS->RegisterAdapterName = FALSE;
1901                      This->pCurrentConfig->pDNS->RegistrationEnabled = FALSE;
1902                  }
1903             }
1904             break;
1905         case WM_COMMAND:
1906             if (LOWORD(wParam) == IDC_DNSADDRLIST && HIWORD(wParam) == LBN_SELCHANGE)
1907             {
1908                 ToggleUpDown(hwndDlg, (HWND)lParam, IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1909                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1910                 break;
1911             }
1912             else if (LOWORD(wParam) == IDC_DNSSUFFIXLIST && HIWORD(wParam) == LBN_SELCHANGE)
1913             {
1914                 ToggleUpDown(hwndDlg, (HWND)lParam, IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1915                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1916                 break;
1917             }
1918             else if (LOWORD(wParam) == IDC_PRIMSUFFIX && HIWORD(wParam) == BN_CLICKED)
1919             {
1920                 if (SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
1921                 {
1922                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXUP), FALSE);
1923                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXDOWN), FALSE);
1924                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXADD), FALSE);
1925                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXMOD), FALSE);
1926                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXDEL), FALSE);
1927                     EnableWindow(GetDlgItem(hwndDlg, IDC_TOPPRIMSUFFIX), TRUE);
1928                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_RESETCONTENT, 0, 0);
1929                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1930                 }
1931             }
1932             else if (LOWORD(wParam) == IDC_SELSUFFIX && HIWORD(wParam) == BN_CLICKED)
1933             {
1934                 if (SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
1935                 {
1936                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXADD), TRUE);
1937                     EnableWindow(GetDlgItem(hwndDlg, IDC_TOPPRIMSUFFIX), FALSE);
1938                     ToggleUpDown(hwndDlg, (HWND)lParam, IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1939                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1940                 }
1941                 break;
1942             }
1943             else if (LOWORD(wParam) == IDC_REGSUFFIX && HIWORD(wParam) == BN_CLICKED)
1944             {
1945                 if (SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
1946                     EnableWindow(GetDlgItem(hwndDlg, IDC_USESUFFIX), TRUE);
1947                 else
1948                     EnableWindow(GetDlgItem(hwndDlg, IDC_USESUFFIX), FALSE);
1949                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1950             }
1951             else if (LOWORD(wParam) == IDC_DNSADDRUP && HIWORD(wParam) == BN_CLICKED)
1952             {
1953                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSADDRLIST), -1);
1954                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1955                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1956                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1957                 break;
1958             }
1959             else if (LOWORD(wParam) == IDC_DNSADDRDOWN && HIWORD(wParam) == BN_CLICKED)
1960             {
1961                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSADDRLIST), 1);
1962                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1963                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1964                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1965                 break;
1966             }
1967             else if (LOWORD(wParam) == IDC_DNSSUFFIXUP && HIWORD(wParam) == BN_CLICKED)
1968             {
1969                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), -1);
1970                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1971                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1972                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1973                 break;
1974             }
1975             else if (LOWORD(wParam) == IDC_DNSSUFFIXDOWN && HIWORD(wParam) == BN_CLICKED)
1976             {
1977                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), 1);
1978                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1979                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1980                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1981                 break;
1982             }
1983             else if (LOWORD(wParam) == IDC_DNSADDRDEL && HIWORD(wParam) == BN_CLICKED)
1984             {
1985                 RemoveItem(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1986                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1987                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1988                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1989                 break;
1990             }
1991             else if (LOWORD(wParam) == IDC_DNSSUFFIXDEL && HIWORD(wParam) == BN_CLICKED)
1992             {
1993                 RemoveItem(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1994                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1995                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1996                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1997                 break;
1998             }
1999             else if (LOWORD(wParam) == IDC_DNSADDRADD && HIWORD(wParam) == BN_CLICKED)
2000             {
2001                  Dns.bAdd = TRUE;
2002                  Dns.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSADDRLIST);
2003                  if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPDNS_DLG), NULL, TcpipAddDNSDlg, (LPARAM)&Dns))
2004                  {
2005                      ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
2006                      PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2007                  }
2008                  break;
2009             }
2010             else if (LOWORD(wParam) == IDC_DNSADDRMOD && HIWORD(wParam) == BN_CLICKED)
2011             {
2012                  lIndex = SendDlgItemMessage(hwndDlg, IDC_DNSADDRLIST, LB_GETCURSEL, 0, 0);
2013                  if (lIndex != LB_ERR)
2014                  {
2015                      Dns.bAdd = FALSE;
2016                      Dns.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSADDRLIST);
2017                      SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_GETTEXT, (WPARAM)lIndex, (LPARAM)Dns.szIP);
2018                      if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPDNS_DLG), NULL, TcpipAddDNSDlg, (LPARAM)&Dns))
2019                      {
2020                          SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_DELETESTRING, lIndex, 0);
2021                          SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_INSERTSTRING, lIndex, (LPARAM)Dns.szIP);
2022                          SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_SETCURSEL, lIndex, 0);
2023                          SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
2024                          PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2025                      }
2026                  }
2027                  break;
2028             }
2029             else if (LOWORD(wParam) == IDC_DNSSUFFIXADD && HIWORD(wParam) == BN_CLICKED)
2030             {
2031                 Suffix.bAdd = TRUE;
2032                 Suffix.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST);
2033                 Suffix.Suffix = NULL;
2034                 if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPSUFFIX_DLG), NULL, TcpipAddSuffixDlg, (LPARAM)&Suffix))
2035                 {
2036                     ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
2037                     lIndex = SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_ADDSTRING, 0, (LPARAM)Suffix.Suffix);
2038                     if (lIndex != LB_ERR)
2039                         SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_SETCURSEL, lIndex, 0);
2040                     SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
2041                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2042                     CoTaskMemFree(Suffix.Suffix);
2043                 }
2044                 break;
2045             }
2046             else if (LOWORD(wParam) == IDC_DNSSUFFIXMOD && HIWORD(wParam) == BN_CLICKED)
2047             {
2048                 lIndex = SendDlgItemMessage(hwndDlg, IDC_DNSSUFFIXLIST, LB_GETCURSEL, 0, 0);
2049                 if (lIndex != LB_ERR)
2050                 {
2051                     Suffix.bAdd = FALSE;
2052                     Suffix.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST);
2053                     lLength = SendMessageW(Suffix.hDlgCtrl, LB_GETTEXTLEN, lIndex, 0);
2054                     if (lLength != LB_ERR)
2055                     {
2056                         Suffix.Suffix = (LPWSTR)CoTaskMemAlloc((lLength + 1) * sizeof(WCHAR));
2057                         if (Suffix.Suffix)
2058                         {
2059                             SendMessageW(Suffix.hDlgCtrl, LB_GETTEXT, lIndex, (LPARAM)Suffix.Suffix);
2060                             Suffix.Suffix[lLength] = L'\0';
2061                             if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPSUFFIX_DLG), NULL, TcpipAddSuffixDlg, (LPARAM)&Suffix))
2062                             {
2063                                 if (Suffix.Suffix)
2064                                 {
2065                                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_DELETESTRING, lIndex, 0);
2066                                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_INSERTSTRING, lIndex, (LPARAM)Suffix.Suffix);
2067                                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_SETCURSEL, lIndex, 0);
2068                                     SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
2069                                     CoTaskMemFree(Suffix.Suffix);
2070                                 }
2071                                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
2072                                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2073                             }
2074                         }
2075                     }
2076                  }
2077                  break;
2078             }
2079     }
2080     return FALSE;
2081 }
2082 
2083 static int CALLBACK
2084 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
2085 {
2086     // NOTE: This callback is needed to set large icon correctly.
2087     HICON hIcon;
2088     switch (uMsg)
2089     {
2090         case PSCB_INITIALIZED:
2091         {
2092             hIcon = LoadIconW(netcfgx_hInstance, MAKEINTRESOURCEW(IDI_NETWORK));
2093             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
2094             break;
2095         }
2096     }
2097     return 0;
2098 }
2099 
2100 VOID
2101 LaunchAdvancedTcpipSettings(
2102     HWND hwndDlg,
2103     TcpipConfNotifyImpl * This)
2104 {
2105     PROPSHEETHEADERW pinfo;
2106     HPROPSHEETPAGE hppages[3];
2107     WCHAR szBuffer[100];
2108 
2109     hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ADVIP_DLG), TcpipAdvancedIpDlg, (LPARAM)This, NULL);
2110     hppages[1] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ADVDNS_DLG), TcpipAdvancedDnsDlg, (LPARAM)This, NULL);
2111     hppages[2] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ADVOPT_DLG), TcpipAdvancedOptDlg, (LPARAM)This, NULL);
2112 
2113 
2114     if (LoadStringW(netcfgx_hInstance, IDS_TCPIP, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
2115         szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
2116     else
2117         szBuffer[0] = L'\0';
2118 
2119     ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
2120     pinfo.dwSize = sizeof(PROPSHEETHEADERW);
2121     pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW |
2122                     PSH_USEICONID | PSH_USECALLBACK;
2123     pinfo.u3.phpage = hppages;
2124     pinfo.nPages = 3;
2125     pinfo.hwndParent = hwndDlg;
2126     pinfo.hInstance = netcfgx_hInstance;
2127     pinfo.pszCaption = szBuffer;
2128     pinfo.u.pszIcon = MAKEINTRESOURCEW(IDI_NETWORK);
2129     pinfo.pfnCallback = PropSheetProc;
2130 
2131     StoreTcpipBasicSettings(hwndDlg, This, FALSE);
2132     if (PropertySheetW(&pinfo) > 0)
2133     {
2134         InitializeTcpipBasicDlgCtrls(hwndDlg, This->pCurrentConfig);
2135         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2136     }
2137 }
2138 
2139 HRESULT
2140 InitializeTcpipAltDlgCtrls(
2141     HWND hwndDlg,
2142     TcpipSettings *pCurSettings)
2143 {
2144     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2145     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2146     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2147     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2148 
2149     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 0, MAKEIPRANGE(0, 255));
2150     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2151     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2152     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2153 
2154     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2155     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2156     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2157     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2158 
2159     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2160     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2161     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2162     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2163 
2164     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2165     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2166     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2167     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2168 
2169     if (pCurSettings->DhcpEnabled)
2170     {
2171         CheckRadioButton(hwndDlg, IDC_USEDHCP, IDC_NODHCP, IDC_USEDHCP);
2172         EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), FALSE);
2173         EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), FALSE);
2174         EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), FALSE);
2175         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), FALSE);
2176         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), FALSE);
2177     }
2178     else
2179     {
2180         CheckRadioButton(hwndDlg, IDC_USEDHCP, IDC_NODHCP, IDC_NODHCP);
2181         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2182         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2183 
2184         if (pCurSettings->Ip)
2185         {
2186             /* Set current ip address */
2187             SendDlgItemMessageA(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ip->IpAddress);
2188             /* Set current hostmask */
2189             SendDlgItemMessageA(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ip->u.Subnetmask);
2190         }
2191     }
2192 
2193     if (pCurSettings->Gw && pCurSettings->Gw->IpAddress)
2194     {
2195         /* Set current gateway */
2196         SendDlgItemMessageA(hwndDlg, IDC_DEFGATEWAY, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Gw->IpAddress);
2197     }
2198 
2199     if (pCurSettings->Ns)
2200     {
2201         SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->IpAddress);
2202         if (pCurSettings->Ns->Next)
2203             SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->Next->IpAddress);
2204         else
2205             SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2206     }
2207     else
2208     {
2209         SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_CLEARADDRESS, 0, 0);
2210         SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2211     }
2212 
2213     return S_OK;
2214 }
2215 
2216 INT_PTR
2217 CALLBACK
2218 TcpipAltConfDlg(
2219     HWND hwndDlg,
2220     UINT uMsg,
2221     WPARAM wParam,
2222     LPARAM lParam)
2223 {
2224     TcpipConfNotifyImpl *This;
2225     LPPROPSHEETPAGE page;
2226     BOOL bNoDHCP;
2227 
2228     switch (uMsg)
2229     {
2230         case WM_INITDIALOG:
2231         {
2232             page = (LPPROPSHEETPAGE)lParam;
2233             This = (TcpipConfNotifyImpl*)page->lParam;
2234             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
2235             if (This->pCurrentConfig)
2236                 InitializeTcpipAltDlgCtrls(hwndDlg, This->pCurrentConfig);
2237             return TRUE;
2238         }
2239         case WM_COMMAND:
2240         {
2241             switch (LOWORD(wParam))
2242             {
2243                 case IDC_USEDHCP:
2244                 case IDC_NODHCP:
2245                 {
2246                     if (HIWORD(wParam) == BN_CLICKED)
2247                     {
2248                         bNoDHCP = (IsDlgButtonChecked(hwndDlg, IDC_NODHCP) == BST_CHECKED);
2249                         if (bNoDHCP)
2250                         {
2251                             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_CLEARADDRESS, 0, 0);
2252                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_CLEARADDRESS, 0, 0);
2253                             SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_CLEARADDRESS, 0, 0);
2254                         }
2255 
2256                         EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), bNoDHCP);
2257                         EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), bNoDHCP);
2258                         EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), bNoDHCP);
2259                         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), bNoDHCP);
2260                         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), bNoDHCP);
2261 
2262                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2263                     }
2264                     break;
2265                 }
2266             }
2267             break;
2268         }
2269     }
2270     return FALSE;
2271 }
2272 
2273 VOID
2274 AddAlternativeDialog(
2275     HWND hDlg,
2276     TcpipConfNotifyImpl * This)
2277 {
2278     HPROPSHEETPAGE hpage;
2279 
2280     hpage = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ALTCF_DLG), TcpipAltConfDlg, (LPARAM)This, NULL);
2281     if (!hpage)
2282         return;
2283 
2284     SendMessageW(hDlg, PSM_INSERTPAGE, 1, (LPARAM)hpage);
2285 }
2286 
2287 INT_PTR
2288 StoreTcpipBasicSettings(
2289     HWND hwndDlg,
2290     TcpipConfNotifyImpl * This,
2291     BOOL bApply)
2292 {
2293     DWORD dwIpAddr;
2294 
2295     if (IsDlgButtonChecked(hwndDlg, IDC_NODHCP) == BST_CHECKED)
2296     {
2297         This->pCurrentConfig->DhcpEnabled = FALSE;
2298         if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) != 4)
2299         {
2300             if (bApply)
2301             {
2302                 DisplayError(IDS_NO_IPADDR_SET, IDS_TCPIP, MB_ICONWARNING);
2303                 SetFocus(GetDlgItem(hwndDlg, IDC_IPADDR));
2304                 return E_FAIL;
2305             }
2306         }
2307         if (!This->pCurrentConfig->Ip)
2308         {
2309             This->pCurrentConfig->Ip = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2310             if (!This->pCurrentConfig->Ip)
2311                 return E_OUTOFMEMORY;
2312             ZeroMemory(This->pCurrentConfig->Ip, sizeof(IP_ADDR));
2313         }
2314         This->pCurrentConfig->Ip->IpAddress = dwIpAddr;
2315 
2316         if (SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) != 4)
2317         {
2318             if (bApply)
2319                 DisplayError(IDS_NO_SUBMASK_SET, IDS_TCPIP, MB_ICONWARNING);
2320             if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2321             {
2322                 if (dwIpAddr <= MAKEIPADDRESS(127, 255, 255, 255))
2323                     dwIpAddr = MAKEIPADDRESS(255, 0, 0, 0);
2324                 else if (dwIpAddr <= MAKEIPADDRESS(191, 255, 255, 255))
2325                     dwIpAddr = MAKEIPADDRESS(255, 255, 0, 0);
2326                 else if (dwIpAddr <= MAKEIPADDRESS(223, 255, 255, 255))
2327                     dwIpAddr = MAKEIPADDRESS(255, 255, 255, 0);
2328 
2329                 SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)dwIpAddr);
2330             }
2331             if (bApply)
2332             {
2333                 SetFocus(GetDlgItem(hwndDlg, IDC_SUBNETMASK));
2334                 return E_FAIL;
2335             }
2336         }
2337         /* store subnetmask */
2338         This->pCurrentConfig->Ip->u.Subnetmask = dwIpAddr;
2339     }
2340     else
2341     {
2342         This->pCurrentConfig->DhcpEnabled = TRUE;
2343     }
2344 
2345     if (SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2346     {
2347         if (!This->pCurrentConfig->Gw)
2348         {
2349             This->pCurrentConfig->Gw = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2350             if (!This->pCurrentConfig->Gw)
2351                 return E_OUTOFMEMORY;
2352             ZeroMemory(This->pCurrentConfig->Gw, sizeof(IP_ADDR));
2353         }
2354         /* store default gateway */
2355         This->pCurrentConfig->Gw->IpAddress = dwIpAddr;
2356     }
2357     else
2358     {
2359         if (This->pCurrentConfig->Gw)
2360         {
2361             IP_ADDR * pNextGw = This->pCurrentConfig->Gw->Next;
2362             CoTaskMemFree(This->pCurrentConfig->Gw);
2363             This->pCurrentConfig->Gw = pNextGw;
2364         }
2365     }
2366 
2367     if (IsDlgButtonChecked(hwndDlg, IDC_FIXEDDNS) == BST_CHECKED)
2368     {
2369         BOOL bSkip = FALSE;
2370         This->pCurrentConfig->AutoconfigActive = FALSE;
2371         if (SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2372         {
2373             if (!This->pCurrentConfig->Ns)
2374             {
2375                 This->pCurrentConfig->Ns = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2376                 if (!This->pCurrentConfig->Ns)
2377                     return E_OUTOFMEMORY;
2378                 ZeroMemory(This->pCurrentConfig->Ns, sizeof(IP_ADDR));
2379             }
2380             This->pCurrentConfig->Ns->IpAddress = dwIpAddr;
2381         }
2382         else if (This->pCurrentConfig->Ns)
2383         {
2384             IP_ADDR *pTemp = This->pCurrentConfig->Ns->Next;
2385 
2386             CoTaskMemFree(This->pCurrentConfig->Ns);
2387             This->pCurrentConfig->Ns = pTemp;
2388             bSkip = TRUE;
2389         }
2390 
2391 
2392         if (SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2393         {
2394             if (!This->pCurrentConfig->Ns || bSkip)
2395             {
2396                 if (!This->pCurrentConfig->Ns)
2397                 {
2398                     This->pCurrentConfig->Ns = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2399                     if (!This->pCurrentConfig->Ns)
2400                         return E_OUTOFMEMORY;
2401                     ZeroMemory(This->pCurrentConfig->Ns, sizeof(IP_ADDR));
2402                 }
2403                 This->pCurrentConfig->Ns->IpAddress = dwIpAddr;
2404             }
2405             else if (!This->pCurrentConfig->Ns->Next)
2406             {
2407                 This->pCurrentConfig->Ns->Next = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2408                 if (!This->pCurrentConfig->Ns->Next)
2409                    return E_OUTOFMEMORY;
2410                 ZeroMemory(This->pCurrentConfig->Ns->Next, sizeof(IP_ADDR));
2411                 This->pCurrentConfig->Ns->Next->IpAddress = dwIpAddr;
2412             }
2413             else
2414             {
2415                 This->pCurrentConfig->Ns->Next->IpAddress = dwIpAddr;
2416             }
2417         }
2418         else
2419         {
2420             if (This->pCurrentConfig->Ns && This->pCurrentConfig->Ns->Next)
2421             {
2422                 if (This->pCurrentConfig->Ns->Next->Next)
2423                 {
2424                     IP_ADDR *pTemp = This->pCurrentConfig->Ns->Next->Next;
2425                     CoTaskMemFree(This->pCurrentConfig->Ns->Next);
2426                     This->pCurrentConfig->Ns->Next = pTemp;
2427                 }
2428                 else
2429                 {
2430                     CoTaskMemFree(This->pCurrentConfig->Ns->Next);
2431                     This->pCurrentConfig->Ns->Next = NULL;
2432                 }
2433             }
2434         }
2435     }
2436     else
2437     {
2438         This->pCurrentConfig->AutoconfigActive = TRUE;
2439     }
2440     return S_OK;
2441 }
2442 
2443 HRESULT
2444 InitializeTcpipBasicDlgCtrls(
2445     HWND hwndDlg,
2446     TcpipSettings * pCurSettings)
2447 {
2448     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2449     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2450     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2451     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2452 
2453     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 0, MAKEIPRANGE(0, 255));
2454     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2455     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2456     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2457 
2458     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2459     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2460     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2461     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2462 
2463     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2464     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2465     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2466     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2467 
2468     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2469     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2470     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2471     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2472 
2473     if (pCurSettings->DhcpEnabled)
2474     {
2475         CheckDlgButton(hwndDlg, IDC_USEDHCP, BST_CHECKED);
2476         EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), FALSE);
2477         EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), FALSE);
2478         EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), FALSE);
2479         EnableWindow(GetDlgItem(hwndDlg, IDC_AUTODNS), TRUE);
2480     }
2481     else
2482     {
2483         CheckDlgButton(hwndDlg, IDC_NODHCP, BST_CHECKED);
2484 
2485         if (pCurSettings->Ip)
2486         {
2487             /* set current ip address */
2488             SendDlgItemMessageA(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ip->IpAddress);
2489             /* set current hostmask */
2490             SendDlgItemMessageA(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ip->u.Subnetmask);
2491         }
2492     }
2493 
2494     if (pCurSettings->Gw && pCurSettings->Gw->IpAddress)
2495     {
2496         /* set current gateway */
2497         SendDlgItemMessageA(hwndDlg, IDC_DEFGATEWAY, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Gw->IpAddress);
2498     }
2499 
2500     if (pCurSettings->AutoconfigActive)
2501     {
2502         CheckDlgButton(hwndDlg, IDC_AUTODNS, BST_CHECKED);
2503         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), FALSE);
2504         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), FALSE);
2505     }
2506     else
2507     {
2508         CheckDlgButton(hwndDlg, IDC_FIXEDDNS, BST_CHECKED);
2509         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2510         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2511         if (pCurSettings->Ns)
2512         {
2513             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->IpAddress);
2514             if (pCurSettings->Ns->Next)
2515             {
2516                 SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->Next->IpAddress);
2517             }
2518             else
2519             {
2520                 SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2521             }
2522         }
2523         else
2524         {
2525             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_CLEARADDRESS, 0, 0);
2526             SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2527         }
2528     }
2529 
2530     return S_OK;
2531 }
2532 
2533 HRESULT
2534 CopyIpAddrString(
2535     IP_ADDR_STRING * pSrc,
2536     IP_ADDR ** pTarget,
2537     COPY_TYPE Type,
2538     LPWSTR szMetric)
2539 {
2540     IP_ADDR_STRING * pCurrent;
2541     IP_ADDR *pNew, *pLast;
2542 
2543     pCurrent = pSrc;
2544     pLast = NULL;
2545 
2546     while(pCurrent)
2547     {
2548         pNew = CoTaskMemAlloc(sizeof(IP_ADDR));
2549         if (!pNew)
2550         {
2551            break;
2552         }
2553         ZeroMemory(pNew, sizeof(IP_ADDR));
2554         pNew->IpAddress = GetIpAddressFromStringA(pCurrent->IpAddress.String);
2555         if (!pNew->IpAddress)
2556         {
2557             CoTaskMemFree(pNew);
2558             return E_FAIL;
2559         }
2560 
2561        if (Type == SUBMASK)
2562        {
2563            pNew->u.Subnetmask = GetIpAddressFromStringA(pCurrent->IpMask.String);
2564            pNew->NTEContext = pCurrent->Context;
2565        }
2566        else if (Type == METRIC)
2567        {
2568            if (szMetric && szMetric[0] != L'\0')
2569            {
2570                pNew->u.Metric = _wtoi(szMetric);
2571                szMetric += wcslen(szMetric) + 1;
2572            }
2573        }
2574 
2575         if (!pLast)
2576             *pTarget = pNew;
2577         else
2578             pLast->Next = pNew;
2579 
2580         pLast = pNew;
2581         pCurrent = pCurrent->Next;
2582 
2583     }
2584     pLast->Next = NULL;
2585     return S_OK;
2586 }
2587 
2588 
2589 
2590 INT_PTR
2591 CALLBACK
2592 TcpipBasicDlg(
2593     HWND hwndDlg,
2594     UINT uMsg,
2595     WPARAM wParam,
2596     LPARAM lParam
2597 )
2598 {
2599     TcpipConfNotifyImpl * This;
2600     LPPROPSHEETPAGE page;
2601     LPNMIPADDRESS lpnmipa;
2602     LPPSHNOTIFY lppsn;
2603     DWORD dwIpAddr;
2604 
2605 
2606     switch(uMsg)
2607     {
2608         case WM_INITDIALOG:
2609             page = (LPPROPSHEETPAGE)lParam;
2610             This = (TcpipConfNotifyImpl*)page->lParam;
2611             if (This->pCurrentConfig)
2612                 InitializeTcpipBasicDlgCtrls(hwndDlg, This->pCurrentConfig);
2613             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
2614             return TRUE;
2615         case WM_NOTIFY:
2616             lppsn = (LPPSHNOTIFY) lParam;
2617             lpnmipa = (LPNMIPADDRESS) lParam;
2618             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
2619             {
2620                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2621                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
2622                 {
2623                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2624                     {
2625                         if (dwIpAddr <= MAKEIPADDRESS(127, 255, 255, 255))
2626                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 0, 0, 0));
2627                         else if (dwIpAddr <= MAKEIPADDRESS(191, 255, 255, 255))
2628                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 0, 0));
2629                         else if (dwIpAddr <= MAKEIPADDRESS(223, 255, 255, 255))
2630                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 255, 0));
2631                      }
2632                 }
2633             }
2634             else if (lppsn->hdr.code == PSN_APPLY)
2635             {
2636                 This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
2637                 if (SUCCEEDED(StoreTcpipBasicSettings(hwndDlg, This, TRUE)))
2638                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
2639                 else
2640                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID);
2641 
2642                 return TRUE;
2643             }
2644             break;
2645         case WM_COMMAND:
2646             if (HIWORD(wParam) == BN_CLICKED)
2647             {
2648                 switch (LOWORD(wParam))
2649                 {
2650                     case IDC_USEDHCP:
2651                         if (IsDlgButtonChecked(hwndDlg, IDC_USEDHCP) == BST_CHECKED)
2652                         {
2653                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2654                             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_CLEARADDRESS, 0, 0);
2655                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_CLEARADDRESS, 0, 0);
2656                             SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_CLEARADDRESS, 0, 0);
2657                             EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), FALSE);
2658                             EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), FALSE);
2659                             EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), FALSE);
2660                             EnableWindow(GetDlgItem(hwndDlg, IDC_AUTODNS), TRUE);
2661                             AddAlternativeDialog(GetParent(hwndDlg), (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER));
2662                         }
2663                         break;
2664                     case IDC_NODHCP:
2665                         if (IsDlgButtonChecked(hwndDlg, IDC_NODHCP) == BST_CHECKED)
2666                         {
2667                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2668                             EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), TRUE);
2669                             EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), TRUE);
2670                             EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), TRUE);
2671                             if (IsDlgButtonChecked(hwndDlg, IDC_AUTODNS) == BST_CHECKED)
2672                             {
2673                                 CheckDlgButton(hwndDlg, IDC_AUTODNS, BST_UNCHECKED);
2674                             }
2675                             EnableWindow(GetDlgItem(hwndDlg, IDC_AUTODNS), FALSE);
2676                             CheckDlgButton(hwndDlg, IDC_FIXEDDNS, BST_CHECKED);
2677                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2678                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2679                             SendMessageW(GetParent(hwndDlg), PSM_REMOVEPAGE, 1, 0);
2680                         }
2681                         break;
2682                     case IDC_AUTODNS:
2683                         if (IsDlgButtonChecked(hwndDlg, IDC_AUTODNS) == BST_CHECKED)
2684                         {
2685                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2686                             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_CLEARADDRESS, 0, 0);
2687                             SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2688                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), FALSE);
2689                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), FALSE);
2690                         }
2691                         break;
2692                     case IDC_FIXEDDNS:
2693                         if (IsDlgButtonChecked(hwndDlg, IDC_FIXEDDNS) == BST_CHECKED)
2694                         {
2695                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2696                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2697                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2698                         }
2699                         break;
2700                     case IDC_ADVANCED:
2701                         LaunchAdvancedTcpipSettings(hwndDlg, (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER));
2702                         break;
2703                 }
2704                 break;
2705             }
2706         default:
2707             break;
2708 
2709     }
2710     return FALSE;
2711 }
2712 
2713 /***************************************************************
2714  * INetCfgComponentPropertyUi interface
2715  */
2716 
2717 HRESULT
2718 WINAPI
2719 INetCfgComponentPropertyUi_fnQueryInterface(
2720     INetCfgComponentPropertyUi * iface,
2721     REFIID iid,
2722     LPVOID * ppvObj)
2723 {
2724     //LPOLESTR pStr;
2725     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2726 
2727     *ppvObj = NULL;
2728 
2729 
2730     if (IsEqualIID (iid, &IID_IUnknown) ||
2731         IsEqualIID (iid, &IID_INetCfgComponentPropertyUi))
2732     {
2733         *ppvObj = This;
2734         INetCfgComponentPropertyUi_AddRef(iface);
2735         return S_OK;
2736     }
2737     else if (IsEqualIID(iid, &IID_INetCfgComponentControl))
2738     {
2739         *ppvObj = (LPVOID*)&This->lpVtblCompControl;
2740         INetCfgComponentPropertyUi_AddRef(iface);
2741         return S_OK;
2742     }
2743 
2744     //StringFromCLSID(iid, &pStr);
2745     //MessageBoxW(NULL, pStr, L"INetConnectionPropertyUi_fnQueryInterface", MB_OK);
2746     //CoTaskMemFree(pStr);
2747 
2748     return E_NOINTERFACE;
2749 }
2750 
2751 
2752 ULONG
2753 WINAPI
2754 INetCfgComponentPropertyUi_fnAddRef(
2755     INetCfgComponentPropertyUi * iface)
2756 {
2757     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2758     ULONG refCount = InterlockedIncrement(&This->ref);
2759 
2760     return refCount;
2761 }
2762 
2763 ULONG
2764 WINAPI
2765 INetCfgComponentPropertyUi_fnRelease(
2766     INetCfgComponentPropertyUi * iface)
2767 {
2768     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2769     ULONG refCount = InterlockedDecrement(&This->ref);
2770 
2771     if (!refCount)
2772     {
2773        CoTaskMemFree(This);
2774     }
2775     return refCount;
2776 }
2777 
2778 HRESULT
2779 WINAPI
2780 INetCfgComponentPropertyUi_fnQueryPropertyUi(
2781     INetCfgComponentPropertyUi * iface,
2782     IUnknown *pUnkReserved)
2783 {
2784     INetLanConnectionUiInfo * pLanInfo;
2785     HRESULT hr;
2786     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2787 
2788     hr = IUnknown_QueryInterface(pUnkReserved, &IID_INetLanConnectionUiInfo, (LPVOID*)&pLanInfo);
2789     if (FAILED(hr))
2790         return hr;
2791 
2792     INetLanConnectionUiInfo_GetDeviceGuid(pLanInfo, &This->NetCfgInstanceId);
2793 
2794     //FIXME
2795     // check if tcpip is enabled on that binding */
2796     IUnknown_Release(pUnkReserved);
2797     return S_OK;
2798 }
2799 
2800 HRESULT
2801 WINAPI
2802 INetCfgComponentPropertyUi_fnSetContext(
2803     INetCfgComponentPropertyUi * iface,
2804     IUnknown *pUnkReserved)
2805 {
2806     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2807 
2808     if (!iface || !pUnkReserved)
2809         return E_POINTER;
2810 
2811     This->pUnknown = pUnkReserved;
2812     return S_OK;
2813 }
2814 
2815 HRESULT
2816 LoadDNSSettings(
2817     TcpipConfNotifyImpl * This)
2818 {
2819     LPOLESTR pStr;
2820     WCHAR szBuffer[200];
2821     HKEY hKey;
2822     DWORD dwSize;
2823 
2824 
2825     This->pCurrentConfig->pDNS = (TcpipAdvancedDNSDlgSettings*) CoTaskMemAlloc(sizeof(TcpipAdvancedDNSDlgSettings));
2826     if (!This->pCurrentConfig->pDNS)
2827         return E_FAIL;
2828 
2829     ZeroMemory(This->pCurrentConfig->pDNS, sizeof(TcpipAdvancedDNSDlgSettings));
2830 
2831     if (FAILED(StringFromCLSID(&This->NetCfgInstanceId, &pStr)))
2832         return E_FAIL;
2833 
2834     swprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", pStr);
2835     CoTaskMemFree(pStr);
2836     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
2837     {
2838         dwSize = sizeof(DWORD);
2839         RegQueryValueExW(hKey, L"RegisterAdapterName", NULL, NULL, (LPBYTE)&This->pCurrentConfig->pDNS->RegisterAdapterName, &dwSize);
2840 
2841         dwSize = sizeof(DWORD);
2842         RegQueryValueExW(hKey, L"RegistrationEnabled", NULL, NULL, (LPBYTE)&This->pCurrentConfig->pDNS->RegistrationEnabled, &dwSize);
2843 
2844         dwSize = sizeof(This->pCurrentConfig->pDNS->szDomain);
2845         RegQueryValueExW(hKey, L"Domain", NULL, NULL, (LPBYTE)This->pCurrentConfig->pDNS->szDomain, &dwSize);
2846 
2847         RegCloseKey(hKey);
2848     }
2849 
2850     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
2851     {
2852         dwSize = sizeof(DWORD);
2853         RegQueryValueExW(hKey, L"UseDomainNameDevolution", NULL, NULL, (LPBYTE)&This->pCurrentConfig->pDNS->UseDomainNameDevolution, &dwSize);
2854 
2855         dwSize = 0;
2856         if (RegQueryValueExW(hKey, L"SearchList", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
2857         {
2858             This->pCurrentConfig->pDNS->szSearchList = (LPWSTR)CoTaskMemAlloc(dwSize);
2859             if (This->pCurrentConfig->pDNS->szSearchList)
2860             {
2861                 if (RegQueryValueExW(hKey, L"SearchList", NULL, NULL, (LPBYTE)This->pCurrentConfig->pDNS->szSearchList, &dwSize) != ERROR_SUCCESS)
2862                 {
2863                     CoTaskMemFree(This->pCurrentConfig->pDNS->szSearchList);
2864                     This->pCurrentConfig->pDNS->szSearchList = NULL;
2865                 }
2866             }
2867         }
2868         RegCloseKey(hKey);
2869     }
2870     return S_OK;
2871 }
2872 
2873 LPWSTR
2874 LoadTcpFilterSettingsFromRegistry(HKEY hKey, LPCWSTR szName, LPDWORD Size)
2875 {
2876     DWORD dwSize;
2877     LPWSTR pData;
2878 
2879     if (RegQueryValueExW(hKey, szName, NULL, NULL, NULL, &dwSize) != ERROR_SUCCESS)
2880         return NULL;
2881 
2882     pData = (LPWSTR)CoTaskMemAlloc(dwSize);
2883     if (!pData)
2884         return NULL;
2885 
2886     if (RegQueryValueExW(hKey, szName, NULL, NULL, (LPBYTE)pData, &dwSize) != ERROR_SUCCESS)
2887     {
2888         CoTaskMemFree(pData);
2889         return NULL;
2890     }
2891     *Size = dwSize;
2892     return pData;
2893 }
2894 
2895 HRESULT
2896 LoadFilterSettings(
2897     TcpipConfNotifyImpl * This)
2898 {
2899     HKEY hKey;
2900     TcpFilterSettings *pFilter;
2901     WCHAR szBuffer[200];
2902     LPOLESTR pStr;
2903     DWORD dwVal, dwSize;
2904 
2905     pFilter = (TcpFilterSettings*)CoTaskMemAlloc(sizeof(TcpFilterSettings));
2906     if (!pFilter)
2907         return E_FAIL;
2908 
2909     ZeroMemory(pFilter, sizeof(TcpFilterSettings));
2910     This->pCurrentConfig->pFilter = pFilter;
2911 
2912 
2913     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
2914     {
2915         dwSize = sizeof(DWORD);
2916         if (RegQueryValueExW(hKey, L"EnableSecurityFilters", NULL, NULL, (LPBYTE)&dwVal, &dwSize) == ERROR_SUCCESS)
2917             pFilter->EnableSecurityFilters = dwVal;
2918         RegCloseKey(hKey);
2919     }
2920     else
2921     {
2922         pFilter->EnableSecurityFilters = FALSE;
2923     }
2924 
2925     if (FAILED(StringFromCLSID(&This->NetCfgInstanceId, &pStr)))
2926         return E_FAIL;
2927 
2928     swprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", pStr);
2929     CoTaskMemFree(pStr);
2930     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
2931     {
2932         return S_OK;
2933     }
2934     pFilter->szTCPAllowedPorts = LoadTcpFilterSettingsFromRegistry(hKey, L"TCPAllowedPorts", &pFilter->TCPSize);
2935     pFilter->szUDPAllowedPorts = LoadTcpFilterSettingsFromRegistry(hKey, L"UDPAllowedPorts", &pFilter->UDPSize);
2936     pFilter->szRawIPAllowedProtocols = LoadTcpFilterSettingsFromRegistry(hKey, L"RawIPAllowedProtocols", &pFilter->IPSize);
2937     RegCloseKey(hKey);
2938     return S_OK;
2939 }
2940 
2941 
2942 HRESULT
2943 Initialize(TcpipConfNotifyImpl * This)
2944 {
2945     DWORD dwSize, Status;
2946     WCHAR szBuffer[50];
2947     IP_ADAPTER_INFO * pCurrentAdapter;
2948     IP_ADAPTER_INFO * pInfo;
2949     PIP_PER_ADAPTER_INFO pPerInfo;
2950     IP_PER_ADAPTER_INFO Info;
2951     LPOLESTR pStr;
2952     HRESULT hr;
2953     BOOL bFound;
2954     TcpipSettings * pCurSettings;
2955     ULONG uLength;
2956 
2957     if (This->pCurrentConfig)
2958         return S_OK;
2959 
2960     hr = StringFromCLSID(&This->NetCfgInstanceId, &pStr);
2961     if (FAILED(hr))
2962         return hr;
2963 
2964 
2965     dwSize = 0;
2966     if (GetAdaptersInfo(NULL, &dwSize) != ERROR_BUFFER_OVERFLOW)
2967     {
2968         CoTaskMemFree(pStr);
2969         return E_FAIL;
2970     }
2971 
2972     pInfo = CoTaskMemAlloc(dwSize);
2973     if (!pInfo)
2974     {
2975         CoTaskMemFree(pStr);
2976         return E_FAIL;
2977     }
2978 
2979     if (GetAdaptersInfo(pInfo, &dwSize) != ERROR_SUCCESS)
2980     {
2981         CoTaskMemFree(pStr);
2982         CoTaskMemFree(pInfo);
2983         return E_FAIL;
2984     }
2985 
2986     pCurrentAdapter = pInfo;
2987     bFound = FALSE;
2988     while(pCurrentAdapter)
2989     {
2990         szBuffer[0] = L'\0';
2991         if (MultiByteToWideChar(CP_ACP, 0, pCurrentAdapter->AdapterName, -1, szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0])))
2992         {
2993             szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
2994         }
2995         if (!_wcsicmp(szBuffer, pStr))
2996         {
2997             bFound = TRUE;
2998             break;
2999         }
3000         pCurrentAdapter = pCurrentAdapter->Next;
3001     }
3002     CoTaskMemFree(pStr);
3003 
3004     if (!bFound)
3005     {
3006         CoTaskMemFree(pInfo);
3007         return E_FAIL;
3008     }
3009 
3010     pCurSettings = CoTaskMemAlloc(sizeof(TcpipSettings));
3011     if (!pCurSettings)
3012     {
3013         CoTaskMemFree(pInfo);
3014         return E_FAIL;
3015     }
3016 
3017     ZeroMemory(pCurSettings, sizeof(TcpipSettings));
3018     This->pCurrentConfig = pCurSettings;
3019     pCurSettings->DhcpEnabled = pCurrentAdapter->DhcpEnabled;
3020     pCurSettings->Index = pCurrentAdapter->Index;
3021 
3022     if (!pCurrentAdapter->DhcpEnabled)
3023     {
3024         CopyIpAddrString(&pCurrentAdapter->IpAddressList, &pCurSettings->Ip, SUBMASK, NULL);
3025     }
3026 
3027     CopyIpAddrString(&pCurrentAdapter->GatewayList, &pCurSettings->Gw, METRIC, NULL);
3028 
3029     uLength = sizeof(IP_PER_ADAPTER_INFO);
3030     ZeroMemory(&Info, sizeof(IP_PER_ADAPTER_INFO));
3031 
3032     if (GetPerAdapterInfo(pCurrentAdapter->Index, &Info, &uLength) == ERROR_BUFFER_OVERFLOW)
3033     {
3034         pPerInfo = (PIP_PER_ADAPTER_INFO)CoTaskMemAlloc(uLength);
3035         if (pPerInfo)
3036         {
3037             Status = GetPerAdapterInfo(pCurrentAdapter->Index, pPerInfo, &uLength);
3038             if (Status == NOERROR)
3039             {
3040                 if (!pPerInfo->AutoconfigActive)
3041                 {
3042                     CopyIpAddrString(&pPerInfo->DnsServerList, &pCurSettings->Ns, IPADDR, NULL);
3043                 }
3044                 pCurSettings->AutoconfigActive = pPerInfo->AutoconfigActive;
3045             }
3046             CoTaskMemFree(pPerInfo);
3047         }
3048     }
3049     else
3050     {
3051         if (!Info.AutoconfigActive)
3052         {
3053             CopyIpAddrString(&Info.DnsServerList, &pCurSettings->Ns, IPADDR, NULL);
3054         }
3055         pCurSettings->AutoconfigActive = Info.AutoconfigActive;
3056     }
3057 
3058     if (FAILED(LoadFilterSettings(This)))
3059         return E_FAIL;
3060 
3061     if (FAILED(LoadDNSSettings(This)))
3062         return E_FAIL;
3063 
3064     CoTaskMemFree(pInfo);
3065 
3066     return S_OK;
3067 }
3068 
3069 HRESULT
3070 WINAPI
3071 INetCfgComponentPropertyUi_fnMergePropPages(
3072     INetCfgComponentPropertyUi * iface,
3073     DWORD *pdwDefPages,
3074     BYTE **pahpspPrivate,
3075     UINT *pcPages,
3076     HWND hwndParent,
3077     LPCWSTR *pszStartPage)
3078 {
3079     HPROPSHEETPAGE * hppages;
3080     UINT NumPages;
3081     HRESULT hr;
3082     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
3083 
3084     hr = Initialize(This);
3085     if (FAILED(hr))
3086         return hr;
3087 
3088     if (This->pCurrentConfig->DhcpEnabled)
3089         NumPages = 2;
3090     else
3091         NumPages = 1;
3092 
3093     hppages = (HPROPSHEETPAGE*) CoTaskMemAlloc(sizeof(HPROPSHEETPAGE) * NumPages);
3094     if (!hppages)
3095         return E_FAIL;
3096 
3097     hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_BASIC_DLG), TcpipBasicDlg, (LPARAM)This, NULL);
3098     if (!hppages[0])
3099     {
3100         CoTaskMemFree(hppages);
3101         return E_FAIL;
3102     }
3103     if (NumPages == 2)
3104     {
3105         hppages[1] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ALTCF_DLG), TcpipAltConfDlg, (LPARAM)This, NULL);
3106         if (!hppages[1])
3107         {
3108             DestroyPropertySheetPage(hppages[0]);
3109             CoTaskMemFree(hppages);
3110             return E_FAIL;
3111         }
3112     }
3113 
3114     *pahpspPrivate = (BYTE*)hppages;
3115     *pcPages = NumPages;
3116 
3117     return S_OK;
3118 }
3119 
3120 HRESULT
3121 WINAPI
3122 INetCfgComponentPropertyUi_fnValidateProperties(
3123     INetCfgComponentPropertyUi * iface,
3124     HWND hwndDlg)
3125 {
3126 MessageBoxW(NULL, L"INetCfgComponentPropertyUi_fnValidateProperties", NULL, MB_OK);
3127     return S_OK;
3128 }
3129 
3130 HRESULT
3131 WINAPI
3132 INetCfgComponentPropertyUi_fnApplyProperties(
3133     INetCfgComponentPropertyUi * iface)
3134 {
3135 MessageBoxW(NULL, L"INetCfgComponentPropertyUi_fnApplyProperties", NULL, MB_OK);
3136     return S_OK;
3137 }
3138 
3139 
3140 HRESULT
3141 WINAPI
3142 INetCfgComponentPropertyUi_fnCancelProperties(
3143     INetCfgComponentPropertyUi * iface)
3144 {
3145 //MessageBoxW(NULL, L"INetCfgComponentPropertyUi_fnCancelProperties", NULL, MB_OK);
3146     return S_OK;
3147 }
3148 
3149 static const INetCfgComponentPropertyUiVtbl vt_NetCfgComponentPropertyUi =
3150 {
3151     INetCfgComponentPropertyUi_fnQueryInterface,
3152     INetCfgComponentPropertyUi_fnAddRef,
3153     INetCfgComponentPropertyUi_fnRelease,
3154     INetCfgComponentPropertyUi_fnQueryPropertyUi,
3155     INetCfgComponentPropertyUi_fnSetContext,
3156     INetCfgComponentPropertyUi_fnMergePropPages,
3157     INetCfgComponentPropertyUi_fnValidateProperties,
3158     INetCfgComponentPropertyUi_fnApplyProperties,
3159     INetCfgComponentPropertyUi_fnCancelProperties
3160 };
3161 
3162 /***************************************************************
3163  * INetCfgComponentControl interface
3164  */
3165 
3166 HRESULT
3167 WINAPI
3168 INetCfgComponentControl_fnQueryInterface(
3169     INetCfgComponentControl * iface,
3170     REFIID iid,
3171     LPVOID * ppvObj)
3172 {
3173     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3174     return INetCfgComponentPropertyUi_QueryInterface((INetCfgComponentPropertyUi*)This, iid, ppvObj);
3175 }
3176 
3177 ULONG
3178 WINAPI
3179 INetCfgComponentControl_fnAddRef(
3180     INetCfgComponentControl * iface)
3181 {
3182     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3183     return INetCfgComponentPropertyUi_AddRef((INetCfgComponentPropertyUi*)This);
3184 }
3185 
3186 ULONG
3187 WINAPI
3188 INetCfgComponentControl_fnRelease(
3189     INetCfgComponentControl * iface)
3190 {
3191     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3192     return INetCfgComponentPropertyUi_Release((INetCfgComponentPropertyUi*)This);
3193 }
3194 
3195 HRESULT
3196 WINAPI
3197 INetCfgComponentControl_fnInitialize(
3198     INetCfgComponentControl * iface,
3199     INetCfgComponent *pIComp,
3200     INetCfg *pINetCfg,
3201     BOOL fInstalling)
3202 {
3203     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3204 
3205     This->pNCfg = pINetCfg;
3206     This->pNComp = pIComp;
3207 
3208     return S_OK;
3209 }
3210 
3211 static
3212 LPWSTR
3213 CreateMultiSzString(IP_ADDR * pAddr, COPY_TYPE Type, LPDWORD Size, BOOL bComma)
3214 {
3215     LPWSTR pStr, pRet;
3216     DWORD dwSize, dwIpAddr;
3217     WCHAR szBuffer[30];
3218     IP_ADDR *pTemp = pAddr;
3219 
3220 
3221     dwSize = 0;
3222     while(pTemp)
3223     {
3224         if (Type == IPADDR)
3225         {
3226             dwIpAddr = pTemp->IpAddress;
3227             swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
3228                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3229         }else if (Type == SUBMASK)
3230         {
3231             dwIpAddr = pTemp->u.Subnetmask;
3232             swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
3233                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3234         }
3235         else if (Type == METRIC)
3236         {
3237             swprintf(szBuffer, L"%u", pTemp->u.Metric);
3238         }
3239 
3240         dwSize += wcslen(szBuffer) + 1;
3241         pTemp = pTemp->Next;
3242     }
3243 
3244     if (!dwSize)
3245         return NULL;
3246 
3247     pStr = pRet = CoTaskMemAlloc((dwSize+1) * sizeof(WCHAR));
3248     if(!pStr)
3249        return NULL;
3250 
3251     pTemp = pAddr;
3252     while(pTemp)
3253     {
3254         if (Type == IPADDR)
3255         {
3256             dwIpAddr = pTemp->IpAddress;
3257             swprintf(pStr, L"%lu.%lu.%lu.%lu",
3258                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3259         }else if (Type == SUBMASK)
3260         {
3261             dwIpAddr = pTemp->u.Subnetmask;
3262             swprintf(pStr, L"%lu.%lu.%lu.%lu",
3263                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3264         }
3265         else if (Type == METRIC)
3266         {
3267             swprintf(pStr, L"%u", pTemp->u.Metric);
3268         }
3269 
3270         if (bComma)
3271         {
3272             pStr += wcslen(pStr);
3273             if (pTemp->Next)
3274             {
3275                 pStr[0] = L',';
3276                 pStr++;
3277             }
3278         }
3279         else
3280         {
3281             pStr += wcslen(pStr) + 1;
3282         }
3283         pTemp = pTemp->Next;
3284     }
3285     pStr[0] = L'\0';
3286     *Size = (dwSize+1) * sizeof(WCHAR);
3287     return pRet;
3288 }
3289 
3290 
3291 HRESULT
3292 WINAPI
3293 INetCfgComponentControl_fnApplyRegistryChanges(
3294     INetCfgComponentControl * iface)
3295 {
3296     HKEY hKey;
3297     LPOLESTR pStr;
3298     DWORD dwSize;
3299     WCHAR szBuffer[200];
3300     TcpipSettings * pCurrentConfig, *pOldConfig;
3301     ULONG NTEInstance;
3302     DWORD DhcpApiVersion;
3303 
3304     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3305 
3306     pCurrentConfig = This->pCurrentConfig;
3307     This->pCurrentConfig = NULL;
3308 
3309     if (FAILED(Initialize(This)))
3310     {
3311         This->pCurrentConfig = pCurrentConfig;
3312         return E_FAIL;
3313     }
3314     pOldConfig = This->pCurrentConfig;
3315     This->pCurrentConfig = pCurrentConfig;
3316 
3317     //MessageBoxW(NULL, L"INetCfgComponentControl_fnApplyRegistryChanges", NULL, MB_OK);
3318 
3319 
3320     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
3321     {
3322         if (pCurrentConfig->pDNS)
3323         {
3324             RegSetValueExW(hKey, L"UseDomainNameDevolution", 0, REG_DWORD, (LPBYTE)&pCurrentConfig->pDNS->UseDomainNameDevolution, sizeof(DWORD));
3325             RegSetValueExW(hKey, L"SearchList", 0, REG_SZ, (LPBYTE)pCurrentConfig->pDNS->szSearchList,
3326                        (wcslen(pCurrentConfig->pDNS->szSearchList)+1) * sizeof(WCHAR));
3327         }
3328         if (pCurrentConfig->pFilter)
3329         {
3330             RegSetValueExW(hKey, L"EnableSecurityFilters", 0, REG_DWORD,
3331                       (LPBYTE)&pCurrentConfig->pFilter->EnableSecurityFilters, sizeof(DWORD));
3332         }
3333         RegCloseKey(hKey);
3334     }
3335 
3336     if (FAILED(StringFromCLSID(&This->NetCfgInstanceId, &pStr)))
3337         return E_FAIL;
3338 
3339     swprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", pStr);
3340     CoTaskMemFree(pStr);
3341 
3342     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
3343     {
3344         if (pCurrentConfig->pDNS)
3345         {
3346             RegSetValueExW(hKey, L"RegisterAdapterName", 0, REG_DWORD, (LPBYTE)&This->pCurrentConfig->pDNS->RegisterAdapterName, sizeof(DWORD));
3347             RegSetValueExW(hKey, L"RegistrationEnabled", 0, REG_DWORD, (LPBYTE)&This->pCurrentConfig->pDNS->RegistrationEnabled, sizeof(DWORD));
3348             RegSetValueExW(hKey, L"Domain", 0, REG_SZ, (LPBYTE)This->pCurrentConfig->pDNS->szDomain,
3349                        (wcslen(This->pCurrentConfig->pDNS->szDomain)+1) * sizeof(WCHAR));
3350         }
3351 #if 0
3352         if (pCurrentConfig->pFilter)
3353         {
3354             if (pCurrentConfig->pFilter->szTCPAllowedPorts)
3355             {
3356                 RegSetValueExW(hKey, L"TCPAllowedPorts", 0, REG_MULTI_SZ,
3357                        (LPBYTE)pCurrentConfig->pFilter->szTCPAllowedPorts,
3358                         pCurrentConfig->pFilter->TCPSize);
3359             }
3360             if (pCurrentConfig->pFilter->szUDPAllowedPorts)
3361             {
3362                 RegSetValueExW(hKey, L"UDPAllowedPorts", 0, REG_MULTI_SZ,
3363                        (LPBYTE)pCurrentConfig->pFilter->szUDPAllowedPorts,
3364                         pCurrentConfig->pFilter->UDPSize);
3365             }
3366             if (pCurrentConfig->pFilter->szRawIPAllowedProtocols)
3367             {
3368                 RegSetValueExW(hKey, L"RawIPAllowedProtocols", 0, REG_MULTI_SZ,
3369                        (LPBYTE)pCurrentConfig->pFilter->szRawIPAllowedProtocols,
3370                         pCurrentConfig->pFilter->IPSize);
3371             }
3372         }
3373 #endif
3374         RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (LPBYTE)&pCurrentConfig->DhcpEnabled, sizeof(DWORD));
3375         if (pCurrentConfig->DhcpEnabled)
3376         {
3377             RegSetValueExW(hKey, L"IPAddress", 0, REG_MULTI_SZ, (LPBYTE)L"0.0.0.0\0", 9 * sizeof(WCHAR));
3378             RegSetValueExW(hKey, L"SubnetMask", 0, REG_MULTI_SZ, (LPBYTE)L"0.0.0.0\0", 9 * sizeof(WCHAR));
3379             if (!pOldConfig->DhcpEnabled)
3380             {
3381                 /* Delete this adapter's current IP address */
3382                 DeleteIPAddress(pOldConfig->Ip->NTEContext);
3383 
3384                 /* Delete all default routes for this adapter */
3385                 dwSize = 0;
3386                 if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
3387                 {
3388                     DWORD Index;
3389                     PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE)CoTaskMemAlloc(dwSize);
3390                     if (pIpForwardTable)
3391                     {
3392                         if (GetIpForwardTable(pIpForwardTable, &dwSize, FALSE) == NO_ERROR)
3393                         {
3394                             for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
3395                             {
3396                                 if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index &&
3397                                     pIpForwardTable->table[Index].dwForwardDest == 0)
3398                                 {
3399                                     DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
3400                                 }
3401                             }
3402                         }
3403                         CoTaskMemFree(pIpForwardTable);
3404                     }
3405                 }
3406             }
3407         }
3408         else
3409         {
3410             /* Open the DHCP API if DHCP is enabled */
3411             if (pOldConfig->DhcpEnabled && DhcpCApiInitialize(&DhcpApiVersion) == NO_ERROR)
3412             {
3413                 /* We have to tell DHCP about this */
3414                 DhcpStaticRefreshParams(pCurrentConfig->Index,
3415                                         htonl(pCurrentConfig->Ip->IpAddress),
3416                                         htonl(pCurrentConfig->Ip->u.Subnetmask));
3417 
3418                 /* Close the API */
3419                 DhcpCApiCleanup();
3420             }
3421             else
3422             {
3423                 /* Delete this adapter's current static IP address */
3424                 DeleteIPAddress(pOldConfig->Ip->NTEContext);
3425 
3426                 /* Add the static IP address via the standard IPHLPAPI function */
3427                 AddIPAddress(htonl(pCurrentConfig->Ip->IpAddress),
3428                              htonl(pCurrentConfig->Ip->u.Subnetmask),
3429                              pCurrentConfig->Index,
3430                              &pCurrentConfig->Ip->NTEContext,
3431                              &NTEInstance);
3432             }
3433 
3434             pStr = CreateMultiSzString(pCurrentConfig->Ip, IPADDR, &dwSize, FALSE);
3435             if(pStr)
3436             {
3437                 RegSetValueExW(hKey, L"IPAddress", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3438                 CoTaskMemFree(pStr);
3439             }
3440 
3441             pStr = CreateMultiSzString(pCurrentConfig->Ip, SUBMASK, &dwSize, FALSE);
3442             if(pStr)
3443             {
3444                 RegSetValueExW(hKey, L"SubnetMask", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3445                 CoTaskMemFree(pStr);
3446             }
3447 
3448             /* Delete all default routes for this adapter */
3449             dwSize = 0;
3450             if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
3451             {
3452                 DWORD Index;
3453                 PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE)CoTaskMemAlloc(dwSize);
3454                 if (pIpForwardTable)
3455                 {
3456                     if (GetIpForwardTable(pIpForwardTable, &dwSize, FALSE) == NO_ERROR)
3457                     {
3458                         for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
3459                         {
3460                             if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index &&
3461                                 pIpForwardTable->table[Index].dwForwardDest == 0)
3462                             {
3463                                 DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
3464                             }
3465                         }
3466                     }
3467                     CoTaskMemFree(pIpForwardTable);
3468                 }
3469             }
3470         }
3471 
3472         if (pCurrentConfig->Gw)
3473         {
3474             MIB_IPFORWARDROW RouterMib;
3475             ZeroMemory(&RouterMib, sizeof(MIB_IPFORWARDROW));
3476 
3477             RouterMib.dwForwardMetric1 = 1;
3478             RouterMib.dwForwardIfIndex = pOldConfig->Index;
3479             RouterMib.dwForwardNextHop = htonl(pCurrentConfig->Gw->IpAddress);
3480 
3481             //TODO
3482             // add multiple gw addresses when required
3483 
3484             if (CreateIpForwardEntry(&RouterMib) == NO_ERROR)
3485             {
3486                 pStr = CreateMultiSzString(pCurrentConfig->Gw, IPADDR, &dwSize, FALSE);
3487                 if(pStr)
3488                 {
3489                     RegSetValueExW(hKey, L"DefaultGateway", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3490                     CoTaskMemFree(pStr);
3491                 }
3492 
3493                 pStr = CreateMultiSzString(pCurrentConfig->Gw, METRIC, &dwSize, FALSE);
3494                 if(pStr)
3495                 {
3496                     RegSetValueExW(hKey, L"DefaultGatewayMetric", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3497                     CoTaskMemFree(pStr);
3498                 }
3499             }
3500         }
3501         else
3502         {
3503             RegSetValueExW(hKey, L"DefaultGateway", 0, REG_MULTI_SZ, (LPBYTE)L"", 1 * sizeof(WCHAR));
3504             RegSetValueExW(hKey, L"DefaultGatewayMetric", 0, REG_MULTI_SZ, (LPBYTE)L"\0", sizeof(WCHAR) * 2);
3505         }
3506 
3507         if (!pCurrentConfig->Ns || pCurrentConfig->AutoconfigActive)
3508         {
3509             RegDeleteValueW(hKey, L"NameServer");
3510         }
3511         else
3512         {
3513             pStr = CreateMultiSzString(pCurrentConfig->Ns, IPADDR, &dwSize, TRUE);
3514             if(pStr)
3515             {
3516                 RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)pStr, dwSize);
3517                 //RegDeleteValueW(hKey, L"DhcpNameServer");
3518                 CoTaskMemFree(pStr);
3519             }
3520         }
3521 
3522         RegCloseKey(hKey);
3523     }
3524     return S_OK;
3525 }
3526 
3527 HRESULT
3528 WINAPI
3529 INetCfgComponentControl_fnApplyPnpChanges(
3530     INetCfgComponentControl * iface,
3531     INetCfgPnpReconfigCallback *pICallback)
3532 {
3533     //MessageBoxW(NULL, L"INetCfgComponentControl_fnApplyPnpChanges", NULL, MB_OK);
3534     return S_OK;
3535 }
3536 
3537 HRESULT
3538 WINAPI
3539 INetCfgComponentControl_fnCancelChanges(
3540     INetCfgComponentControl * iface)
3541 {
3542     //MessageBoxW(NULL, L"INetCfgComponentControl_fnCancelChanges", NULL, MB_OK);
3543     return S_OK;
3544 }
3545 
3546 static const INetCfgComponentControlVtbl vt_NetCfgComponentControl =
3547 {
3548     INetCfgComponentControl_fnQueryInterface,
3549     INetCfgComponentControl_fnAddRef,
3550     INetCfgComponentControl_fnRelease,
3551     INetCfgComponentControl_fnInitialize,
3552     INetCfgComponentControl_fnApplyRegistryChanges,
3553     INetCfgComponentControl_fnApplyPnpChanges,
3554     INetCfgComponentControl_fnCancelChanges
3555 };
3556 
3557 HRESULT
3558 WINAPI
3559 TcpipConfigNotify_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
3560 {
3561     TcpipConfNotifyImpl *This;
3562 
3563     if (!ppv)
3564         return E_POINTER;
3565 
3566     This = (TcpipConfNotifyImpl *) CoTaskMemAlloc(sizeof (TcpipConfNotifyImpl));
3567     if (!This)
3568         return E_OUTOFMEMORY;
3569 
3570     This->ref = 1;
3571     This->lpVtbl = (const INetCfgComponentPropertyUi*)&vt_NetCfgComponentPropertyUi;
3572     This->lpVtblCompControl = (const INetCfgComponentControl*)&vt_NetCfgComponentControl;
3573     This->pNCfg = NULL;
3574     This->pUnknown = NULL;
3575     This->pNComp = NULL;
3576     This->pCurrentConfig = NULL;
3577 
3578     if (!SUCCEEDED (INetCfgComponentPropertyUi_QueryInterface ((INetCfgComponentPropertyUi*)This, riid, ppv)))
3579     {
3580         INetCfgComponentPropertyUi_Release((INetCfgComponentPropertyUi*)This);
3581         return E_NOINTERFACE;
3582     }
3583 
3584     INetCfgComponentPropertyUi_Release((INetCfgComponentPropertyUi*)This);
3585     return S_OK;
3586 }
3587