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