inet_addr returns address in network order, the IP address control wants it
[reactos.git] / reactos / lib / cpl / ncpa / tcpip_properties.c
1 /*
2 * ReactOS
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS Network Control Panel
22 * FILE: lib/cpl/system/tcpip_properties.c
23 * PURPOSE: ReactOS Network Control Panel
24 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
25 * UPDATE HISTORY:
26 * 08-15-2004 Created
27 */
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <tchar.h>
33 #include <windows.h>
34 #include <iptypes.h>
35 #include <iphlpapi.h>
36 #include <commctrl.h>
37 #include <dhcpcapi.h>
38 #include <prsht.h>
39
40
41 #ifdef _MSC_VER
42 #include <cpl.h>
43 #else
44
45 // this is missing on reactos...
46 #ifndef IPM_SETADDRESS
47 #define IPM_SETADDRESS (WM_USER+101)
48 #endif
49
50 #endif
51
52
53 #include "resource.h"
54 #include "ncpa.h"
55
56 void InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc);
57
58 static void
59 EnableDHCP( HWND hwndDlg, BOOL Enabled ) {
60 CheckDlgButton(hwndDlg,IDC_USEDHCP,Enabled ? BST_CHECKED : BST_UNCHECKED);
61 CheckDlgButton(hwndDlg,IDC_NODHCP,Enabled ? BST_UNCHECKED : BST_CHECKED);
62 }
63
64 static void
65 ManualDNS( HWND hwndDlg, BOOL Enabled ) {
66 CheckDlgButton(hwndDlg,IDC_FIXEDDNS,Enabled ? BST_CHECKED : BST_UNCHECKED);
67 CheckDlgButton(hwndDlg,IDC_AUTODNS,Enabled ? BST_UNCHECKED : BST_CHECKED);
68 EnableWindow(GetDlgItem(hwndDlg,IDC_DNS1),Enabled);
69 EnableWindow(GetDlgItem(hwndDlg,IDC_DNS2),Enabled);
70 }
71
72 static BOOL
73 GetAddressFromField( HWND hwndDlg, UINT CtlId,
74 DWORD *dwIPAddr,
75 const char **AddressString ) {
76 LRESULT lResult;
77 struct in_addr inIPAddr;
78
79 *AddressString = NULL;
80
81 lResult = SendMessage(GetDlgItem(hwndDlg, IDC_IPADDR), IPM_GETADDRESS, 0,
82 (ULONG_PTR)dwIPAddr);
83 if( lResult != 4 ) return FALSE;
84
85 inIPAddr.s_addr = *dwIPAddr;
86 *AddressString = inet_ntoa(inIPAddr);
87 if( !*AddressString ) return FALSE;
88
89 return TRUE;
90 }
91
92 static BOOL
93 InternTCPIPSettings( HWND hwndDlg ) {
94 PROPSHEETPAGE *pPage = (PROPSHEETPAGE *)GetWindowLongPtr(hwndDlg,GWL_USERDATA);
95 IP_ADAPTER_INFO *pInfo = NULL;
96 TCHAR pszRegKey[MAX_PATH];
97 HKEY hKey = NULL;
98 DWORD IpAddress, NetMask, Gateway;
99 const char *AddressString;
100 BOOL RetVal = FALSE;
101 BOOL DhcpEnabled = FALSE;
102 MIB_IPFORWARDROW RowToAdd = { 0 };
103
104 if(pPage)
105 pInfo = (IP_ADAPTER_INFO *)pPage->lParam;
106
107 if( !pPage || !pInfo ) goto cleanup;
108
109 _stprintf(pszRegKey,_T("SYSTEM\\CurrentControlSet\\Services\\TCPIP\\Parameters\\Interfaces\\%S"),pInfo->AdapterName);
110 if(RegOpenKey(HKEY_LOCAL_MACHINE,pszRegKey,&hKey)!=ERROR_SUCCESS) goto cleanup;
111
112 if( !GetAddressFromField
113 ( hwndDlg, IDC_IPADDR, &IpAddress, &AddressString ) ||
114 RegSetValueEx
115 ( hKey, _T("IPAddress"), 0, REG_SZ, (const BYTE*)AddressString,
116 strlen(AddressString) ) != ERROR_SUCCESS )
117 goto cleanup;
118
119 if( !GetAddressFromField
120 ( hwndDlg, IDC_SUBNETMASK, &NetMask, &AddressString ) ||
121 RegSetValueEx
122 ( hKey, _T("SubnetMask"), 0, REG_SZ, (const BYTE*)AddressString,
123 strlen(AddressString) ) != ERROR_SUCCESS )
124 goto cleanup;
125
126 if( DhcpEnabled ) /* FIXME - DhcpEnabled is never initialized at this point! */
127 DhcpLeaseIpAddress( pInfo->Index );
128 else {
129 DhcpReleaseIpAddressLease( pInfo->Index );
130 DhcpStaticRefreshParams( pInfo->Index, IpAddress, NetMask );
131 }
132
133 if( !GetAddressFromField
134 ( hwndDlg, IDC_DEFGATEWAY, &Gateway, &AddressString ) ||
135 RegSetValueEx
136 ( hKey, _T("DefaultGateway"), 0, REG_SZ, (const BYTE*)AddressString,
137 strlen(AddressString) ) != ERROR_SUCCESS )
138 goto cleanup;
139
140 /* If not on DHCP then add a default gateway, assuming one was specified */
141 if( !DhcpEnabled ) {
142 RowToAdd.dwForwardMask = 0;
143 RowToAdd.dwForwardMetric1 = 1;
144 RowToAdd.dwForwardNextHop = Gateway;
145 CreateIpForwardEntry( &RowToAdd );
146 }
147
148 cleanup:
149 if( hKey ) RegCloseKey( hKey );
150
151 return RetVal;
152 }
153
154 static INT_PTR CALLBACK
155 TCPIPPropertyPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
156 {
157 PROPSHEETPAGE *pPage = (PROPSHEETPAGE *)GetWindowLongPtr(hwndDlg,GWL_USERDATA);
158 IP_ADAPTER_INFO *pInfo = NULL;
159 int StaticDNS = 0;
160 char *NextDNSServer;
161
162 if(pPage)
163 pInfo = (IP_ADAPTER_INFO *)pPage->lParam;
164 switch(uMsg)
165 {
166 case WM_INITDIALOG:
167 {
168 pPage = (PROPSHEETPAGE *)lParam;
169 pInfo = (IP_ADAPTER_INFO *)pPage->lParam;
170 EnableWindow(GetDlgItem(hwndDlg,IDC_ADVANCED),FALSE);
171 SetWindowLongPtr(hwndDlg,GWL_USERDATA,(DWORD_PTR)pPage->lParam);
172
173 EnableDHCP( hwndDlg, pInfo->DhcpEnabled );
174
175 {
176 DWORD dwIPAddr;
177 IP_ADDR_STRING *pString;
178 pString = &pInfo->IpAddressList;
179 while(pString->Next)
180 pString = pString->Next;
181 dwIPAddr = inet_addr(pString->IpAddress.String);
182 SendDlgItemMessage(hwndDlg,IDC_IPADDR,IPM_SETADDRESS,0,
183 ntohl(dwIPAddr));
184 dwIPAddr = inet_addr(pString->IpMask.String);
185 SendDlgItemMessage(hwndDlg,IDC_SUBNETMASK,IPM_SETADDRESS,0,
186 ntohl(dwIPAddr));
187
188 pString = &pInfo->GatewayList;
189 while(pString->Next)
190 pString = pString->Next;
191 dwIPAddr = inet_addr(pString->IpAddress.String);
192 SendDlgItemMessage(hwndDlg,IDC_DEFGATEWAY,IPM_SETADDRESS,0,
193 ntohl(dwIPAddr));
194
195 }
196 {
197 TCHAR pszRegKey[MAX_PATH];
198 HKEY hKey;
199 _stprintf(pszRegKey,_T("SYSTEM\\CurrentControlSet\\Services\\TCPIP\\Parameters\\Interfaces\\%S"),pInfo->AdapterName);
200 if(RegOpenKey(HKEY_LOCAL_MACHINE,pszRegKey,&hKey)==ERROR_SUCCESS)
201 {
202 char pszDNS[MAX_PATH];
203 DWORD dwSize = sizeof(pszDNS);
204 DWORD dwType = REG_SZ;
205 DWORD dwIPAddr;
206 RegQueryValueExA(hKey,"NameServer",NULL,&dwType,(BYTE*)pszDNS,&dwSize);
207 RegCloseKey(hKey);
208
209 NextDNSServer = pszDNS;
210
211 while( NextDNSServer && StaticDNS < 2 ) {
212 dwIPAddr = inet_addr(NextDNSServer);
213 if( dwIPAddr != INADDR_NONE ) {
214 SendDlgItemMessage(hwndDlg,IDC_DNS1 + StaticDNS,
215 IPM_SETADDRESS,0,ntohl(dwIPAddr));
216 StaticDNS++;
217 }
218 NextDNSServer = strchr( pszDNS, ',' );
219 if( NextDNSServer )
220 NextDNSServer++;
221 }
222
223 ManualDNS( hwndDlg, StaticDNS );
224 }
225 }
226 }
227 break;
228 case WM_COMMAND:
229 switch(LOWORD(wParam))
230 {
231 case IDC_FIXEDDNS:
232 ManualDNS( hwndDlg, TRUE );
233 break;
234
235 case IDC_AUTODNS:
236 ManualDNS( hwndDlg, FALSE );
237 break;
238
239 case IDC_USEDHCP:
240 EnableDHCP( hwndDlg, TRUE );
241 break;
242
243 case IDC_NODHCP:
244 EnableDHCP( hwndDlg, FALSE );
245 break;
246
247 case IDOK:
248 /* Set the IP Address and DNS Information so we won't
249 * be doing all this for nothing */
250 InternTCPIPSettings( hwndDlg );
251 break;
252 }
253 break;
254 }
255 return FALSE;
256 }
257
258 void DisplayTCPIPProperties(HWND hParent,IP_ADAPTER_INFO *pInfo)
259 {
260 PROPSHEETPAGE psp[1];
261 PROPSHEETHEADER psh;
262 INITCOMMONCONTROLSEX cce;
263
264 cce.dwSize = sizeof(INITCOMMONCONTROLSEX);
265 cce.dwICC = ICC_INTERNET_CLASSES;
266 InitCommonControlsEx(&cce);
267
268 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
269 psh.dwSize = sizeof(PROPSHEETHEADER);
270 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
271 psh.hwndParent = hParent;
272 psh.hInstance = hApplet;
273 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
274 psh.pszCaption = NULL;//Caption;
275 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
276 psh.nStartPage = 0;
277 psh.ppsp = psp;
278 psh.pfnCallback = NULL;
279
280
281 InitPropSheetPage(&psp[0], IDD_TCPIPPROPERTIES, TCPIPPropertyPageProc);
282 psp[0].lParam = (LPARAM)pInfo;
283
284 if (PropertySheet(&psh) == -1)
285 {
286 MessageBox(hParent,_T("Unable to create property sheet"),_T("Error"),MB_ICONSTOP);
287 }
288
289 return;
290 }