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