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