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         SendDlgItemMessageW(hwndDlg, AllowButton, BM_SETCHECK, BST_CHECKED, 0);
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         SendDlgItemMessageW(hwndDlg, AllowButton, BM_SETCHECK, BST_CHECKED, 0);
261     else
262         SendDlgItemMessageW(hwndDlg, RestrictButton, BM_SETCHECK, BST_CHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_USE_FILTER, BM_GETCHECK, 0, 0) == 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                     SendDlgItemMessageW(hwndDlg, IDC_USE_FILTER, BM_SETCHECK, BST_CHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_TCP_ALLOW_ALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
404                         {
405                             SendDlgItemMessageW(hwndDlg, IDC_TCP_RESTRICT, BM_SETCHECK, BST_UNCHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_TCP_RESTRICT, BM_GETCHECK, 0, 0) == BST_CHECKED)
413                         {
414                             SendDlgItemMessageW(hwndDlg, IDC_TCP_ALLOW_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_UDP_ALLOW_ALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
422                         {
423                             SendDlgItemMessageW(hwndDlg, IDC_UDP_RESTRICT, BM_SETCHECK, BST_UNCHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_UDP_RESTRICT, BM_GETCHECK, 0, 0) == BST_CHECKED)
431                         {
432                             SendDlgItemMessageW(hwndDlg, IDC_UDP_ALLOW_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_IP_ALLOW_ALL, BM_GETCHECK, 0, 0) == BST_CHECKED)
440                         {
441                             SendDlgItemMessageW(hwndDlg, IDC_IP_RESTRICT, BM_SETCHECK, BST_UNCHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_IP_RESTRICT, BM_GETCHECK, 0, 0) == BST_CHECKED)
449                         {
450                             SendDlgItemMessageW(hwndDlg, IDC_IP_ALLOW_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
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 (SendDlgItemMessageW(hwndDlg, IDC_USE_FILTER, BM_GETCHECK, 0, 0) == 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 static
670 VOID
671 EnableIpButtons(
672     HWND hwndDlg)
673 {
674     BOOL bEnable;
675 
676     bEnable = (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_IPLIST)) != 0);
677 
678     EnableWindow(GetDlgItem(hwndDlg, IDC_IPMOD), bEnable);
679     EnableWindow(GetDlgItem(hwndDlg, IDC_IPDEL), bEnable);
680 }
681 
682 static
683 VOID
684 EnableGwButtons(
685     HWND hwndDlg)
686 {
687     BOOL bEnable;
688 
689     bEnable = (ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_GWLIST)) != 0);
690 
691     EnableWindow(GetDlgItem(hwndDlg, IDC_GWMOD), bEnable);
692     EnableWindow(GetDlgItem(hwndDlg, IDC_GWDEL), bEnable);
693 }
694 
695 VOID
696 InitializeTcpipAdvancedIpDlg(
697     HWND hwndDlg,
698     TcpipConfNotifyImpl * This)
699 {
700 
701     RECT rect;
702     LVITEMW li;
703     WCHAR szBuffer[100];
704 
705     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_IPLIST), IDS_IPADDR, 0, 100);
706     GetClientRect(GetDlgItem(hwndDlg, IDC_IPLIST), &rect);
707     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_IPLIST), IDS_SUBMASK, 1, (rect.right - rect.left - 100));
708 
709     if (This->pCurrentConfig->DhcpEnabled)
710     {
711         if (LoadStringW(netcfgx_hInstance, IDS_DHCPACTIVE, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
712         {
713             ZeroMemory(&li, sizeof(LVITEMW));
714             li.mask = LVIF_TEXT;
715             li.pszText = szBuffer;
716             SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_INSERTITEMW, 0, (LPARAM)&li);
717         }
718         EnableWindow(GetDlgItem(hwndDlg, IDC_IPADD), FALSE);
719         EnableWindow(GetDlgItem(hwndDlg, IDC_IPMOD), FALSE);
720         EnableWindow(GetDlgItem(hwndDlg, IDC_IPDEL), FALSE);
721     }
722     else
723     {
724         InsertIpAddressToListView(GetDlgItem(hwndDlg, IDC_IPLIST), This->pCurrentConfig->Ip, TRUE);
725         EnableIpButtons(hwndDlg);
726     }
727 
728     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_GWLIST), IDS_GATEWAY, 0, 100);
729     GetClientRect(GetDlgItem(hwndDlg, IDC_IPLIST), &rect);
730     InsertColumnToListView(GetDlgItem(hwndDlg, IDC_GWLIST), IDS_METRIC, 1, (rect.right - rect.left - 100));
731 
732     InsertIpAddressToListView(GetDlgItem(hwndDlg, IDC_GWLIST), This->pCurrentConfig->Gw, FALSE);
733     EnableGwButtons(hwndDlg);
734 
735     SendDlgItemMessageW(hwndDlg, IDC_METRIC, EM_LIMITTEXT, 4, 0);
736 
737 }
738 
739 INT_PTR
740 CALLBACK
741 TcpipAdvGwDlg(
742     HWND hwndDlg,
743     UINT uMsg,
744     WPARAM wParam,
745     LPARAM lParam
746 )
747 {
748     WCHAR szBuffer[70];
749     TcpipGwSettings *pGwSettings;
750     DWORD dwIpAddr;
751     LPNMIPADDRESS lpnmipa;
752     LVFINDINFOW find;
753 
754     switch(uMsg)
755     {
756         case WM_INITDIALOG:
757             pGwSettings = (TcpipGwSettings *)lParam;
758             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
759 
760             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
761             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
762             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
763             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
764 
765             if (pGwSettings->bAdd)
766             {
767                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
768                 {
769                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
770                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
771                 }
772                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), FALSE);
773                 SendDlgItemMessageW(hwndDlg, IDC_USEMETRIC, BM_SETCHECK, BST_CHECKED, 0);
774             }
775             else
776             {
777                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
778                 {
779                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
780                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
781                 }
782 
783                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)GetIpAddressFromStringW(pGwSettings->szIP));
784 
785                 if (pGwSettings->Metric)
786                 {
787                     SetDlgItemInt(hwndDlg, IDC_METRIC, pGwSettings->Metric, FALSE);
788                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), TRUE);
789                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), TRUE);
790                 }
791                 else
792                 {
793                     SendDlgItemMessageW(hwndDlg, IDC_USEMETRIC, BM_SETCHECK, BST_CHECKED, 0);
794                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), FALSE);
795                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), FALSE);
796                 }
797             }
798             return TRUE;
799         case WM_COMMAND:
800             if (LOWORD(wParam) == IDC_USEMETRIC)
801             {
802                 if (SendDlgItemMessage(hwndDlg, IDC_USEMETRIC, BM_GETCHECK, 0, 0) == BST_CHECKED)
803                 {
804                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), FALSE);
805                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), FALSE);
806                     SendDlgItemMessageW(hwndDlg, IDC_METRIC, WM_SETTEXT, 0, (LPARAM)L"");
807                 }
808                 else
809                 {
810                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), TRUE);
811                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRICTXT), TRUE);
812                 }
813                 break;
814             }
815             else if (LOWORD(wParam) == IDCANCEL)
816             {
817                 EndDialog(hwndDlg, FALSE);
818                 break;
819             }
820             else if (LOWORD(wParam) == IDC_OK)
821             {
822                 if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
823                 {
824                     pGwSettings = (TcpipGwSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
825                     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_GETTEXT, 16, (LPARAM)pGwSettings->szIP);
826 
827                     ZeroMemory(&find, sizeof(LVFINDINFOW));
828                     find.flags = LVFI_STRING;
829                     find.psz = pGwSettings->szIP;
830 
831                     if (SendDlgItemMessage(hwndDlg, IDC_USEMETRIC, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
832                         pGwSettings->Metric = GetDlgItemInt(hwndDlg, IDC_METRIC, NULL, FALSE);
833                     else
834                         pGwSettings->Metric = 0;
835 
836 
837                     if (SendMessageW(pGwSettings->hDlgCtrl, LVM_FINDITEMW, (WPARAM)-1, (LPARAM)&find) == -1)
838                     {
839                         EndDialog(hwndDlg, TRUE);
840                         break;
841                     }
842                     if (!pGwSettings->bAdd)
843                     {
844                         EndDialog(hwndDlg, FALSE);
845                         break;
846                     }
847                     DisplayError(IDS_DUP_GW, IDS_TCPIP, MB_ICONINFORMATION);
848                 }
849                 break;
850             }
851             break;
852         case WM_NOTIFY:
853             lpnmipa = (LPNMIPADDRESS) lParam;
854             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
855             {
856                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
857                 {
858                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
859                         EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
860                 }
861             }
862             break;
863     }
864     return FALSE;
865 }
866 
867 BOOL
868 GetGWListEntry(HWND hDlgCtrl, INT Index, TcpipGwSettings * pGwSettings)
869 {
870     LVITEMW li;
871     WCHAR szBuffer[30];
872     BOOL bRet;
873 
874     ZeroMemory(&li, sizeof(LVITEMW));
875     li.mask = LVIF_TEXT;
876     li.cchTextMax = 16;
877     li.pszText = pGwSettings->szIP;
878     li.iItem = Index;
879 
880     if (!SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
881         return FALSE;
882     li.pszText = szBuffer;
883     li.cchTextMax = 30;
884     li.iSubItem = 1;
885 
886     bRet = SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li);
887     if (bRet)
888     {
889         pGwSettings->Metric = _wtoi(szBuffer);
890     }
891 
892     return bRet;
893 }
894 
895 INT_PTR
896 CALLBACK
897 TcpipAddIpDlg(
898     HWND hwndDlg,
899     UINT uMsg,
900     WPARAM wParam,
901     LPARAM lParam
902 )
903 {
904     LPNMIPADDRESS lpnmipa;
905     DWORD dwIpAddr;
906     TcpipIpSettings *pIpSettings;
907     WCHAR szBuffer[50];
908     LVFINDINFOW find;
909     LRESULT lResult;
910 
911     switch(uMsg)
912     {
913         case WM_INITDIALOG:
914             pIpSettings = (TcpipIpSettings*)lParam;
915             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
916 
917             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
918             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
919             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
920             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
921             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 0, MAKEIPRANGE(0, 255));
922             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
923             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
924             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
925 
926             if (pIpSettings->bAdd)
927             {
928                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
929                 {
930                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
931                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
932                 }
933                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), FALSE);
934             }
935             else
936             {
937                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
938                 {
939                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
940                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
941                 }
942 
943                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)GetIpAddressFromStringW(pIpSettings->szIP));
944                 SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)GetIpAddressFromStringW(pIpSettings->szMask));
945             }
946             return TRUE;
947         case WM_NOTIFY:
948             lpnmipa = (LPNMIPADDRESS) lParam;
949             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
950             {
951                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
952                 {
953                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
954                     {
955                         if (dwIpAddr <= MAKEIPADDRESS(127, 255, 255, 255))
956                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 0, 0, 0));
957                         else if (dwIpAddr <= MAKEIPADDRESS(191, 255, 255, 255))
958                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 0, 0));
959                         else if (dwIpAddr <= MAKEIPADDRESS(223, 255, 255, 255))
960                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 255, 0));
961                         EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
962                      }
963                 }
964             }
965             break;
966         case WM_COMMAND:
967             if (LOWORD(wParam) == IDC_OK)
968             {
969                 pIpSettings = (TcpipIpSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
970                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_GETTEXT, 16, (LPARAM)pIpSettings->szIP);
971                 SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, WM_GETTEXT, 16, (LPARAM)pIpSettings->szMask);
972 
973                 ZeroMemory(&find, sizeof(LVFINDINFOW));
974                 find.flags = LVFI_STRING;
975                 find.psz = pIpSettings->szIP;
976                 lResult = SendMessageW(pIpSettings->hDlgCtrl, LVM_FINDITEMW, (WPARAM)-1, (LPARAM)&find);
977 
978                 if (lResult == -1)
979                 {
980                     EndDialog(hwndDlg, TRUE);
981                     break;
982                 }
983                 else if (!pIpSettings->bAdd)
984                 {
985                     EndDialog(hwndDlg, FALSE);
986                     break;
987                 }
988                 DisplayError(IDS_DUP_IPADDR, IDS_TCPIP, MB_ICONINFORMATION);
989                 break;
990             }
991             else if (LOWORD(wParam) == IDCANCEL)
992             {
993                 EndDialog(hwndDlg, FALSE);
994             }
995             break;
996     }
997     return FALSE;
998 }
999 
1000 BOOL
1001 VerifyDNSSuffix(
1002     LPWSTR szName)
1003 {
1004     UINT Index;
1005     UINT Length = wcslen(szName);
1006 
1007     for(Index = 0; Index < Length; Index++)
1008         if (iswalnum(szName[Index]) == 0 && szName[Index] != '.' && szName[Index] != '-')
1009             return FALSE;
1010 
1011     return TRUE;
1012 }
1013 
1014 INT_PTR
1015 CALLBACK
1016 TcpipAddSuffixDlg(
1017     HWND hwndDlg,
1018     UINT uMsg,
1019     WPARAM wParam,
1020     LPARAM lParam
1021 )
1022 {
1023     WCHAR szBuffer[100];
1024     TcpipSuffixSettings * pSettings;
1025     LRESULT lLength;
1026 
1027     switch(uMsg)
1028     {
1029         case WM_INITDIALOG:
1030             pSettings = (TcpipSuffixSettings*)lParam;
1031             if (!pSettings->bAdd)
1032             {
1033                 SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_SETTEXT, 0, (LPARAM)pSettings->Suffix);
1034                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1035                 {
1036                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1037                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1038                 }
1039                 CoTaskMemFree(pSettings->Suffix);
1040                 pSettings->Suffix = NULL;
1041             }
1042             else
1043             {
1044                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1045                 {
1046                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1047                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1048                 }
1049             }
1050             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSettings);
1051             return TRUE;
1052         case WM_COMMAND:
1053            if (LOWORD(wParam) == IDCANCEL)
1054            {
1055                EndDialog(hwndDlg, FALSE);
1056                break;
1057            }
1058            else if (LOWORD(wParam) == IDC_OK)
1059            {
1060                lLength = SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_GETTEXTLENGTH, 0, 0);
1061                if (lLength)
1062                {
1063                    pSettings = (TcpipSuffixSettings*) GetWindowLongPtr(hwndDlg, DWLP_USER);
1064                    pSettings->Suffix = (LPWSTR)CoTaskMemAlloc((lLength + 1)* sizeof(WCHAR));
1065                    if (pSettings->Suffix)
1066                    {
1067                        SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_GETTEXT, lLength + 1, (LPARAM)pSettings->Suffix);
1068                        if (SendMessageW(pSettings->hDlgCtrl, LB_FINDSTRING, 0, (LPARAM)pSettings->Suffix) != LB_ERR)
1069                        {
1070                            DisplayError(IDS_DUP_SUFFIX, IDS_TCPIP, MB_ICONWARNING);
1071                            CoTaskMemFree(pSettings->Suffix);
1072                            break;
1073                        }
1074 
1075                        if (!VerifyDNSSuffix(pSettings->Suffix))
1076                        {
1077                            DisplayError(IDS_DOMAIN_SUFFIX, IDS_TCPIP, MB_ICONWARNING);
1078                            CoTaskMemFree(pSettings->Suffix);
1079                            break;
1080                        }
1081                        EndDialog(hwndDlg, TRUE);
1082                    }
1083                }
1084                break;
1085            }
1086     }
1087     return FALSE;
1088 }
1089 
1090 
1091 
1092 INT
1093 GetSelectedItem(HWND hDlgCtrl)
1094 {
1095     LVITEMW li;
1096     UINT iItemCount, iIndex;
1097 
1098     iItemCount = ListView_GetItemCount(hDlgCtrl);
1099     if (!iItemCount)
1100         return -1;
1101 
1102     for (iIndex = 0; iIndex < iItemCount; iIndex++)
1103     {
1104         ZeroMemory(&li, sizeof(LVITEMW));
1105         li.mask = LVIF_STATE;
1106         li.stateMask = (UINT)-1;
1107         li.iItem = iIndex;
1108         if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
1109         {
1110             if (li.state & LVIS_SELECTED)
1111                 return iIndex;
1112         }
1113     }
1114     return -1;
1115 }
1116 
1117 
1118 BOOL
1119 GetIPListEntry(HWND hDlgCtrl, INT Index, TcpipIpSettings * pIpSettings)
1120 {
1121     LVITEMW li;
1122 
1123     ZeroMemory(&li, sizeof(LVITEMW));
1124     li.mask = LVIF_TEXT;
1125     li.cchTextMax = 16;
1126     li.pszText = pIpSettings->szIP;
1127     li.iItem = Index;
1128 
1129     if (!SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
1130         return FALSE;
1131 
1132     ZeroMemory(&li, sizeof(LVITEMW));
1133     li.mask = LVIF_TEXT;
1134     li.cchTextMax = 16;
1135     li.pszText = pIpSettings->szMask;
1136     li.iSubItem = 1;
1137     li.iItem = Index;
1138 
1139     return SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li);
1140 }
1141 
1142 VOID
1143 DeleteItemFromList(HWND hDlgCtrl)
1144 {
1145     LVITEMW li;
1146 
1147     memset(&li, 0x0, sizeof(LVITEMW));
1148     li.iItem = GetSelectedItem(hDlgCtrl);
1149     if (li.iItem < 0)
1150     {
1151         DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONINFORMATION);
1152         SetFocus(hDlgCtrl);
1153     }
1154     else
1155     {
1156         (void)ListView_DeleteItem(hDlgCtrl, li.iItem);
1157     }
1158 }
1159 
1160 UINT
1161 GetIpAddressFromStringW(
1162     WCHAR * szBuffer)
1163 {
1164     DWORD dwIpAddr = 0;
1165     INT Val;
1166     UINT Index = 3;
1167     LPWSTR pLast = szBuffer;
1168     LPWSTR pNext = szBuffer;
1169 
1170 
1171     while((pNext = wcschr(pNext, L'.')))
1172     {
1173         pNext[0] = L'\0';
1174         Val = _wtoi(pLast);
1175         dwIpAddr |= (Val << Index * 8);
1176         Index--;
1177         pNext++;
1178         pLast = pNext;
1179     }
1180     dwIpAddr |= _wtoi(pLast);
1181 
1182     return dwIpAddr;
1183 }
1184 
1185 UINT
1186 GetIpAddressFromStringA(
1187     char * sBuffer)
1188 {
1189     WCHAR szIp[16];
1190 
1191     if (MultiByteToWideChar(CP_ACP, 0, sBuffer, -1, szIp, 16))
1192     {
1193         szIp[15] = L'\0';
1194        return GetIpAddressFromStringW(szIp);
1195     }
1196     return (UINT)-1;
1197 }
1198 
1199 
1200 VOID
1201 FreeIPAddr(IP_ADDR *pAddr)
1202 {
1203     IP_ADDR *pNext;
1204 
1205     if (!pAddr)
1206         return;
1207 
1208     while(pAddr)
1209     {
1210         pNext = pAddr->Next;
1211         CoTaskMemFree(pAddr);
1212         pAddr = pNext;
1213     }
1214 }
1215 
1216 BOOL
1217 GetListViewItem(HWND hDlgCtrl, UINT Index, UINT SubIndex, WCHAR * szBuffer, UINT BufferSize)
1218 {
1219     LVITEMW li;
1220 
1221     ZeroMemory(&li, sizeof(LVITEMW));
1222     li.mask = LVIF_TEXT;
1223     li.pszText = szBuffer;
1224     li.iItem = Index;
1225     li.iSubItem = SubIndex;
1226     li.cchTextMax = BufferSize;
1227     return SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li);
1228 }
1229 
1230 VOID
1231 StoreIPSettings(
1232     HWND hDlgCtrl,
1233     TcpipConfNotifyImpl * This,
1234     BOOL bSubmask)
1235 {
1236     WCHAR szBuffer[30];
1237 
1238     INT iIndex, iCount;
1239     IP_ADDR *pCur, *pLast;
1240 
1241     iCount = ListView_GetItemCount(hDlgCtrl);
1242     if (!iCount)
1243     {
1244         return;
1245     }
1246 
1247     pLast = NULL;
1248     for(iIndex = 0; iIndex < iCount; iIndex++)
1249     {
1250         if (GetListViewItem(hDlgCtrl, iIndex, 0, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1251         {
1252             pCur = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
1253             if (!pCur)
1254                 break;
1255             ZeroMemory(pCur, sizeof(IP_ADDR));
1256 
1257             szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1258             pCur->IpAddress = GetIpAddressFromStringW(szBuffer);
1259 
1260             if (GetListViewItem(hDlgCtrl, iIndex, 1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR) ))
1261             {
1262                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1263                 if (bSubmask)
1264                     pCur->u.Subnetmask = GetIpAddressFromStringW(szBuffer);
1265                 else
1266                     pCur->u.Metric  = _wtoi(szBuffer);
1267             }
1268 
1269             if (!pLast)
1270             {
1271                 if (bSubmask)
1272                     This->pCurrentConfig->Ip = pCur;
1273                 else
1274                     This->pCurrentConfig->Gw = pCur;
1275             }
1276             else
1277             {
1278                 pLast->Next = pCur;
1279             }
1280 
1281             pLast = pCur;
1282         }
1283     }
1284 }
1285 
1286 
1287 INT_PTR
1288 CALLBACK
1289 TcpipAdvancedIpDlg(
1290     HWND hwndDlg,
1291     UINT uMsg,
1292     WPARAM wParam,
1293     LPARAM lParam
1294 )
1295 {
1296     TcpipConfNotifyImpl * This;
1297     LPPROPSHEETPAGE page;
1298     INT_PTR res;
1299     WCHAR szBuffer[200];
1300     LPPSHNOTIFY lppsn;
1301     TcpipGwSettings Gw;
1302     TcpipIpSettings Ip;
1303 
1304     LVITEMW li;
1305 
1306     switch(uMsg)
1307     {
1308         case WM_INITDIALOG:
1309             page = (LPPROPSHEETPAGE)lParam;
1310             This = (TcpipConfNotifyImpl*)page->lParam;
1311             InitializeTcpipAdvancedIpDlg(hwndDlg, This);
1312             SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)This);
1313             return TRUE;
1314         case WM_NOTIFY:
1315             lppsn = (LPPSHNOTIFY) lParam;
1316             if (lppsn->hdr.code == PSN_KILLACTIVE)
1317             {
1318                 This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1319                 if (!This->pCurrentConfig->DhcpEnabled && ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_IPLIST)) == 0)
1320                 {
1321                     DisplayError(IDS_NO_IPADDR_SET, IDS_TCPIP, MB_ICONWARNING);
1322                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
1323                     return TRUE;
1324                 }
1325             }
1326             else if (lppsn->hdr.code == PSN_APPLY)
1327             {
1328                 This = (TcpipConfNotifyImpl*) GetWindowLongPtr(hwndDlg, DWLP_USER);
1329                 FreeIPAddr(This->pCurrentConfig->Gw);
1330                 This->pCurrentConfig->Gw = NULL;
1331                 FreeIPAddr(This->pCurrentConfig->Ip);
1332                 This->pCurrentConfig->Ip = NULL;
1333                 StoreIPSettings(GetDlgItem(hwndDlg, IDC_IPLIST), This, TRUE);
1334                 StoreIPSettings(GetDlgItem(hwndDlg, IDC_GWLIST), This, FALSE);
1335                 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
1336                 return TRUE;
1337             }
1338             break;
1339         case WM_COMMAND:
1340             if (LOWORD(wParam) == IDC_AUTOMETRIC)
1341             {
1342                 if (SendDlgItemMessageW(hwndDlg, IDC_AUTOMETRIC, BM_GETCHECK, 0, 0) == BST_CHECKED)
1343                     EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), FALSE);
1344                 else
1345                    EnableWindow(GetDlgItem(hwndDlg, IDC_METRIC), TRUE);
1346             }
1347             else if (LOWORD(wParam) == IDC_IPADD)
1348             {
1349                 Ip.bAdd = TRUE;
1350                 Ip.hDlgCtrl = GetDlgItem(hwndDlg, IDC_IPLIST);
1351                 res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPADDIP_DLG), hwndDlg, TcpipAddIpDlg, (LPARAM)&Ip);
1352                 if (res)
1353                 {
1354                     memset(&li, 0x0, sizeof(LVITEMW));
1355                     li.mask = LVIF_TEXT | LVIF_PARAM;
1356                     li.iItem = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_IPLIST));
1357                     li.pszText = Ip.szIP;
1358                     li.iItem = SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_INSERTITEMW, 0, (LPARAM)&li);
1359                     if (li.iItem  != -1)
1360                     {
1361                         li.mask = LVIF_TEXT;
1362                         li.iSubItem = 1;
1363                         li.pszText = Ip.szMask;
1364                         SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1365                     }
1366 
1367                     EnableIpButtons(hwndDlg);
1368                 }
1369             }
1370             else if (LOWORD(wParam) == IDC_IPMOD)
1371             {
1372                 memset(&li, 0x0, sizeof(LVITEMW));
1373                 li.iItem = GetSelectedItem(GetDlgItem(hwndDlg, IDC_IPLIST));
1374                 if (li.iItem < 0)
1375                 {
1376                     /* no item selected */
1377                     DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONINFORMATION);
1378                     SetFocus(GetDlgItem(hwndDlg, IDC_IPLIST));
1379                     break;
1380                 }
1381                 Ip.bAdd = FALSE;
1382                 Ip.hDlgCtrl = GetDlgItem(hwndDlg, IDC_IPLIST);
1383                 if (GetIPListEntry(GetDlgItem(hwndDlg, IDC_IPLIST), li.iItem, &Ip))
1384                 {
1385                     res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPADDIP_DLG), hwndDlg, TcpipAddIpDlg, (LPARAM)&Ip);
1386                     if (res)
1387                     {
1388                             li.mask = LVIF_TEXT;
1389                             li.pszText = Ip.szIP;
1390                             SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1391                             li.pszText = Ip.szMask;
1392                             li.iSubItem = 1;
1393                             SendDlgItemMessageW(hwndDlg, IDC_IPLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1394                     }
1395                 }
1396             }
1397             else if (LOWORD(wParam) == IDC_IPDEL)
1398             {
1399                 DeleteItemFromList(GetDlgItem(hwndDlg, IDC_IPLIST));
1400                 EnableIpButtons(hwndDlg);
1401                 break;
1402             }
1403             else if (LOWORD(wParam) == IDC_GWADD)
1404             {
1405                 Gw.bAdd = TRUE;
1406                 Gw.hDlgCtrl = GetDlgItem(hwndDlg, IDC_GWLIST);
1407                 res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPGW_DLG), hwndDlg, TcpipAdvGwDlg, (LPARAM)&Gw);
1408                 if (res)
1409                 {
1410                     memset(&li, 0x0, sizeof(LVITEMW));
1411                     li.mask = LVIF_TEXT;
1412                     li.iItem = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_GWLIST));
1413                     li.pszText = Gw.szIP;
1414                     li.iItem = SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_INSERTITEMW, 0, (LPARAM)&li);
1415                     if (li.iItem >= 0)
1416                     {
1417                         if (Gw.Metric)
1418                         {
1419                             swprintf(szBuffer, L"%u", Gw.Metric);
1420                             li.iSubItem = 1;
1421                             li.pszText = szBuffer;
1422                             SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1423                         }
1424                         else
1425                         {
1426                             if (LoadStringW(netcfgx_hInstance, IDS_AUTOMATIC, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1427                             {
1428                                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1429                                 li.iSubItem = 1;
1430                                 li.pszText = szBuffer;
1431                                 SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1432                             }
1433                         }
1434                     }
1435 
1436                     EnableGwButtons(hwndDlg);
1437                 }
1438                 break;
1439             }
1440             else if (LOWORD(wParam) == IDC_GWMOD)
1441             {
1442                 memset(&li, 0x0, sizeof(LVITEMW));
1443                 li.iItem = GetSelectedItem(GetDlgItem(hwndDlg, IDC_GWLIST));
1444                 if (li.iItem < 0)
1445                 {
1446                     /* no item selected */
1447                     DisplayError(IDS_NOITEMSEL, IDS_TCPIP, MB_ICONINFORMATION);
1448                     SetFocus(GetDlgItem(hwndDlg, IDC_GWLIST));
1449                     break;
1450                 }
1451                 if (GetGWListEntry(GetDlgItem(hwndDlg, IDC_GWLIST), li.iItem, &Gw))
1452                 {
1453                     Gw.bAdd = FALSE;
1454                     Gw.hDlgCtrl = GetDlgItem(hwndDlg, IDC_GWLIST);
1455                     res = DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPGW_DLG), hwndDlg, TcpipAdvGwDlg, (LPARAM)&Gw);
1456                     if (res)
1457                     {
1458                         li.mask = LVIF_TEXT;
1459                         li.pszText = Gw.szIP;
1460                         (void)SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1461                         if (Gw.Metric)
1462                         {
1463                             swprintf(szBuffer, L"%u", Gw.Metric);
1464                             li.iSubItem = 1;
1465                             li.pszText = szBuffer;
1466                             SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1467                         }
1468                         else
1469                         {
1470                             if (LoadStringW(netcfgx_hInstance, IDS_AUTOMATIC, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1471                             {
1472                                 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1473                                 li.iSubItem = 1;
1474                                 li.pszText = szBuffer;
1475                                 SendDlgItemMessageW(hwndDlg, IDC_GWLIST, LVM_SETITEMW, 0, (LPARAM)&li);
1476                             }
1477                         }
1478                     }
1479                 }
1480                 break;
1481             }
1482             else if (LOWORD(wParam) == IDC_GWDEL)
1483             {
1484                 DeleteItemFromList(GetDlgItem(hwndDlg, IDC_GWLIST));
1485                 EnableGwButtons(hwndDlg);
1486                 break;
1487             }
1488     }
1489     return FALSE;
1490 }
1491 
1492 INT_PTR
1493 CALLBACK
1494 TcpipAddDNSDlg(
1495     HWND hwndDlg,
1496     UINT uMsg,
1497     WPARAM wParam,
1498     LPARAM lParam
1499 )
1500 {
1501     TcpipDnsSettings * pSettings;
1502     WCHAR szBuffer[100];
1503     DWORD dwIpAddr;
1504     LPNMIPADDRESS lpnmipa;
1505 
1506     switch(uMsg)
1507     {
1508         case WM_INITDIALOG:
1509             pSettings = (TcpipDnsSettings*)lParam;
1510             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
1511             if (!pSettings->bAdd)
1512             {
1513                 if (LoadStringW(netcfgx_hInstance, IDS_MOD, 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                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_SETTEXT, 0, (LPARAM)pSettings->szIP);
1519                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
1520             }
1521             else
1522             {
1523                 if (LoadStringW(netcfgx_hInstance, IDS_ADD, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
1524                 {
1525                     szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
1526                     SendDlgItemMessageW(hwndDlg, IDC_OK, WM_SETTEXT, 0, (LPARAM)szBuffer);
1527                 }
1528                 EnableWindow(GetDlgItem(hwndDlg, IDC_OK), FALSE);
1529             }
1530             return TRUE;
1531         case WM_COMMAND:
1532             if (LOWORD(wParam) == IDCANCEL)
1533             {
1534                 EndDialog(hwndDlg, FALSE);
1535                 break;
1536             }
1537             else if (LOWORD(wParam) == IDC_OK)
1538             {
1539                 pSettings = (TcpipDnsSettings*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1540                 SendDlgItemMessageW(hwndDlg, IDC_IPADDR, WM_GETTEXT, 16, (LPARAM)pSettings->szIP);
1541                 if (SendMessageW(pSettings->hDlgCtrl, LB_FINDSTRING, 0, (LPARAM)pSettings->szIP) == LB_ERR)
1542                 {
1543                     if (pSettings->bAdd)
1544                         SendMessageW(pSettings->hDlgCtrl, LB_ADDSTRING, 0, (LPARAM)pSettings->szIP);
1545                     EndDialog(hwndDlg, TRUE);
1546                     break;
1547                 }
1548                 if (!pSettings->bAdd)
1549                 {
1550                     EndDialog(hwndDlg, FALSE);
1551                     break;
1552                 }
1553                 DisplayError(IDS_DUP_SUFFIX, IDS_TCPIP, MB_ICONERROR);
1554                 break;
1555             }
1556             break;
1557         case WM_NOTIFY:
1558             lpnmipa = (LPNMIPADDRESS) lParam;
1559             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
1560             {
1561                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
1562                 {
1563                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
1564                         EnableWindow(GetDlgItem(hwndDlg, IDC_OK), TRUE);
1565                 }
1566             }
1567             break;
1568     }
1569     return FALSE;
1570 }
1571 
1572 
1573 
1574 VOID
1575 InitializeTcpipAdvancedDNSDlg(
1576     HWND hwndDlg,
1577     TcpipConfNotifyImpl * This)
1578 {
1579     WCHAR szBuffer[200];
1580     LPWSTR pFirst, pSep, pList;
1581     IP_ADDR * pAddr;
1582     DWORD dwIpAddr;
1583 
1584     /* insert DNS addresses */
1585     pAddr = This->pCurrentConfig->Ns;
1586     while(pAddr)
1587     {
1588         dwIpAddr = pAddr->IpAddress;
1589         swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
1590                  FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
1591 
1592         SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_ADDSTRING, 0, (LPARAM)szBuffer);
1593         pAddr = pAddr->Next;
1594     }
1595     SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_SETCURSEL, 0, 0);
1596 
1597     if (!This->pCurrentConfig->pDNS)
1598         return;
1599 
1600     if (This->pCurrentConfig->pDNS->RegisterAdapterName)
1601         SendDlgItemMessageW(hwndDlg, IDC_REGSUFFIX, BM_SETCHECK, BST_CHECKED, 0);
1602     else
1603         EnableWindow(GetDlgItem(hwndDlg, IDC_USESUFFIX), FALSE);
1604 
1605     if (This->pCurrentConfig->pDNS->RegistrationEnabled)
1606         SendDlgItemMessageW(hwndDlg, IDC_USESUFFIX, BM_SETCHECK, BST_CHECKED, 0);
1607 
1608     if (This->pCurrentConfig->pDNS->szDomain[0])
1609         SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_SETTEXT, 0, (LPARAM)szBuffer);
1610 
1611     if (This->pCurrentConfig->pDNS->UseDomainNameDevolution)
1612         SendDlgItemMessageW(hwndDlg, IDC_TOPPRIMSUFFIX, BM_SETCHECK, BST_CHECKED, 0);
1613 
1614     if (!This->pCurrentConfig->pDNS->szSearchList || (wcslen(This->pCurrentConfig->pDNS->szSearchList) == 0))
1615     {
1616         SendDlgItemMessageW(hwndDlg, IDC_PRIMSUFFIX, BM_SETCHECK, BST_CHECKED, 0);
1617         EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXADD), FALSE);
1618 
1619         return;
1620     }
1621 
1622     pList = This->pCurrentConfig->pDNS->szSearchList;
1623     if (wcslen(pList))
1624     {
1625         pFirst = pList;
1626         do
1627         {
1628             pSep = wcschr(pFirst, L',');
1629             if (pSep)
1630             {
1631                 pSep[0] = L'\0';
1632                 SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_ADDSTRING, 0, (LPARAM)pFirst);
1633                 pFirst = pSep + 1;
1634                 pSep[0] = L',';
1635             }
1636             else
1637             {
1638                 SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_ADDSTRING, 0, (LPARAM)pFirst);
1639                 break;
1640             }
1641         }while(TRUE);
1642 
1643         EnableWindow(GetDlgItem(hwndDlg, IDC_TOPPRIMSUFFIX), FALSE);
1644         SendDlgItemMessageW(hwndDlg, IDC_SELSUFFIX, BM_SETCHECK, BST_CHECKED, 0);
1645         SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_SETCURSEL, 0, 0);
1646     }
1647 }
1648 
1649 VOID
1650 ToggleUpDown(HWND hwndDlg, HWND hDlgCtrl, UINT UpButton, UINT DownButton, UINT ModButton, UINT DelButton)
1651 {
1652     LRESULT lResult, lCount;
1653 
1654     lResult = SendMessageW(hDlgCtrl, LB_GETCURSEL, 0, 0);
1655     lCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1656     if (lResult != LB_ERR)
1657     {
1658         if (lResult == 0)
1659             EnableWindow(GetDlgItem(hwndDlg, UpButton), FALSE);
1660         else
1661              EnableWindow(GetDlgItem(hwndDlg, UpButton), TRUE);
1662 
1663         if (lResult < lCount -1)
1664              EnableWindow(GetDlgItem(hwndDlg, DownButton), TRUE);
1665         else
1666              EnableWindow(GetDlgItem(hwndDlg, DownButton), FALSE);
1667     }
1668 
1669     if (lCount)
1670     {
1671         EnableWindow(GetDlgItem(hwndDlg, ModButton), TRUE);
1672         EnableWindow(GetDlgItem(hwndDlg, DelButton), TRUE);
1673     }
1674     else
1675     {
1676         EnableWindow(GetDlgItem(hwndDlg, ModButton), FALSE);
1677         EnableWindow(GetDlgItem(hwndDlg, DelButton), FALSE);
1678         EnableWindow(GetDlgItem(hwndDlg, UpButton), FALSE);
1679         EnableWindow(GetDlgItem(hwndDlg, DownButton), FALSE);
1680     }
1681 }
1682 
1683 VOID
1684 MoveItem(
1685     HWND hDlgCtrl,
1686     INT pos)
1687 {
1688     WCHAR szBuffer[100];
1689     LRESULT lResult;
1690 
1691     lResult = SendMessageW(hDlgCtrl, LB_GETCURSEL, 0, 0);
1692     if (lResult != LB_ERR)
1693     {
1694         if (SendMessageW(hDlgCtrl, LB_GETTEXTLEN, (WPARAM)lResult, 0) < sizeof(szBuffer)/sizeof(WCHAR) - 1)
1695         {
1696             if (SendMessageW(hDlgCtrl, LB_GETTEXT, (WPARAM)lResult, (LPARAM)szBuffer) != LB_ERR)
1697             {
1698                 SendMessageW(hDlgCtrl, LB_DELETESTRING, (WPARAM)lResult, 0);
1699                 SendMessageW(hDlgCtrl, LB_INSERTSTRING, (WPARAM)lResult + pos, (LPARAM)szBuffer);
1700                 SendMessageW(hDlgCtrl, LB_SETCURSEL, (WPARAM)lResult + pos, 0);
1701             }
1702         }
1703     }
1704 }
1705 VOID
1706 RemoveItem(
1707     HWND hDlgCtrl)
1708 {
1709     LRESULT lResult, lCount;
1710 
1711     lResult = SendMessageW(hDlgCtrl, LB_GETCURSEL, 0, 0);
1712     if (lResult != LB_ERR)
1713     {
1714         SendMessageW(hDlgCtrl, LB_DELETESTRING, (WPARAM)lResult, 0);
1715         lCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1716         if (lResult + 1 < lCount)
1717             SendMessageW(hDlgCtrl, LB_SETCURSEL, (WPARAM)lResult, 0);
1718         else
1719             SendMessageW(hDlgCtrl, LB_SETCURSEL, (WPARAM)lCount-1, 0);
1720     }
1721 }
1722 
1723 LPWSTR
1724 GetListViewEntries(
1725     HWND hDlgCtrl)
1726 {
1727     DWORD dwSize;
1728     INT iCount, iIndex;
1729     INT_PTR lResult;
1730     LPWSTR pszSearchList, pItem;
1731 
1732     iCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1733     if (!iCount || iCount == LB_ERR)
1734         return NULL; //BUGBUG
1735 
1736     dwSize = 0;
1737 
1738     for (iIndex = 0; iIndex < iCount; iIndex++)
1739     {
1740         lResult = SendMessageW(hDlgCtrl, LB_GETTEXTLEN, iIndex, 0);
1741         if (lResult == LB_ERR)
1742             return NULL;
1743 
1744         dwSize += lResult + 1;
1745     }
1746 
1747     pszSearchList = (LPWSTR)CoTaskMemAlloc((dwSize + 1) * sizeof(WCHAR));
1748     if (!pszSearchList)
1749         return NULL;
1750 
1751     pItem = pszSearchList;
1752     for (iIndex = 0; iIndex < iCount; iIndex++)
1753     {
1754         lResult = SendMessageW(hDlgCtrl, LB_GETTEXT, iIndex, (LPARAM)pItem);
1755         if (lResult == LB_ERR)
1756         {
1757             CoTaskMemFree(pszSearchList);
1758             return NULL;
1759         }
1760         dwSize -= lResult + 1;
1761         pItem += wcslen(pItem);
1762         if (iIndex != iCount -1)
1763         {
1764             pItem[0] = L',';
1765             pItem++;
1766         }
1767     }
1768     pItem[0] = L'\0';
1769     return pszSearchList;
1770 }
1771 
1772 VOID
1773 StoreDNSSettings(
1774     HWND hDlgCtrl,
1775     TcpipConfNotifyImpl *This)
1776 {
1777     INT iCount, iIndex;
1778     WCHAR Ip[16];
1779     IP_ADDR *pCur, *pLast;
1780 
1781     FreeIPAddr(This->pCurrentConfig->Ns);
1782     This->pCurrentConfig->Ns = NULL;
1783 
1784     iCount = SendMessageW(hDlgCtrl, LB_GETCOUNT, 0, 0);
1785     if (!iCount || iCount == LB_ERR)
1786     {
1787         return;
1788     }
1789 
1790     pLast = NULL;
1791     for(iIndex = 0; iIndex < iCount; iIndex++)
1792     {
1793         if (SendMessageW(hDlgCtrl, LB_GETTEXT, iIndex, (LPARAM)Ip) == LB_ERR)
1794             break;
1795 
1796         pCur = CoTaskMemAlloc(sizeof(IP_ADDR));
1797         if (!pCur)
1798             break;
1799         ZeroMemory(pCur, sizeof(IP_ADDR));
1800         pCur->IpAddress = GetIpAddressFromStringW(Ip);
1801 
1802         if (!pLast)
1803             This->pCurrentConfig->Ns = pCur;
1804         else
1805             pLast->Next = pCur;
1806 
1807         pLast = pCur;
1808         pCur = pCur->Next;
1809     }
1810     This->pCurrentConfig->AutoconfigActive = FALSE;
1811 }
1812 
1813 INT_PTR
1814 CALLBACK
1815 TcpipAdvancedDnsDlg(
1816     HWND hwndDlg,
1817     UINT uMsg,
1818     WPARAM wParam,
1819     LPARAM lParam
1820 )
1821 {
1822     TcpipConfNotifyImpl * This;
1823     LPPROPSHEETPAGE page;
1824     TcpipDnsSettings Dns;
1825     LRESULT lIndex, lLength;
1826     TcpipSuffixSettings Suffix;
1827     LPPSHNOTIFY lppsn;
1828     WCHAR szSuffix[100];
1829     WCHAR szFormat[200];
1830     WCHAR szBuffer[300];
1831 
1832 
1833     switch(uMsg)
1834     {
1835         case WM_INITDIALOG:
1836             page = (LPPROPSHEETPAGE)lParam;
1837             This = (TcpipConfNotifyImpl*)page->lParam;
1838             SetWindowLongPtr(hwndDlg, DWLP_USER, (INT_PTR)This);
1839             InitializeTcpipAdvancedDNSDlg(hwndDlg, This);
1840             ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1841             ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1842             return TRUE;
1843         case WM_NOTIFY:
1844             lppsn = (LPPSHNOTIFY) lParam;
1845             if (lppsn->hdr.code == PSN_KILLACTIVE)
1846             {
1847                 if (SendDlgItemMessageW(hwndDlg, IDC_SELSUFFIX, BM_GETCHECK, 0, 0) == BST_CHECKED &&
1848                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_GETCOUNT, 0, 0) == 0)
1849                 {
1850                     DisplayError(IDS_NO_SUFFIX, IDS_TCPIP, MB_ICONWARNING);
1851                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
1852                     return TRUE;
1853                 }
1854                 if (SendDlgItemMessageW(hwndDlg, IDC_SUFFIX, WM_GETTEXT, sizeof(szSuffix)/sizeof(WCHAR), (LPARAM)szSuffix))
1855                 {
1856                     szSuffix[(sizeof(szSuffix)/sizeof(WCHAR))-1] = L'\0';
1857                     if (VerifyDNSSuffix(szSuffix) == FALSE)
1858                     {
1859                         if (LoadStringW(netcfgx_hInstance, IDS_DNS_SUFFIX, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
1860                         {
1861                             szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
1862                             swprintf(szBuffer, szFormat, szSuffix);
1863                             if (LoadStringW(netcfgx_hInstance, IDS_TCPIP, szFormat, sizeof(szFormat)/sizeof(WCHAR)))
1864                                 szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
1865                             else
1866                                 szFormat[0] = L'\0';
1867 
1868                             MessageBoxW(hwndDlg, szBuffer, szFormat, MB_ICONWARNING);
1869                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
1870                             SetFocus(GetDlgItem(hwndDlg, IDC_SUFFIX));
1871                             return TRUE;
1872                         }
1873                     }
1874                 }
1875             }
1876             else if (lppsn->hdr.code == PSN_APPLY)
1877             {
1878                  This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
1879                  if (!This->pCurrentConfig->pDNS)
1880                    break;
1881 
1882                  StoreDNSSettings(GetDlgItem(hwndDlg, IDC_DNSADDRLIST), This);
1883                  if (SendDlgItemMessageW(hwndDlg, IDC_PRIMSUFFIX, BM_GETCHECK, 0, 0) == BST_CHECKED)
1884                  {
1885                      CoTaskMemFree(This->pCurrentConfig->pDNS->szSearchList);
1886                      This->pCurrentConfig->pDNS->szSearchList = NULL;
1887                      if (SendDlgItemMessageW(hwndDlg, IDC_TOPPRIMSUFFIX, BM_GETCHECK, 0, 0) == BST_CHECKED)
1888                          This->pCurrentConfig->pDNS->UseDomainNameDevolution = TRUE;
1889                      else
1890                          This->pCurrentConfig->pDNS->UseDomainNameDevolution = FALSE;
1891                  }
1892                  else
1893                  {
1894                      CoTaskMemFree(This->pCurrentConfig->pDNS->szSearchList);
1895                      This->pCurrentConfig->pDNS->szSearchList = NULL;
1896                      This->pCurrentConfig->pDNS->UseDomainNameDevolution = FALSE;
1897                      This->pCurrentConfig->pDNS->szSearchList = GetListViewEntries(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1898                  }
1899 
1900                  if (SendDlgItemMessageW(hwndDlg, IDC_REGSUFFIX, BM_GETCHECK, 0, 0) == BST_CHECKED)
1901                  {
1902                      This->pCurrentConfig->pDNS->RegisterAdapterName = TRUE;
1903                      if (SendDlgItemMessageW(hwndDlg, IDC_USESUFFIX, BM_GETCHECK, 0, 0) == BST_CHECKED)
1904                          This->pCurrentConfig->pDNS->RegistrationEnabled = TRUE;
1905                      else
1906                          This->pCurrentConfig->pDNS->RegistrationEnabled = FALSE;
1907                  }
1908                  else
1909                  {
1910                      This->pCurrentConfig->pDNS->RegisterAdapterName = FALSE;
1911                      This->pCurrentConfig->pDNS->RegistrationEnabled = FALSE;
1912                  }
1913             }
1914             break;
1915         case WM_COMMAND:
1916             if (LOWORD(wParam) == IDC_DNSADDRLIST && HIWORD(wParam) == LBN_SELCHANGE)
1917             {
1918                 ToggleUpDown(hwndDlg, (HWND)lParam, IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1919                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1920                 break;
1921             }
1922             else if (LOWORD(wParam) == IDC_DNSSUFFIXLIST && HIWORD(wParam) == LBN_SELCHANGE)
1923             {
1924                 ToggleUpDown(hwndDlg, (HWND)lParam, IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1925                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1926                 break;
1927             }
1928             else if (LOWORD(wParam) == IDC_PRIMSUFFIX && HIWORD(wParam) == BN_CLICKED)
1929             {
1930                 if (SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
1931                 {
1932                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXUP), FALSE);
1933                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXDOWN), FALSE);
1934                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXADD), FALSE);
1935                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXMOD), FALSE);
1936                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXDEL), FALSE);
1937                     EnableWindow(GetDlgItem(hwndDlg, IDC_TOPPRIMSUFFIX), TRUE);
1938                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_RESETCONTENT, 0, 0);
1939                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1940                 }
1941             }
1942             else if (LOWORD(wParam) == IDC_SELSUFFIX && HIWORD(wParam) == BN_CLICKED)
1943             {
1944                 if (SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
1945                 {
1946                     EnableWindow(GetDlgItem(hwndDlg, IDC_DNSSUFFIXADD), TRUE);
1947                     EnableWindow(GetDlgItem(hwndDlg, IDC_TOPPRIMSUFFIX), FALSE);
1948                     ToggleUpDown(hwndDlg, (HWND)lParam, IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1949                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1950                 }
1951                 break;
1952             }
1953             else if (LOWORD(wParam) == IDC_REGSUFFIX && HIWORD(wParam) == BN_CLICKED)
1954             {
1955                 if (SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
1956                     EnableWindow(GetDlgItem(hwndDlg, IDC_USESUFFIX), TRUE);
1957                 else
1958                     EnableWindow(GetDlgItem(hwndDlg, IDC_USESUFFIX), FALSE);
1959                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1960             }
1961             else if (LOWORD(wParam) == IDC_DNSADDRUP && HIWORD(wParam) == BN_CLICKED)
1962             {
1963                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSADDRLIST), -1);
1964                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1965                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1966                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1967                 break;
1968             }
1969             else if (LOWORD(wParam) == IDC_DNSADDRDOWN && HIWORD(wParam) == BN_CLICKED)
1970             {
1971                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSADDRLIST), 1);
1972                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1973                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1974                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1975                 break;
1976             }
1977             else if (LOWORD(wParam) == IDC_DNSSUFFIXUP && HIWORD(wParam) == BN_CLICKED)
1978             {
1979                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), -1);
1980                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1981                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1982                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1983                 break;
1984             }
1985             else if (LOWORD(wParam) == IDC_DNSSUFFIXDOWN && HIWORD(wParam) == BN_CLICKED)
1986             {
1987                 MoveItem(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), 1);
1988                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
1989                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
1990                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1991                 break;
1992             }
1993             else if (LOWORD(wParam) == IDC_DNSADDRDEL && HIWORD(wParam) == BN_CLICKED)
1994             {
1995                 RemoveItem(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1996                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
1997                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
1998                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
1999                 break;
2000             }
2001             else if (LOWORD(wParam) == IDC_DNSSUFFIXDEL && HIWORD(wParam) == BN_CLICKED)
2002             {
2003                 RemoveItem(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
2004                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
2005                 SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
2006                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2007                 break;
2008             }
2009             else if (LOWORD(wParam) == IDC_DNSADDRADD && HIWORD(wParam) == BN_CLICKED)
2010             {
2011                  Dns.bAdd = TRUE;
2012                  Dns.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSADDRLIST);
2013                  if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPDNS_DLG), NULL, TcpipAddDNSDlg, (LPARAM)&Dns))
2014                  {
2015                      ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSADDRLIST), IDC_DNSADDRUP, IDC_DNSADDRDOWN, IDC_DNSADDRMOD, IDC_DNSADDRDEL);
2016                      PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2017                  }
2018                  break;
2019             }
2020             else if (LOWORD(wParam) == IDC_DNSADDRMOD && HIWORD(wParam) == BN_CLICKED)
2021             {
2022                  lIndex = SendDlgItemMessage(hwndDlg, IDC_DNSADDRLIST, LB_GETCURSEL, 0, 0);
2023                  if (lIndex != LB_ERR)
2024                  {
2025                      Dns.bAdd = FALSE;
2026                      Dns.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSADDRLIST);
2027                      SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_GETTEXT, (WPARAM)lIndex, (LPARAM)Dns.szIP);
2028                      if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPDNS_DLG), NULL, TcpipAddDNSDlg, (LPARAM)&Dns))
2029                      {
2030                          SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_DELETESTRING, lIndex, 0);
2031                          SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_INSERTSTRING, lIndex, (LPARAM)Dns.szIP);
2032                          SendDlgItemMessageW(hwndDlg, IDC_DNSADDRLIST, LB_SETCURSEL, lIndex, 0);
2033                          SetFocus(GetDlgItem(hwndDlg, IDC_DNSADDRLIST));
2034                          PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2035                      }
2036                  }
2037                  break;
2038             }
2039             else if (LOWORD(wParam) == IDC_DNSSUFFIXADD && HIWORD(wParam) == BN_CLICKED)
2040             {
2041                 Suffix.bAdd = TRUE;
2042                 Suffix.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST);
2043                 Suffix.Suffix = NULL;
2044                 if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPSUFFIX_DLG), NULL, TcpipAddSuffixDlg, (LPARAM)&Suffix))
2045                 {
2046                     ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
2047                     lIndex = SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_ADDSTRING, 0, (LPARAM)Suffix.Suffix);
2048                     if (lIndex != LB_ERR)
2049                         SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_SETCURSEL, lIndex, 0);
2050                     SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
2051                     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2052                     CoTaskMemFree(Suffix.Suffix);
2053                 }
2054                 break;
2055             }
2056             else if (LOWORD(wParam) == IDC_DNSSUFFIXMOD && HIWORD(wParam) == BN_CLICKED)
2057             {
2058                 lIndex = SendDlgItemMessage(hwndDlg, IDC_DNSSUFFIXLIST, LB_GETCURSEL, 0, 0);
2059                 if (lIndex != LB_ERR)
2060                 {
2061                     Suffix.bAdd = FALSE;
2062                     Suffix.hDlgCtrl = GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST);
2063                     lLength = SendMessageW(Suffix.hDlgCtrl, LB_GETTEXTLEN, lIndex, 0);
2064                     if (lLength != LB_ERR)
2065                     {
2066                         Suffix.Suffix = (LPWSTR)CoTaskMemAlloc((lLength + 1) * sizeof(WCHAR));
2067                         if (Suffix.Suffix)
2068                         {
2069                             SendMessageW(Suffix.hDlgCtrl, LB_GETTEXT, lIndex, (LPARAM)Suffix.Suffix);
2070                             Suffix.Suffix[lLength] = L'\0';
2071                             if (DialogBoxParamW(netcfgx_hInstance, MAKEINTRESOURCEW(IDD_TCPIPSUFFIX_DLG), NULL, TcpipAddSuffixDlg, (LPARAM)&Suffix))
2072                             {
2073                                 if (Suffix.Suffix)
2074                                 {
2075                                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_DELETESTRING, lIndex, 0);
2076                                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_INSERTSTRING, lIndex, (LPARAM)Suffix.Suffix);
2077                                     SendDlgItemMessageW(hwndDlg, IDC_DNSSUFFIXLIST, LB_SETCURSEL, lIndex, 0);
2078                                     SetFocus(GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST));
2079                                     CoTaskMemFree(Suffix.Suffix);
2080                                 }
2081                                 ToggleUpDown(hwndDlg, GetDlgItem(hwndDlg, IDC_DNSSUFFIXLIST), IDC_DNSSUFFIXUP, IDC_DNSSUFFIXDOWN, IDC_DNSSUFFIXMOD, IDC_DNSSUFFIXDEL);
2082                                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2083                             }
2084                         }
2085                     }
2086                  }
2087                  break;
2088             }
2089     }
2090     return FALSE;
2091 }
2092 
2093 static int CALLBACK
2094 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
2095 {
2096     // NOTE: This callback is needed to set large icon correctly.
2097     HICON hIcon;
2098     switch (uMsg)
2099     {
2100         case PSCB_INITIALIZED:
2101         {
2102             hIcon = LoadIconW(netcfgx_hInstance, MAKEINTRESOURCEW(IDI_NETWORK));
2103             SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
2104             break;
2105         }
2106     }
2107     return 0;
2108 }
2109 
2110 VOID
2111 LaunchAdvancedTcpipSettings(
2112     HWND hwndDlg,
2113     TcpipConfNotifyImpl * This)
2114 {
2115     PROPSHEETHEADERW pinfo;
2116     HPROPSHEETPAGE hppages[3];
2117     WCHAR szBuffer[100];
2118 
2119     hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ADVIP_DLG), TcpipAdvancedIpDlg, (LPARAM)This, NULL);
2120     hppages[1] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ADVDNS_DLG), TcpipAdvancedDnsDlg, (LPARAM)This, NULL);
2121     hppages[2] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ADVOPT_DLG), TcpipAdvancedOptDlg, (LPARAM)This, NULL);
2122 
2123 
2124     if (LoadStringW(netcfgx_hInstance, IDS_TCPIP, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
2125         szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
2126     else
2127         szBuffer[0] = L'\0';
2128 
2129     ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
2130     pinfo.dwSize = sizeof(PROPSHEETHEADERW);
2131     pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW |
2132                     PSH_USEICONID | PSH_USECALLBACK;
2133     pinfo.u3.phpage = hppages;
2134     pinfo.nPages = 3;
2135     pinfo.hwndParent = hwndDlg;
2136     pinfo.hInstance = netcfgx_hInstance;
2137     pinfo.pszCaption = szBuffer;
2138     pinfo.u.pszIcon = MAKEINTRESOURCEW(IDI_NETWORK);
2139     pinfo.pfnCallback = PropSheetProc;
2140 
2141     StoreTcpipBasicSettings(hwndDlg, This, FALSE);
2142     PropertySheetW(&pinfo);
2143 
2144     InitializeTcpipBasicDlgCtrls(hwndDlg, This->pCurrentConfig);
2145     PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2146 }
2147 
2148 INT_PTR
2149 CALLBACK
2150 TcpipAltConfDlg(
2151     HWND hwndDlg,
2152     UINT uMsg,
2153     WPARAM wParam,
2154     LPARAM lParam)
2155 {
2156     switch(uMsg)
2157     {
2158         case WM_INITDIALOG:
2159             return TRUE;
2160     }
2161     return FALSE;
2162 }
2163 
2164 VOID
2165 AddAlternativeDialog(
2166     HWND hDlg,
2167     TcpipConfNotifyImpl * This)
2168 {
2169     HPROPSHEETPAGE hpage;
2170 
2171     hpage = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ALTCF_DLG), TcpipAltConfDlg, (LPARAM)This, NULL);
2172     if (!hpage)
2173         return;
2174 
2175     SendMessageW(hDlg, PSM_INSERTPAGE, 1, (LPARAM)hpage);
2176 }
2177 
2178 INT_PTR
2179 StoreTcpipBasicSettings(
2180     HWND hwndDlg,
2181     TcpipConfNotifyImpl * This,
2182     BOOL bApply)
2183 {
2184     DWORD dwIpAddr;
2185 
2186     if (SendDlgItemMessageW(hwndDlg, IDC_NODHCP, BM_GETCHECK, 0, 0) == BST_CHECKED)
2187     {
2188         This->pCurrentConfig->DhcpEnabled = FALSE;
2189         if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) != 4)
2190         {
2191             if (bApply)
2192             {
2193                 DisplayError(IDS_NO_IPADDR_SET, IDS_TCPIP, MB_ICONWARNING);
2194                 SetFocus(GetDlgItem(hwndDlg, IDC_IPADDR));
2195                 return E_FAIL;
2196             }
2197         }
2198         if (!This->pCurrentConfig->Ip)
2199         {
2200             This->pCurrentConfig->Ip = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2201             if (!This->pCurrentConfig->Ip)
2202                 return E_OUTOFMEMORY;
2203             ZeroMemory(This->pCurrentConfig->Ip, sizeof(IP_ADDR));
2204         }
2205         This->pCurrentConfig->Ip->IpAddress = dwIpAddr;
2206 
2207         if (SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) != 4)
2208         {
2209             if (bApply)
2210                 DisplayError(IDS_NO_SUBMASK_SET, IDS_TCPIP, MB_ICONWARNING);
2211             if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2212             {
2213                 if (dwIpAddr <= MAKEIPADDRESS(127, 255, 255, 255))
2214                     dwIpAddr = MAKEIPADDRESS(255, 0, 0, 0);
2215                 else if (dwIpAddr <= MAKEIPADDRESS(191, 255, 255, 255))
2216                     dwIpAddr = MAKEIPADDRESS(255, 255, 0, 0);
2217                 else if (dwIpAddr <= MAKEIPADDRESS(223, 255, 255, 255))
2218                     dwIpAddr = MAKEIPADDRESS(255, 255, 255, 0);
2219 
2220                 SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)dwIpAddr);
2221             }
2222             if (bApply)
2223             {
2224                 SetFocus(GetDlgItem(hwndDlg, IDC_SUBNETMASK));
2225                 return E_FAIL;
2226             }
2227         }
2228         /* store subnetmask */
2229         This->pCurrentConfig->Ip->u.Subnetmask = dwIpAddr;
2230 
2231         if (SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2232         {
2233             if (!This->pCurrentConfig->Gw)
2234             {
2235                 This->pCurrentConfig->Gw = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2236                 if (!This->pCurrentConfig->Gw)
2237                     return E_OUTOFMEMORY;
2238                 ZeroMemory(This->pCurrentConfig->Gw, sizeof(IP_ADDR));
2239             }
2240             /* store default gateway */
2241             This->pCurrentConfig->Gw->IpAddress = dwIpAddr;
2242        }
2243        else
2244        {
2245            if (This->pCurrentConfig->Gw)
2246            {
2247                IP_ADDR * pNextGw = This->pCurrentConfig->Gw->Next;
2248                CoTaskMemFree(This->pCurrentConfig->Gw);
2249                This->pCurrentConfig->Gw = pNextGw;
2250            }
2251        }
2252     }
2253     else
2254     {
2255         This->pCurrentConfig->DhcpEnabled = TRUE;
2256     }
2257     if (SendDlgItemMessageW(hwndDlg, IDC_FIXEDDNS, BM_GETCHECK, 0, 0) == BST_CHECKED)
2258     {
2259         BOOL bSkip = FALSE;
2260         This->pCurrentConfig->AutoconfigActive = FALSE;
2261         if (SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2262         {
2263             if (!This->pCurrentConfig->Ns)
2264             {
2265                 This->pCurrentConfig->Ns = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2266                 if (!This->pCurrentConfig->Ns)
2267                     return E_OUTOFMEMORY;
2268                 ZeroMemory(This->pCurrentConfig->Ns, sizeof(IP_ADDR));
2269             }
2270             This->pCurrentConfig->Ns->IpAddress = dwIpAddr;
2271         }
2272         else if (This->pCurrentConfig->Ns)
2273         {
2274             IP_ADDR *pTemp = This->pCurrentConfig->Ns->Next;
2275 
2276             CoTaskMemFree(This->pCurrentConfig->Ns);
2277             This->pCurrentConfig->Ns = pTemp;
2278             bSkip = TRUE;
2279         }
2280 
2281 
2282         if (SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2283         {
2284             if (!This->pCurrentConfig->Ns || bSkip)
2285             {
2286                 if (!This->pCurrentConfig->Ns)
2287                 {
2288                     This->pCurrentConfig->Ns = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2289                     if (!This->pCurrentConfig->Ns)
2290                         return E_OUTOFMEMORY;
2291                     ZeroMemory(This->pCurrentConfig->Ns, sizeof(IP_ADDR));
2292                 }
2293                 This->pCurrentConfig->Ns->IpAddress = dwIpAddr;
2294             }
2295             else if (!This->pCurrentConfig->Ns->Next)
2296             {
2297                 This->pCurrentConfig->Ns->Next = (IP_ADDR*)CoTaskMemAlloc(sizeof(IP_ADDR));
2298                 if (!This->pCurrentConfig->Ns->Next)
2299                    return E_OUTOFMEMORY;
2300                 ZeroMemory(This->pCurrentConfig->Ns->Next, sizeof(IP_ADDR));
2301                 This->pCurrentConfig->Ns->Next->IpAddress = dwIpAddr;
2302             }
2303             else
2304             {
2305                 This->pCurrentConfig->Ns->Next->IpAddress = dwIpAddr;
2306             }
2307         }
2308         else
2309         {
2310             if (This->pCurrentConfig->Ns && This->pCurrentConfig->Ns->Next)
2311             {
2312                 if (This->pCurrentConfig->Ns->Next->Next)
2313                 {
2314                     IP_ADDR *pTemp = This->pCurrentConfig->Ns->Next->Next;
2315                     CoTaskMemFree(This->pCurrentConfig->Ns->Next);
2316                     This->pCurrentConfig->Ns->Next = pTemp;
2317                 }
2318                 else
2319                 {
2320                     CoTaskMemFree(This->pCurrentConfig->Ns->Next);
2321                     This->pCurrentConfig->Ns->Next = NULL;
2322                 }
2323             }
2324         }
2325     }
2326     else
2327     {
2328         This->pCurrentConfig->AutoconfigActive = TRUE;
2329     }
2330    return S_OK;
2331 }
2332 
2333 HRESULT
2334 InitializeTcpipBasicDlgCtrls(
2335     HWND hwndDlg,
2336     TcpipSettings * pCurSettings)
2337 {
2338     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2339     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2340     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2341     SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2342 
2343     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 0, MAKEIPRANGE(0, 255));
2344     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2345     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2346     SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2347 
2348     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2349     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2350     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2351     SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2352 
2353     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2354     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2355     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2356     SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2357 
2358     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 0, MAKEIPRANGE(1, 223));
2359     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 1, MAKEIPRANGE(0, 255));
2360     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 2, MAKEIPRANGE(0, 255));
2361     SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETRANGE, 3, MAKEIPRANGE(0, 255));
2362 
2363     if (pCurSettings->DhcpEnabled)
2364     {
2365         SendDlgItemMessageW(hwndDlg, IDC_USEDHCP, BM_SETCHECK, BST_CHECKED, 0);
2366         EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), FALSE);
2367         EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), FALSE);
2368         EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), FALSE);
2369         EnableWindow(GetDlgItem(hwndDlg, IDC_AUTODNS), TRUE);
2370     }
2371     else
2372     {
2373         SendDlgItemMessageW(hwndDlg, IDC_NODHCP, BM_SETCHECK, BST_CHECKED, 0);
2374 
2375         if (pCurSettings->Ip)
2376         {
2377             /* set current ip address */
2378             SendDlgItemMessageA(hwndDlg, IDC_IPADDR, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ip->IpAddress);
2379             /* set current hostmask */
2380             SendDlgItemMessageA(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ip->u.Subnetmask);
2381         }
2382         if (pCurSettings->Gw && pCurSettings->Gw->IpAddress)
2383         {
2384             /* set current gateway */
2385             SendDlgItemMessageA(hwndDlg, IDC_DEFGATEWAY, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Gw->IpAddress);
2386         }
2387     }
2388     if (pCurSettings->AutoconfigActive)
2389     {
2390         SendDlgItemMessageW(hwndDlg, IDC_AUTODNS, BM_SETCHECK, BST_CHECKED, 0);
2391         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), FALSE);
2392         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), FALSE);
2393     }
2394     else
2395     {
2396         SendDlgItemMessageW(hwndDlg, IDC_FIXEDDNS, BM_SETCHECK, BST_CHECKED, 0);
2397         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2398         EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2399         if (pCurSettings->Ns)
2400         {
2401             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->IpAddress);
2402             if (pCurSettings->Ns->Next)
2403             {
2404                 SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_SETADDRESS, 0, (LPARAM)pCurSettings->Ns->Next->IpAddress);
2405             }
2406             else
2407             {
2408                 SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2409             }
2410         }
2411         else
2412         {
2413             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_CLEARADDRESS, 0, 0);
2414             SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2415         }
2416     }
2417 
2418     return S_OK;
2419 }
2420 
2421 HRESULT
2422 CopyIpAddrString(
2423     IP_ADDR_STRING * pSrc,
2424     IP_ADDR ** pTarget,
2425     COPY_TYPE Type,
2426     LPWSTR szMetric)
2427 {
2428     IP_ADDR_STRING * pCurrent;
2429     IP_ADDR *pNew, *pLast;
2430 
2431     pCurrent = pSrc;
2432     pLast = NULL;
2433 
2434     while(pCurrent)
2435     {
2436         pNew = CoTaskMemAlloc(sizeof(IP_ADDR));
2437         if (!pNew)
2438         {
2439            break;
2440         }
2441         ZeroMemory(pNew, sizeof(IP_ADDR));
2442         pNew->IpAddress = GetIpAddressFromStringA(pCurrent->IpAddress.String);
2443         if (!pNew->IpAddress)
2444         {
2445             CoTaskMemFree(pNew);
2446             return E_FAIL;
2447         }
2448 
2449        if (Type == SUBMASK)
2450        {
2451            pNew->u.Subnetmask = GetIpAddressFromStringA(pCurrent->IpMask.String);
2452            pNew->NTEContext = pCurrent->Context;
2453        }
2454        else if (Type == METRIC)
2455        {
2456            if (szMetric && szMetric[0] != L'\0')
2457            {
2458                pNew->u.Metric = _wtoi(szMetric);
2459                szMetric += wcslen(szMetric) + 1;
2460            }
2461        }
2462 
2463         if (!pLast)
2464             *pTarget = pNew;
2465         else
2466             pLast->Next = pNew;
2467 
2468         pLast = pNew;
2469         pCurrent = pCurrent->Next;
2470 
2471     }
2472     pLast->Next = NULL;
2473     return S_OK;
2474 }
2475 
2476 
2477 
2478 INT_PTR
2479 CALLBACK
2480 TcpipBasicDlg(
2481     HWND hwndDlg,
2482     UINT uMsg,
2483     WPARAM wParam,
2484     LPARAM lParam
2485 )
2486 {
2487     TcpipConfNotifyImpl * This;
2488     LPPROPSHEETPAGE page;
2489     LPNMIPADDRESS lpnmipa;
2490     LPPSHNOTIFY lppsn;
2491     DWORD dwIpAddr;
2492 
2493 
2494     switch(uMsg)
2495     {
2496         case WM_INITDIALOG:
2497             page = (LPPROPSHEETPAGE)lParam;
2498             This = (TcpipConfNotifyImpl*)page->lParam;
2499             if (This->pCurrentConfig)
2500                 InitializeTcpipBasicDlgCtrls(hwndDlg, This->pCurrentConfig);
2501             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This);
2502             return TRUE;
2503         case WM_NOTIFY:
2504             lppsn = (LPPSHNOTIFY) lParam;
2505             lpnmipa = (LPNMIPADDRESS) lParam;
2506             if (lpnmipa->hdr.code == IPN_FIELDCHANGED)
2507             {
2508                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2509                 if (lpnmipa->hdr.idFrom == IDC_IPADDR)
2510                 {
2511                     if (SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_GETADDRESS, 0, (LPARAM)&dwIpAddr) == 4)
2512                     {
2513                         if (dwIpAddr <= MAKEIPADDRESS(127, 255, 255, 255))
2514                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 0, 0, 0));
2515                         else if (dwIpAddr <= MAKEIPADDRESS(191, 255, 255, 255))
2516                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 0, 0));
2517                         else if (dwIpAddr <= MAKEIPADDRESS(223, 255, 255, 255))
2518                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(255, 255, 255, 0));
2519                      }
2520                 }
2521             }
2522             else if (lppsn->hdr.code == PSN_APPLY)
2523             {
2524                 This = (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER);
2525                 if (SUCCEEDED(StoreTcpipBasicSettings(hwndDlg, This, TRUE)))
2526                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
2527                 else
2528                     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID);
2529 
2530                 return TRUE;
2531             }
2532             break;
2533         case WM_COMMAND:
2534             if (HIWORD(wParam) == BN_CLICKED)
2535             {
2536                 switch (LOWORD(wParam))
2537                 {
2538                     case IDC_USEDHCP:
2539                         if (SendDlgItemMessageW(hwndDlg, IDC_USEDHCP, BM_GETCHECK, 0, 0) == BST_CHECKED)
2540                         {
2541                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2542                             SendDlgItemMessageW(hwndDlg, IDC_IPADDR, IPM_CLEARADDRESS, 0, 0);
2543                             SendDlgItemMessageW(hwndDlg, IDC_SUBNETMASK, IPM_CLEARADDRESS, 0, 0);
2544                             SendDlgItemMessageW(hwndDlg, IDC_DEFGATEWAY, IPM_CLEARADDRESS, 0, 0);
2545                             EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), FALSE);
2546                             EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), FALSE);
2547                             EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), FALSE);
2548                             EnableWindow(GetDlgItem(hwndDlg, IDC_AUTODNS), TRUE);
2549                             AddAlternativeDialog(GetParent(hwndDlg), (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER));
2550                         }
2551                         break;
2552                     case IDC_NODHCP:
2553                         if (SendDlgItemMessageW(hwndDlg, IDC_NODHCP, BM_GETCHECK, 0, 0) == BST_CHECKED)
2554                         {
2555                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2556                             EnableWindow(GetDlgItem(hwndDlg, IDC_IPADDR), TRUE);
2557                             EnableWindow(GetDlgItem(hwndDlg, IDC_SUBNETMASK), TRUE);
2558                             EnableWindow(GetDlgItem(hwndDlg, IDC_DEFGATEWAY), TRUE);
2559                             if (SendDlgItemMessageW(hwndDlg, IDC_AUTODNS, BM_GETCHECK, 0, 0) == BST_CHECKED)
2560                             {
2561                                 SendDlgItemMessageW(hwndDlg, IDC_AUTODNS, BM_SETCHECK, BST_UNCHECKED, 0);
2562                             }
2563                             EnableWindow(GetDlgItem(hwndDlg, IDC_AUTODNS), FALSE);
2564                             SendDlgItemMessageW(hwndDlg, IDC_FIXEDDNS, BM_SETCHECK, BST_CHECKED, 0);
2565                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2566                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2567                             SendMessageW(GetParent(hwndDlg), PSM_REMOVEPAGE, 1, 0);
2568                         }
2569                         break;
2570                     case IDC_AUTODNS:
2571                         if (SendDlgItemMessageW(hwndDlg, IDC_AUTODNS, BM_GETCHECK, 0, 0) == BST_CHECKED)
2572                         {
2573                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2574                             SendDlgItemMessageW(hwndDlg, IDC_DNS1, IPM_CLEARADDRESS, 0, 0);
2575                             SendDlgItemMessageW(hwndDlg, IDC_DNS2, IPM_CLEARADDRESS, 0, 0);
2576                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), FALSE);
2577                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), FALSE);
2578                         }
2579                         break;
2580                     case IDC_FIXEDDNS:
2581                         if (SendDlgItemMessageW(hwndDlg, IDC_FIXEDDNS, BM_GETCHECK, 0, 0) == BST_CHECKED)
2582                         {
2583                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
2584                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS1), TRUE);
2585                             EnableWindow(GetDlgItem(hwndDlg, IDC_DNS2), TRUE);
2586                         }
2587                         break;
2588                     case IDC_ADVANCED:
2589                         LaunchAdvancedTcpipSettings(hwndDlg, (TcpipConfNotifyImpl*)GetWindowLongPtr(hwndDlg, DWLP_USER));
2590                         break;
2591                 }
2592                 break;
2593             }
2594         default:
2595             break;
2596 
2597     }
2598     return FALSE;
2599 }
2600 
2601 /***************************************************************
2602  * INetCfgComponentPropertyUi interface
2603  */
2604 
2605 HRESULT
2606 WINAPI
2607 INetCfgComponentPropertyUi_fnQueryInterface(
2608     INetCfgComponentPropertyUi * iface,
2609     REFIID iid,
2610     LPVOID * ppvObj)
2611 {
2612     //LPOLESTR pStr;
2613     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2614 
2615     *ppvObj = NULL;
2616 
2617 
2618     if (IsEqualIID (iid, &IID_IUnknown) ||
2619         IsEqualIID (iid, &IID_INetCfgComponentPropertyUi))
2620     {
2621         *ppvObj = This;
2622         INetCfgComponentPropertyUi_AddRef(iface);
2623         return S_OK;
2624     }
2625     else if (IsEqualIID(iid, &IID_INetCfgComponentControl))
2626     {
2627         *ppvObj = (LPVOID*)&This->lpVtblCompControl;
2628         INetCfgComponentPropertyUi_AddRef(iface);
2629         return S_OK;
2630     }
2631 
2632     //StringFromCLSID(iid, &pStr);
2633     //MessageBoxW(NULL, pStr, L"INetConnectionPropertyUi_fnQueryInterface", MB_OK);
2634     //CoTaskMemFree(pStr);
2635 
2636     return E_NOINTERFACE;
2637 }
2638 
2639 
2640 ULONG
2641 WINAPI
2642 INetCfgComponentPropertyUi_fnAddRef(
2643     INetCfgComponentPropertyUi * iface)
2644 {
2645     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2646     ULONG refCount = InterlockedIncrement(&This->ref);
2647 
2648     return refCount;
2649 }
2650 
2651 ULONG
2652 WINAPI
2653 INetCfgComponentPropertyUi_fnRelease(
2654     INetCfgComponentPropertyUi * iface)
2655 {
2656     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2657     ULONG refCount = InterlockedDecrement(&This->ref);
2658 
2659     if (!refCount)
2660     {
2661        CoTaskMemFree(This);
2662     }
2663     return refCount;
2664 }
2665 
2666 HRESULT
2667 WINAPI
2668 INetCfgComponentPropertyUi_fnQueryPropertyUi(
2669     INetCfgComponentPropertyUi * iface,
2670     IUnknown *pUnkReserved)
2671 {
2672     INetLanConnectionUiInfo * pLanInfo;
2673     HRESULT hr;
2674     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2675 
2676     hr = IUnknown_QueryInterface(pUnkReserved, &IID_INetLanConnectionUiInfo, (LPVOID*)&pLanInfo);
2677     if (FAILED(hr))
2678         return hr;
2679 
2680     INetLanConnectionUiInfo_GetDeviceGuid(pLanInfo, &This->NetCfgInstanceId);
2681 
2682     //FIXME
2683     // check if tcpip is enabled on that binding */
2684     IUnknown_Release(pUnkReserved);
2685     return S_OK;
2686 }
2687 
2688 HRESULT
2689 WINAPI
2690 INetCfgComponentPropertyUi_fnSetContext(
2691     INetCfgComponentPropertyUi * iface,
2692     IUnknown *pUnkReserved)
2693 {
2694     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2695 
2696     if (!iface || !pUnkReserved)
2697         return E_POINTER;
2698 
2699     This->pUnknown = pUnkReserved;
2700     return S_OK;
2701 }
2702 
2703 HRESULT
2704 LoadDNSSettings(
2705     TcpipConfNotifyImpl * This)
2706 {
2707     LPOLESTR pStr;
2708     WCHAR szBuffer[200];
2709     HKEY hKey;
2710     DWORD dwSize;
2711 
2712 
2713     This->pCurrentConfig->pDNS = (TcpipAdvancedDNSDlgSettings*) CoTaskMemAlloc(sizeof(TcpipAdvancedDNSDlgSettings));
2714     if (!This->pCurrentConfig->pDNS)
2715         return E_FAIL;
2716 
2717     ZeroMemory(This->pCurrentConfig->pDNS, sizeof(TcpipAdvancedDNSDlgSettings));
2718 
2719     if (FAILED(StringFromCLSID(&This->NetCfgInstanceId, &pStr)))
2720         return E_FAIL;
2721 
2722     swprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", pStr);
2723     CoTaskMemFree(pStr);
2724     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
2725     {
2726         dwSize = sizeof(DWORD);
2727         RegQueryValueExW(hKey, L"RegisterAdapterName", NULL, NULL, (LPBYTE)&This->pCurrentConfig->pDNS->RegisterAdapterName, &dwSize);
2728         RegQueryValueExW(hKey, L"RegistrationEnabled", NULL, NULL, (LPBYTE)&This->pCurrentConfig->pDNS->RegistrationEnabled, &dwSize);
2729 
2730         dwSize = sizeof(This->pCurrentConfig->pDNS->szDomain);
2731         RegQueryValueExW(hKey, L"Domain", NULL, NULL, (LPBYTE)This->pCurrentConfig->pDNS->szDomain, &dwSize);
2732 
2733         RegCloseKey(hKey);
2734     }
2735 
2736     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
2737     {
2738         dwSize = sizeof(DWORD);
2739         RegQueryValueExW(hKey, L"UseDomainNameDevolution", NULL, NULL, (LPBYTE)&This->pCurrentConfig->pDNS->UseDomainNameDevolution, &dwSize);
2740 
2741         dwSize = 0;
2742         if (RegQueryValueExW(hKey, L"SearchList", NULL, NULL, NULL, &dwSize) == ERROR_SUCCESS)
2743         {
2744             This->pCurrentConfig->pDNS->szSearchList = (LPWSTR)CoTaskMemAlloc(dwSize);
2745             if (This->pCurrentConfig->pDNS->szSearchList)
2746             {
2747                 if (RegQueryValueExW(hKey, L"SearchList", NULL, NULL, (LPBYTE)This->pCurrentConfig->pDNS->szSearchList, &dwSize) != ERROR_SUCCESS)
2748                 {
2749                     CoTaskMemFree(This->pCurrentConfig->pDNS->szSearchList);
2750                     This->pCurrentConfig->pDNS->szSearchList = NULL;
2751                 }
2752             }
2753         }
2754         RegCloseKey(hKey);
2755     }
2756     return S_OK;
2757 }
2758 
2759 LPWSTR
2760 LoadTcpFilterSettingsFromRegistry(HKEY hKey, LPCWSTR szName, LPDWORD Size)
2761 {
2762     DWORD dwSize;
2763     LPWSTR pData;
2764 
2765     if (RegQueryValueExW(hKey, szName, NULL, NULL, NULL, &dwSize) != ERROR_SUCCESS)
2766         return NULL;
2767 
2768     pData = (LPWSTR)CoTaskMemAlloc(dwSize);
2769     if (!pData)
2770         return NULL;
2771 
2772     if (RegQueryValueExW(hKey, szName, NULL, NULL, (LPBYTE)pData, &dwSize) != ERROR_SUCCESS)
2773     {
2774         CoTaskMemFree(pData);
2775         return NULL;
2776     }
2777     *Size = dwSize;
2778     return pData;
2779 }
2780 
2781 HRESULT
2782 LoadFilterSettings(
2783     TcpipConfNotifyImpl * This)
2784 {
2785     HKEY hKey;
2786     TcpFilterSettings *pFilter;
2787     WCHAR szBuffer[200];
2788     LPOLESTR pStr;
2789     DWORD dwVal, dwSize;
2790 
2791     pFilter = (TcpFilterSettings*)CoTaskMemAlloc(sizeof(TcpFilterSettings));
2792     if (!pFilter)
2793         return E_FAIL;
2794 
2795     ZeroMemory(pFilter, sizeof(TcpFilterSettings));
2796     This->pCurrentConfig->pFilter = pFilter;
2797 
2798 
2799     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
2800     {
2801         dwSize = sizeof(DWORD);
2802         if (RegQueryValueExW(hKey, L"EnableSecurityFilters", NULL, NULL, (LPBYTE)&dwVal, &dwSize) == ERROR_SUCCESS)
2803             pFilter->EnableSecurityFilters = dwVal;
2804         RegCloseKey(hKey);
2805     }
2806     else
2807     {
2808         pFilter->EnableSecurityFilters = FALSE;
2809     }
2810 
2811     if (FAILED(StringFromCLSID(&This->NetCfgInstanceId, &pStr)))
2812         return E_FAIL;
2813 
2814     swprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", pStr);
2815     CoTaskMemFree(pStr);
2816     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
2817     {
2818         return S_OK;
2819     }
2820     pFilter->szTCPAllowedPorts = LoadTcpFilterSettingsFromRegistry(hKey, L"TCPAllowedPorts", &pFilter->TCPSize);
2821     pFilter->szUDPAllowedPorts = LoadTcpFilterSettingsFromRegistry(hKey, L"UDPAllowedPorts", &pFilter->UDPSize);
2822     pFilter->szRawIPAllowedProtocols = LoadTcpFilterSettingsFromRegistry(hKey, L"RawIPAllowedProtocols", &pFilter->IPSize);
2823     RegCloseKey(hKey);
2824     return S_OK;
2825 }
2826 
2827 
2828 HRESULT
2829 Initialize(TcpipConfNotifyImpl * This)
2830 {
2831     DWORD dwSize, Status;
2832     WCHAR szBuffer[50];
2833     IP_ADAPTER_INFO * pCurrentAdapter;
2834     IP_ADAPTER_INFO * pInfo;
2835     PIP_PER_ADAPTER_INFO pPerInfo;
2836     IP_PER_ADAPTER_INFO Info;
2837     LPOLESTR pStr;
2838     HRESULT hr;
2839     BOOL bFound;
2840     TcpipSettings * pCurSettings;
2841     ULONG uLength;
2842 
2843     if (This->pCurrentConfig)
2844         return S_OK;
2845 
2846     hr = StringFromCLSID(&This->NetCfgInstanceId, &pStr);
2847     if (FAILED(hr))
2848         return hr;
2849 
2850 
2851     dwSize = 0;
2852     if (GetAdaptersInfo(NULL, &dwSize) != ERROR_BUFFER_OVERFLOW)
2853     {
2854         CoTaskMemFree(pStr);
2855         return E_FAIL;
2856     }
2857 
2858     pInfo = CoTaskMemAlloc(dwSize);
2859     if (!pInfo)
2860     {
2861         CoTaskMemFree(pStr);
2862         return E_FAIL;
2863     }
2864 
2865     if (GetAdaptersInfo(pInfo, &dwSize) != ERROR_SUCCESS)
2866     {
2867         CoTaskMemFree(pStr);
2868         CoTaskMemFree(pInfo);
2869         return E_FAIL;
2870     }
2871 
2872     pCurrentAdapter = pInfo;
2873     bFound = FALSE;
2874     while(pCurrentAdapter)
2875     {
2876         szBuffer[0] = L'\0';
2877         if (MultiByteToWideChar(CP_ACP, 0, pCurrentAdapter->AdapterName, -1, szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0])))
2878         {
2879             szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
2880         }
2881         if (!_wcsicmp(szBuffer, pStr))
2882         {
2883             bFound = TRUE;
2884             break;
2885         }
2886         pCurrentAdapter = pCurrentAdapter->Next;
2887     }
2888     CoTaskMemFree(pStr);
2889 
2890     if (!bFound)
2891     {
2892         CoTaskMemFree(pInfo);
2893         return E_FAIL;
2894     }
2895 
2896     pCurSettings = CoTaskMemAlloc(sizeof(TcpipSettings));
2897     if (!pCurSettings)
2898     {
2899         CoTaskMemFree(pInfo);
2900         return E_FAIL;
2901     }
2902 
2903     ZeroMemory(pCurSettings, sizeof(TcpipSettings));
2904     This->pCurrentConfig = pCurSettings;
2905     pCurSettings->DhcpEnabled = pCurrentAdapter->DhcpEnabled;
2906     pCurSettings->Index = pCurrentAdapter->Index;
2907 
2908     if (!pCurrentAdapter->DhcpEnabled)
2909     {
2910         CopyIpAddrString(&pCurrentAdapter->IpAddressList, &pCurSettings->Ip, SUBMASK, NULL);
2911         CopyIpAddrString(&pCurrentAdapter->GatewayList, &pCurSettings->Gw, METRIC, NULL); //FIXME
2912     }
2913 
2914     uLength = sizeof(IP_PER_ADAPTER_INFO);
2915     ZeroMemory(&Info, sizeof(IP_PER_ADAPTER_INFO));
2916 
2917     if (GetPerAdapterInfo(pCurrentAdapter->Index, &Info, &uLength) == ERROR_BUFFER_OVERFLOW)
2918     {
2919         pPerInfo = (PIP_PER_ADAPTER_INFO)CoTaskMemAlloc(uLength);
2920         if (pPerInfo)
2921         {
2922             Status = GetPerAdapterInfo(pCurrentAdapter->Index, pPerInfo, &uLength);
2923             if (Status == NOERROR)
2924             {
2925                 if (!pPerInfo->AutoconfigActive)
2926                 {
2927                     CopyIpAddrString(&pPerInfo->DnsServerList, &pCurSettings->Ns, IPADDR, NULL);
2928                 }
2929                 pCurSettings->AutoconfigActive = pPerInfo->AutoconfigActive;
2930             }
2931             CoTaskMemFree(pPerInfo);
2932         }
2933     }
2934     else
2935     {
2936         if (!Info.AutoconfigActive)
2937         {
2938             CopyIpAddrString(&Info.DnsServerList, &pCurSettings->Ns, IPADDR, NULL);
2939         }
2940         pCurSettings->AutoconfigActive = Info.AutoconfigActive;
2941     }
2942 
2943     if (FAILED(LoadFilterSettings(This)))
2944         return E_FAIL;
2945 
2946     if (FAILED(LoadDNSSettings(This)))
2947         return E_FAIL;
2948 
2949     CoTaskMemFree(pInfo);
2950 
2951     return S_OK;
2952 }
2953 
2954 HRESULT
2955 WINAPI
2956 INetCfgComponentPropertyUi_fnMergePropPages(
2957     INetCfgComponentPropertyUi * iface,
2958     DWORD *pdwDefPages,
2959     BYTE **pahpspPrivate,
2960     UINT *pcPages,
2961     HWND hwndParent,
2962     LPCWSTR *pszStartPage)
2963 {
2964     HPROPSHEETPAGE * hppages;
2965     UINT NumPages;
2966     HRESULT hr;
2967     TcpipConfNotifyImpl * This = (TcpipConfNotifyImpl*)iface;
2968 
2969     hr = Initialize(This);
2970     if (FAILED(hr))
2971         return hr;
2972 
2973     if (This->pCurrentConfig->DhcpEnabled)
2974         NumPages = 2;
2975     else
2976         NumPages = 1;
2977 
2978     hppages = (HPROPSHEETPAGE*) CoTaskMemAlloc(sizeof(HPROPSHEETPAGE) * NumPages);
2979     if (!hppages)
2980         return E_FAIL;
2981 
2982     hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_BASIC_DLG), TcpipBasicDlg, (LPARAM)This, NULL);
2983     if (!hppages[0])
2984     {
2985         CoTaskMemFree(hppages);
2986         return E_FAIL;
2987     }
2988     if (NumPages == 2)
2989     {
2990         hppages[1] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_TCPIP_ALTCF_DLG), TcpipAltConfDlg, (LPARAM)This, NULL);
2991         if (!hppages[1])
2992         {
2993             DestroyPropertySheetPage(hppages[0]);
2994             CoTaskMemFree(hppages);
2995             return E_FAIL;
2996         }
2997     }
2998 
2999     *pahpspPrivate = (BYTE*)hppages;
3000     *pcPages = NumPages;
3001 
3002     return S_OK;
3003 }
3004 
3005 HRESULT
3006 WINAPI
3007 INetCfgComponentPropertyUi_fnValidateProperties(
3008     INetCfgComponentPropertyUi * iface,
3009     HWND hwndDlg)
3010 {
3011 MessageBoxW(NULL, L"INetCfgComponentPropertyUi_fnValidateProperties", NULL, MB_OK);
3012     return S_OK;
3013 }
3014 
3015 HRESULT
3016 WINAPI
3017 INetCfgComponentPropertyUi_fnApplyProperties(
3018     INetCfgComponentPropertyUi * iface)
3019 {
3020 MessageBoxW(NULL, L"INetCfgComponentPropertyUi_fnApplyProperties", NULL, MB_OK);
3021     return S_OK;
3022 }
3023 
3024 
3025 HRESULT
3026 WINAPI
3027 INetCfgComponentPropertyUi_fnCancelProperties(
3028     INetCfgComponentPropertyUi * iface)
3029 {
3030 //MessageBoxW(NULL, L"INetCfgComponentPropertyUi_fnCancelProperties", NULL, MB_OK);
3031     return S_OK;
3032 }
3033 
3034 static const INetCfgComponentPropertyUiVtbl vt_NetCfgComponentPropertyUi =
3035 {
3036     INetCfgComponentPropertyUi_fnQueryInterface,
3037     INetCfgComponentPropertyUi_fnAddRef,
3038     INetCfgComponentPropertyUi_fnRelease,
3039     INetCfgComponentPropertyUi_fnQueryPropertyUi,
3040     INetCfgComponentPropertyUi_fnSetContext,
3041     INetCfgComponentPropertyUi_fnMergePropPages,
3042     INetCfgComponentPropertyUi_fnValidateProperties,
3043     INetCfgComponentPropertyUi_fnApplyProperties,
3044     INetCfgComponentPropertyUi_fnCancelProperties
3045 };
3046 
3047 /***************************************************************
3048  * INetCfgComponentControl interface
3049  */
3050 
3051 HRESULT
3052 WINAPI
3053 INetCfgComponentControl_fnQueryInterface(
3054     INetCfgComponentControl * iface,
3055     REFIID iid,
3056     LPVOID * ppvObj)
3057 {
3058     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3059     return INetCfgComponentPropertyUi_QueryInterface((INetCfgComponentPropertyUi*)This, iid, ppvObj);
3060 }
3061 
3062 ULONG
3063 WINAPI
3064 INetCfgComponentControl_fnAddRef(
3065     INetCfgComponentControl * iface)
3066 {
3067     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3068     return INetCfgComponentPropertyUi_AddRef((INetCfgComponentPropertyUi*)This);
3069 }
3070 
3071 ULONG
3072 WINAPI
3073 INetCfgComponentControl_fnRelease(
3074     INetCfgComponentControl * iface)
3075 {
3076     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3077     return INetCfgComponentPropertyUi_Release((INetCfgComponentPropertyUi*)This);
3078 }
3079 
3080 HRESULT
3081 WINAPI
3082 INetCfgComponentControl_fnInitialize(
3083     INetCfgComponentControl * iface,
3084     INetCfgComponent *pIComp,
3085     INetCfg *pINetCfg,
3086     BOOL fInstalling)
3087 {
3088     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3089 
3090     This->pNCfg = pINetCfg;
3091     This->pNComp = pIComp;
3092 
3093     return S_OK;
3094 }
3095 
3096 static
3097 LPWSTR
3098 CreateMultiSzString(IP_ADDR * pAddr, COPY_TYPE Type, LPDWORD Size, BOOL bComma)
3099 {
3100     LPWSTR pStr, pRet;
3101     DWORD dwSize, dwIpAddr;
3102     WCHAR szBuffer[30];
3103     IP_ADDR *pTemp = pAddr;
3104 
3105 
3106     dwSize = 0;
3107     while(pTemp)
3108     {
3109         if (Type == IPADDR)
3110         {
3111             dwIpAddr = pTemp->IpAddress;
3112             swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
3113                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3114         }else if (Type == SUBMASK)
3115         {
3116             dwIpAddr = pTemp->u.Subnetmask;
3117             swprintf(szBuffer, L"%lu.%lu.%lu.%lu",
3118                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3119         }
3120         else if (Type == METRIC)
3121         {
3122             swprintf(szBuffer, L"%u", pTemp->u.Metric);
3123         }
3124 
3125         dwSize += wcslen(szBuffer) + 1;
3126         pTemp = pTemp->Next;
3127     }
3128 
3129     if (!dwSize)
3130         return NULL;
3131 
3132     pStr = pRet = CoTaskMemAlloc((dwSize+1) * sizeof(WCHAR));
3133     if(!pStr)
3134        return NULL;
3135 
3136     pTemp = pAddr;
3137     while(pTemp)
3138     {
3139         if (Type == IPADDR)
3140         {
3141             dwIpAddr = pTemp->IpAddress;
3142             swprintf(pStr, L"%lu.%lu.%lu.%lu",
3143                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3144         }else if (Type == SUBMASK)
3145         {
3146             dwIpAddr = pTemp->u.Subnetmask;
3147             swprintf(pStr, L"%lu.%lu.%lu.%lu",
3148                     FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr));
3149         }
3150         else if (Type == METRIC)
3151         {
3152             swprintf(pStr, L"%u", pTemp->u.Metric);
3153         }
3154 
3155         if (bComma)
3156         {
3157             pStr += wcslen(pStr);
3158             if (pTemp->Next)
3159             {
3160                 pStr[0] = L',';
3161                 pStr++;
3162             }
3163         }
3164         else
3165         {
3166             pStr += wcslen(pStr) + 1;
3167         }
3168         pTemp = pTemp->Next;
3169     }
3170     pStr[0] = L'\0';
3171     *Size = (dwSize+1) * sizeof(WCHAR);
3172     return pRet;
3173 }
3174 
3175 
3176 HRESULT
3177 WINAPI
3178 INetCfgComponentControl_fnApplyRegistryChanges(
3179     INetCfgComponentControl * iface)
3180 {
3181     HKEY hKey;
3182     LPOLESTR pStr;
3183     DWORD dwSize;
3184     WCHAR szBuffer[200];
3185     TcpipSettings * pCurrentConfig, *pOldConfig;
3186     ULONG NTEInstance;
3187     DWORD DhcpApiVersion;
3188 
3189     TcpipConfNotifyImpl * This = impl_from_INetCfgComponentControl(iface);
3190 
3191     pCurrentConfig = This->pCurrentConfig;
3192     This->pCurrentConfig = NULL;
3193 
3194     if (FAILED(Initialize(This)))
3195     {
3196         This->pCurrentConfig = pCurrentConfig;
3197         return E_FAIL;
3198     }
3199     pOldConfig = This->pCurrentConfig;
3200     This->pCurrentConfig = pCurrentConfig;
3201 
3202     //MessageBoxW(NULL, L"INetCfgComponentControl_fnApplyRegistryChanges", NULL, MB_OK);
3203 
3204 
3205     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
3206     {
3207         if (pCurrentConfig->pDNS)
3208         {
3209             RegSetValueExW(hKey, L"UseDomainNameDevolution", 0, REG_DWORD, (LPBYTE)&pCurrentConfig->pDNS->UseDomainNameDevolution, sizeof(DWORD));
3210             RegSetValueExW(hKey, L"SearchList", 0, REG_SZ, (LPBYTE)pCurrentConfig->pDNS->szSearchList,
3211                        (wcslen(pCurrentConfig->pDNS->szSearchList)+1) * sizeof(WCHAR));
3212         }
3213         if (pCurrentConfig->pFilter)
3214         {
3215             RegSetValueExW(hKey, L"EnableSecurityFilters", 0, REG_DWORD,
3216                       (LPBYTE)&pCurrentConfig->pFilter->EnableSecurityFilters, sizeof(DWORD));
3217         }
3218         RegCloseKey(hKey);
3219     }
3220 
3221     if (FAILED(StringFromCLSID(&This->NetCfgInstanceId, &pStr)))
3222         return E_FAIL;
3223 
3224     swprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s", pStr);
3225     CoTaskMemFree(pStr);
3226 
3227     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
3228     {
3229         if (pCurrentConfig->pDNS)
3230         {
3231             RegSetValueExW(hKey, L"RegisterAdapterName", 0, REG_DWORD, (LPBYTE)&This->pCurrentConfig->pDNS->RegisterAdapterName, sizeof(DWORD));
3232             RegSetValueExW(hKey, L"RegistrationEnabled", 0, REG_DWORD, (LPBYTE)&This->pCurrentConfig->pDNS->RegistrationEnabled, sizeof(DWORD));
3233             RegSetValueExW(hKey, L"Domain", 0, REG_SZ, (LPBYTE)This->pCurrentConfig->pDNS->szDomain,
3234                        (wcslen(This->pCurrentConfig->pDNS->szDomain)+1) * sizeof(WCHAR));
3235         }
3236 #if 0
3237         if (pCurrentConfig->pFilter)
3238         {
3239             if (pCurrentConfig->pFilter->szTCPAllowedPorts)
3240             {
3241                 RegSetValueExW(hKey, L"TCPAllowedPorts", 0, REG_MULTI_SZ,
3242                        (LPBYTE)pCurrentConfig->pFilter->szTCPAllowedPorts,
3243                         pCurrentConfig->pFilter->TCPSize);
3244             }
3245             if (pCurrentConfig->pFilter->szUDPAllowedPorts)
3246             {
3247                 RegSetValueExW(hKey, L"UDPAllowedPorts", 0, REG_MULTI_SZ,
3248                        (LPBYTE)pCurrentConfig->pFilter->szUDPAllowedPorts,
3249                         pCurrentConfig->pFilter->UDPSize);
3250             }
3251             if (pCurrentConfig->pFilter->szRawIPAllowedProtocols)
3252             {
3253                 RegSetValueExW(hKey, L"RawIPAllowedProtocols", 0, REG_MULTI_SZ,
3254                        (LPBYTE)pCurrentConfig->pFilter->szRawIPAllowedProtocols,
3255                         pCurrentConfig->pFilter->IPSize);
3256             }
3257         }
3258 #endif
3259         RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (LPBYTE)&pCurrentConfig->DhcpEnabled, sizeof(DWORD));
3260         if (pCurrentConfig->DhcpEnabled)
3261         {
3262             RegSetValueExW(hKey, L"IPAddress", 0, REG_MULTI_SZ, (LPBYTE)L"0.0.0.0\0", 9 * sizeof(WCHAR));
3263             RegSetValueExW(hKey, L"SubnetMask", 0, REG_MULTI_SZ, (LPBYTE)L"0.0.0.0\0", 9 * sizeof(WCHAR));
3264             RegSetValueExW(hKey, L"DefaultGateway", 0, REG_MULTI_SZ, (LPBYTE)L"\0", 2 * sizeof(WCHAR));
3265             RegSetValueExW(hKey, L"DefaultGatewayMetric", 0, REG_MULTI_SZ, (LPBYTE)L"\0", 2 * sizeof(WCHAR));
3266             if (!pOldConfig->DhcpEnabled)
3267             {
3268                 /* Delete this adapter's current IP address */
3269                 DeleteIPAddress(pOldConfig->Ip->NTEContext);
3270 
3271                 /* Delete all default routes for this adapter */
3272                 dwSize = 0;
3273                 if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
3274                 {
3275                     DWORD Index;
3276                     PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE)CoTaskMemAlloc(dwSize);
3277                     if (pIpForwardTable)
3278                     {
3279                         if (GetIpForwardTable(pIpForwardTable, &dwSize, FALSE) == NO_ERROR)
3280                         {
3281                             for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
3282                             {
3283                                 if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index &&
3284                                     pIpForwardTable->table[Index].dwForwardDest == 0)
3285                                 {
3286                                     DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
3287                                 }
3288                             }
3289                         }
3290                         CoTaskMemFree(pIpForwardTable);
3291                     }
3292                 }
3293             }
3294         }
3295         else
3296         {
3297             /* Open the DHCP API if DHCP is enabled */
3298             if (pOldConfig->DhcpEnabled && DhcpCApiInitialize(&DhcpApiVersion) == NO_ERROR)
3299             {
3300                 /* We have to tell DHCP about this */
3301                 DhcpStaticRefreshParams(pCurrentConfig->Index,
3302                                         htonl(pCurrentConfig->Ip->IpAddress),
3303                                         htonl(pCurrentConfig->Ip->u.Subnetmask));
3304 
3305                 /* Close the API */
3306                 DhcpCApiCleanup();
3307             }
3308             else
3309             {
3310                 /* Delete this adapter's current static IP address */
3311                 DeleteIPAddress(pOldConfig->Ip->NTEContext);
3312 
3313                 /* Add the static IP address via the standard IPHLPAPI function */
3314                 AddIPAddress(htonl(pCurrentConfig->Ip->IpAddress),
3315                              htonl(pCurrentConfig->Ip->u.Subnetmask),
3316                              pCurrentConfig->Index,
3317                              &pCurrentConfig->Ip->NTEContext,
3318                              &NTEInstance);
3319             }
3320 
3321             pStr = CreateMultiSzString(pCurrentConfig->Ip, IPADDR, &dwSize, FALSE);
3322             if(pStr)
3323             {
3324                 RegSetValueExW(hKey, L"IPAddress", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3325                 CoTaskMemFree(pStr);
3326             }
3327 
3328             pStr = CreateMultiSzString(pCurrentConfig->Ip, SUBMASK, &dwSize, FALSE);
3329             if(pStr)
3330             {
3331                 RegSetValueExW(hKey, L"SubnetMask", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3332                 CoTaskMemFree(pStr);
3333             }
3334 
3335             /* Delete all default routes for this adapter */
3336             dwSize = 0;
3337             if (GetIpForwardTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
3338             {
3339                 DWORD Index;
3340                 PMIB_IPFORWARDTABLE pIpForwardTable = (PMIB_IPFORWARDTABLE)CoTaskMemAlloc(dwSize);
3341                 if (pIpForwardTable)
3342                 {
3343                     if (GetIpForwardTable(pIpForwardTable, &dwSize, FALSE) == NO_ERROR)
3344                     {
3345                         for (Index = 0; Index < pIpForwardTable->dwNumEntries; Index++)
3346                         {
3347                             if (pIpForwardTable->table[Index].dwForwardIfIndex == pOldConfig->Index &&
3348                                 pIpForwardTable->table[Index].dwForwardDest == 0)
3349                             {
3350                                 DeleteIpForwardEntry(&pIpForwardTable->table[Index]);
3351                             }
3352                         }
3353                     }
3354                     CoTaskMemFree(pIpForwardTable);
3355                 }
3356             }
3357 
3358             if (pCurrentConfig->Gw)
3359             {
3360                 MIB_IPFORWARDROW RouterMib;
3361                 ZeroMemory(&RouterMib, sizeof(MIB_IPFORWARDROW));
3362 
3363                 RouterMib.dwForwardMetric1 = 1;
3364                 RouterMib.dwForwardIfIndex = pOldConfig->Index;
3365                 RouterMib.dwForwardNextHop = htonl(pCurrentConfig->Gw->IpAddress);
3366 
3367                 //TODO
3368                 // add multiple gw addresses when required
3369 
3370                 if (CreateIpForwardEntry(&RouterMib) == NO_ERROR)
3371                 {
3372                     pStr = CreateMultiSzString(pCurrentConfig->Gw, IPADDR, &dwSize, FALSE);
3373                     if(pStr)
3374                     {
3375                         RegSetValueExW(hKey, L"DefaultGateway", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3376                         CoTaskMemFree(pStr);
3377                     }
3378 
3379                     pStr = CreateMultiSzString(pCurrentConfig->Gw, METRIC, &dwSize, FALSE);
3380                     if(pStr)
3381                     {
3382                         RegSetValueExW(hKey, L"DefaultGatewayMetric", 0, REG_MULTI_SZ, (LPBYTE)pStr, dwSize);
3383                         CoTaskMemFree(pStr);
3384                     }
3385                 }
3386             }
3387             else
3388             {
3389                 RegSetValueExW(hKey, L"DefaultGateway", 0, REG_MULTI_SZ, (LPBYTE)L"", 1 * sizeof(WCHAR));
3390                 RegSetValueExW(hKey, L"DefaultGatewayMetric", 0, REG_MULTI_SZ, (LPBYTE)L"\0", sizeof(WCHAR) * 2);
3391             }
3392         }
3393 
3394         if (!pCurrentConfig->Ns || pCurrentConfig->AutoconfigActive)
3395         {
3396             RegDeleteValueW(hKey, L"NameServer");
3397         }
3398         else
3399         {
3400             pStr = CreateMultiSzString(pCurrentConfig->Ns, IPADDR, &dwSize, TRUE);
3401             if(pStr)
3402             {
3403                 RegSetValueExW(hKey, L"NameServer", 0, REG_SZ, (LPBYTE)pStr, dwSize);
3404                 //RegDeleteValueW(hKey, L"DhcpNameServer");
3405                 CoTaskMemFree(pStr);
3406             }
3407         }
3408 
3409         RegCloseKey(hKey);
3410     }
3411     return S_OK;
3412 }
3413 
3414 HRESULT
3415 WINAPI
3416 INetCfgComponentControl_fnApplyPnpChanges(
3417     INetCfgComponentControl * iface,
3418     INetCfgPnpReconfigCallback *pICallback)
3419 {
3420     //MessageBoxW(NULL, L"INetCfgComponentControl_fnApplyPnpChanges", NULL, MB_OK);
3421     return S_OK;
3422 }
3423 
3424 HRESULT
3425 WINAPI
3426 INetCfgComponentControl_fnCancelChanges(
3427     INetCfgComponentControl * iface)
3428 {
3429     //MessageBoxW(NULL, L"INetCfgComponentControl_fnCancelChanges", NULL, MB_OK);
3430     return S_OK;
3431 }
3432 
3433 static const INetCfgComponentControlVtbl vt_NetCfgComponentControl =
3434 {
3435     INetCfgComponentControl_fnQueryInterface,
3436     INetCfgComponentControl_fnAddRef,
3437     INetCfgComponentControl_fnRelease,
3438     INetCfgComponentControl_fnInitialize,
3439     INetCfgComponentControl_fnApplyRegistryChanges,
3440     INetCfgComponentControl_fnApplyPnpChanges,
3441     INetCfgComponentControl_fnCancelChanges
3442 };
3443 
3444 HRESULT
3445 WINAPI
3446 TcpipConfigNotify_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
3447 {
3448     TcpipConfNotifyImpl *This;
3449 
3450     if (!ppv)
3451         return E_POINTER;
3452 
3453     This = (TcpipConfNotifyImpl *) CoTaskMemAlloc(sizeof (TcpipConfNotifyImpl));
3454     if (!This)
3455         return E_OUTOFMEMORY;
3456 
3457     This->ref = 1;
3458     This->lpVtbl = (const INetCfgComponentPropertyUi*)&vt_NetCfgComponentPropertyUi;
3459     This->lpVtblCompControl = (const INetCfgComponentControl*)&vt_NetCfgComponentControl;
3460     This->pNCfg = NULL;
3461     This->pUnknown = NULL;
3462     This->pNComp = NULL;
3463     This->pCurrentConfig = NULL;
3464 
3465     if (!SUCCEEDED (INetCfgComponentPropertyUi_QueryInterface ((INetCfgComponentPropertyUi*)This, riid, ppv)))
3466     {
3467         INetCfgComponentPropertyUi_Release((INetCfgComponentPropertyUi*)This);
3468         return E_NOINTERFACE;
3469     }
3470 
3471     INetCfgComponentPropertyUi_Release((INetCfgComponentPropertyUi*)This);
3472     return S_OK;
3473 }
3474