2 * PROJECT: ReactOS Network Control Panel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/cpl/system/tcpip_properties.c
5 * PURPOSE: ReactOS Network Control Panel
6 * COPYRIGHT: Copyright 2004 Gero Kuehn (reactos.filter@gkware.com)
7 * Copyright 2006 Ge van Geldorp <gvg@reactos.org>
26 // this is missing on reactos...
27 #ifndef IPM_SETADDRESS
28 #define IPM_SETADDRESS (WM_USER+101)
39 typedef struct _TCPIP_PROPERTIES_DATA
{
54 } TCPIP_PROPERTIES_DATA
, *PTCPIP_PROPERTIES_DATA
;
56 void InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
);
57 DWORD APIENTRY
DhcpNotifyConfigChange(LPWSTR ServerName
, LPWSTR AdapterName
,
58 BOOL NewIpAddress
, DWORD IpIndex
,
59 DWORD IpAddress
, DWORD SubnetMask
,
64 ManualDNS(HWND Dlg
, BOOL Enabled
) {
65 CheckDlgButton(Dlg
, IDC_FIXEDDNS
,
66 Enabled
? BST_CHECKED
: BST_UNCHECKED
);
67 CheckDlgButton(Dlg
, IDC_AUTODNS
,
68 Enabled
? BST_UNCHECKED
: BST_CHECKED
);
69 EnableWindow(GetDlgItem(Dlg
, IDC_DNS1
), Enabled
);
70 EnableWindow(GetDlgItem(Dlg
, IDC_DNS2
), Enabled
);
72 SendDlgItemMessage(Dlg
, IDC_DNS1
, IPM_CLEARADDRESS
, 0, 0);
73 SendDlgItemMessage(Dlg
, IDC_DNS2
, IPM_CLEARADDRESS
, 0, 0);
78 EnableDHCP(HWND Dlg
, BOOL Enabled
) {
79 CheckDlgButton(Dlg
, IDC_USEDHCP
, Enabled
? BST_CHECKED
: BST_UNCHECKED
);
80 CheckDlgButton(Dlg
, IDC_NODHCP
, Enabled
? BST_UNCHECKED
: BST_CHECKED
);
81 EnableWindow(GetDlgItem(Dlg
, IDC_IPADDR
), ! Enabled
);
82 EnableWindow(GetDlgItem(Dlg
, IDC_SUBNETMASK
), ! Enabled
);
83 EnableWindow(GetDlgItem(Dlg
, IDC_DEFGATEWAY
), ! Enabled
);
84 EnableWindow(GetDlgItem(Dlg
, IDC_AUTODNS
), Enabled
);
86 SendDlgItemMessage(Dlg
, IDC_IPADDR
, IPM_CLEARADDRESS
, 0, 0);
87 SendDlgItemMessage(Dlg
, IDC_SUBNETMASK
, IPM_CLEARADDRESS
, 0, 0);
88 SendDlgItemMessage(Dlg
, IDC_DEFGATEWAY
, IPM_CLEARADDRESS
, 0, 0);
95 ShowError(HWND Parent
, UINT MsgId
)
97 WCHAR Error
[32], Msg
[64];
99 if (0 == LoadStringW((HINSTANCE
) GetWindowLongPtrW(Parent
, GWLP_HINSTANCE
),
100 IDS_ERROR
, Error
, sizeof(Error
) / sizeof(Error
[0]))) {
101 wcscpy(Error
, L
"Error");
103 if (0 == LoadStringW((HINSTANCE
) GetWindowLongPtrW(Parent
, GWLP_HINSTANCE
),
104 MsgId
, Msg
, sizeof(Msg
) / sizeof(Msg
[0]))) {
105 wcscpy(Msg
, L
"Unknown error");
107 MessageBoxW(Parent
, Msg
, Error
, MB_OK
| MB_ICONSTOP
);
111 ValidateAndStore(HWND Dlg
, PTCPIP_PROPERTIES_DATA DlgData
)
115 DlgData
->DhcpEnabled
= (BST_CHECKED
==
116 IsDlgButtonChecked(Dlg
, IDC_USEDHCP
));
117 if (! DlgData
->DhcpEnabled
) {
118 if (4 != SendMessageW(GetDlgItem(Dlg
, IDC_IPADDR
), IPM_GETADDRESS
,
119 0, (LPARAM
) &IpAddress
)) {
120 ShowError(Dlg
, IDS_ENTER_VALID_IPADDRESS
);
121 SetFocus(GetDlgItem(Dlg
, IDC_IPADDR
));
124 DlgData
->IpAddress
= htonl(IpAddress
);
125 if (4 != SendMessageW(GetDlgItem(Dlg
, IDC_SUBNETMASK
), IPM_GETADDRESS
,
126 0, (LPARAM
) &IpAddress
)) {
127 ShowError(Dlg
, IDS_ENTER_VALID_SUBNET
);
128 SetFocus(GetDlgItem(Dlg
, IDC_SUBNETMASK
));
131 DlgData
->SubnetMask
= htonl(IpAddress
);
132 if (4 != SendMessageW(GetDlgItem(Dlg
, IDC_DEFGATEWAY
), IPM_GETADDRESS
,
133 0, (LPARAM
) &IpAddress
)) {
134 DlgData
->Gateway
= INADDR_NONE
;
136 DlgData
->Gateway
= htonl(IpAddress
);
138 ASSERT(BST_CHECKED
== IsDlgButtonChecked(Dlg
, IDC_FIXEDDNS
));
140 DlgData
->IpAddress
= INADDR_NONE
;
141 DlgData
->SubnetMask
= INADDR_NONE
;
142 DlgData
->Gateway
= INADDR_NONE
;
145 if (BST_CHECKED
== IsDlgButtonChecked(Dlg
, IDC_FIXEDDNS
)) {
146 if (4 != SendMessageW(GetDlgItem(Dlg
, IDC_DNS1
), IPM_GETADDRESS
,
147 0, (LPARAM
) &IpAddress
)) {
148 DlgData
->Dns1
= INADDR_NONE
;
150 DlgData
->Dns1
= htonl(IpAddress
);
152 if (4 != SendMessageW(GetDlgItem(Dlg
, IDC_DNS2
), IPM_GETADDRESS
,
153 0, (LPARAM
) &IpAddress
)) {
154 DlgData
->Dns2
= INADDR_NONE
;
156 DlgData
->Dns2
= htonl(IpAddress
);
159 DlgData
->Dns1
= INADDR_NONE
;
160 DlgData
->Dns2
= INADDR_NONE
;
167 InternTCPIPSettings(HWND Dlg
, PTCPIP_PROPERTIES_DATA DlgData
) {
173 if (! ValidateAndStore(Dlg
, DlgData
)) {
174 /* Should never happen, we should have validated at PSN_KILLACTIVE */
180 if (DlgData
->DhcpEnabled
) {
181 Changed
= ! DlgData
->OldDhcpEnabled
;
185 Changed
= DlgData
->OldDhcpEnabled
||
186 DlgData
->IpAddress
!= DlgData
->OldIpAddress
||
187 DlgData
->SubnetMask
!= DlgData
->OldSubnetMask
;
188 IpChanged
= DlgData
->OldDhcpEnabled
||
189 DlgData
->IpAddress
!= DlgData
->OldIpAddress
;
194 AdapterName
= HeapAlloc(GetProcessHeap(), 0,
195 (strlen(DlgData
->AdapterName
) + 1) *
197 if (NULL
== AdapterName
) {
198 ShowError(Dlg
, IDS_OUT_OF_MEMORY
);
201 MultiByteToWideChar(CP_THREAD_ACP
, 0, DlgData
->AdapterName
, -1,
202 AdapterName
, strlen(DlgData
->AdapterName
) + 1);
203 if (0 == DhcpNotifyConfigChange(NULL
, AdapterName
, IpChanged
,
204 DlgData
->AdapterIndex
,
206 DlgData
->SubnetMask
, DhcpAction
)) {
207 HeapFree(GetProcessHeap(), 0, AdapterName
);
208 ShowError(Dlg
, IDS_CANNOT_SAVE_CHANGES
);
211 HeapFree(GetProcessHeap(), 0, AdapterName
);
214 /* FIXME Save default gateway and DNS entries */
218 static INT_PTR CALLBACK
219 TCPIPPropertyPageProc(HWND Dlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
221 LPPROPSHEETPAGEW Page
;
222 PTCPIP_PROPERTIES_DATA DlgData
;
225 DlgData
= (PTCPIP_PROPERTIES_DATA
) GetWindowLongPtrW(Dlg
, GWL_USERDATA
);
228 Page
= (LPPROPSHEETPAGEW
) lParam
;
229 DlgData
= (PTCPIP_PROPERTIES_DATA
) Page
->lParam
;
230 SetWindowLongPtrW(Dlg
, GWL_USERDATA
, Page
->lParam
);
232 EnableWindow(GetDlgItem(Dlg
, IDC_ADVANCED
), FALSE
);
234 EnableDHCP(Dlg
, DlgData
->OldDhcpEnabled
);
236 if (! DlgData
->OldDhcpEnabled
)
238 if (INADDR_NONE
!= DlgData
->OldIpAddress
) {
239 SendDlgItemMessage(Dlg
, IDC_IPADDR
, IPM_SETADDRESS
, 0,
240 ntohl(DlgData
->OldIpAddress
));
242 if (INADDR_NONE
!= DlgData
->OldSubnetMask
) {
243 SendDlgItemMessage(Dlg
, IDC_SUBNETMASK
, IPM_SETADDRESS
, 0,
244 ntohl(DlgData
->OldSubnetMask
));
246 if (INADDR_NONE
!= DlgData
->OldGateway
) {
247 SendDlgItemMessage(Dlg
, IDC_DEFGATEWAY
, IPM_SETADDRESS
, 0,
248 ntohl(DlgData
->OldGateway
));
252 if (INADDR_NONE
!= DlgData
->OldDns1
) {
253 SendDlgItemMessage(Dlg
, IDC_DNS1
, IPM_SETADDRESS
, 0,
254 ntohl(DlgData
->OldDns1
));
255 if (INADDR_NONE
!= DlgData
->OldDns2
) {
256 SendDlgItemMessage(Dlg
, IDC_DNS2
, IPM_SETADDRESS
, 0,
257 ntohl(DlgData
->OldDns2
));
260 ManualDNS(Dlg
, INADDR_NONE
!= DlgData
->OldDns1
);
264 switch(LOWORD(wParam
)) {
266 ManualDNS(Dlg
, TRUE
);
270 ManualDNS(Dlg
, FALSE
);
274 EnableDHCP(Dlg
, TRUE
);
278 EnableDHCP(Dlg
, FALSE
);
284 Nmhdr
= (LPNMHDR
) lParam
;
286 switch(Nmhdr
->code
) {
288 /* Do validation here, must set FALSE to continue */
289 SetWindowLongPtrW(Dlg
, DWL_MSGRESULT
,
290 (LONG_PTR
) ! ValidateAndStore(Dlg
, DlgData
));
294 /* Set the IP Address and DNS Information so we won't
295 * be doing all this for nothing */
296 SetWindowLongPtrW(Dlg
, DWL_MSGRESULT
,
297 InternTCPIPSettings(Dlg
, DlgData
) ?
298 PSNRET_NOERROR
: PSNRET_INVALID
);
308 LoadDataFromInfo(PTCPIP_PROPERTIES_DATA DlgData
, IP_ADAPTER_INFO
*Info
)
310 IP_ADDR_STRING
*pString
;
311 WCHAR RegKey
[MAX_PATH
];
318 DlgData
->AdapterName
= Info
->AdapterName
;
319 DlgData
->AdapterIndex
= Info
->Index
;
321 DlgData
->OldDhcpEnabled
= Info
->DhcpEnabled
;
323 pString
= &Info
->IpAddressList
;
324 while (NULL
!= pString
->Next
) {
325 pString
= pString
->Next
;
327 DlgData
->OldIpAddress
= inet_addr(pString
->IpAddress
.String
);
328 DlgData
->OldSubnetMask
= inet_addr(pString
->IpMask
.String
);
329 pString
= &Info
->GatewayList
;
330 while (NULL
!= pString
->Next
) {
331 pString
= pString
->Next
;
333 DlgData
->OldGateway
= inet_addr(pString
->IpAddress
.String
);
335 DlgData
->OldDns1
= INADDR_NONE
;
336 DlgData
->OldDns2
= INADDR_NONE
;
338 L
"SYSTEM\\CurrentControlSet\\Services\\TCPIP\\Parameters\\Interfaces\\%S",
340 if (ERROR_SUCCESS
== RegOpenKeyW(HKEY_LOCAL_MACHINE
, RegKey
, &hKey
)) {
342 RegQueryValueExA(hKey
, "NameServer", NULL
, &Type
, (BYTE
*)Dns
,
346 if ('\0' != Dns
[0]) {
347 DlgData
->OldDns1
= inet_addr(Dns
);
348 NextDnsServer
= strchr(Dns
, ',');
349 if (NULL
!= NextDnsServer
&& '\0' != *NextDnsServer
) {
350 DlgData
->OldDns2
= inet_addr(NextDnsServer
);
359 DisplayTCPIPProperties(HWND hParent
, IP_ADAPTER_INFO
*pInfo
)
361 PROPSHEETPAGEW psp
[1];
362 PROPSHEETHEADERW psh
;
363 INITCOMMONCONTROLSEX cce
;
364 TCPIP_PROPERTIES_DATA DlgData
;
366 if (! LoadDataFromInfo(&DlgData
, pInfo
))
368 ShowError(hParent
, IDS_CANNOT_LOAD_CONFIG
);
372 cce
.dwSize
= sizeof(INITCOMMONCONTROLSEX
);
373 cce
.dwICC
= ICC_INTERNET_CLASSES
;
374 InitCommonControlsEx(&cce
);
376 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
377 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
378 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_NOAPPLYNOW
;
379 psh
.hwndParent
= hParent
;
380 psh
.hInstance
= hApplet
;
381 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_CPLSYSTEM
));
382 psh
.pszCaption
= NULL
;//Caption;
383 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
386 psh
.pfnCallback
= NULL
;
388 InitPropSheetPage(&psp
[0], IDD_TCPIPPROPERTIES
, TCPIPPropertyPageProc
);
389 psp
[0].lParam
= (LPARAM
) &DlgData
;
391 if (PropertySheetW(&psh
) == -1)
393 ShowError(hParent
, IDS_CANNOT_CREATE_PROPSHEET
);