Send a LBN_SELCHANGE notification after selecting the first network component entry...
[reactos.git] / reactos / dll / cpl / ncpa / ncpa.c
1 /*
2 * Copyright 2004 Gero Kuehn
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 /*
19 * PROJECT: ReactOS Network Control Panel
20 * FILE: lib/cpl/system/ncpa.c
21 * PURPOSE: ReactOS Network Control Panel
22 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
23 * UPDATE HISTORY:
24 * 07-18-2004 Created
25 */
26
27 /*
28 * Read this first !
29 *
30 * This file contains a first attempt for reactos network configuration
31 *
32 * - It is not complete.
33 * - It does not work the way it works on Windows.
34 *
35 * A lot of code that can be found here now, will probably be relocated into the OS core or some
36 * protocol Co-Installers or Notify Objects later when all the required COM
37 * and "netcfgx.dll" infrastructure (esp. headers and Interfaces) get implemented step by step.
38 *
39 * This code is only a first approach to provide a usable network configuration dialogs for
40 * the new network support in Reactos.
41 *
42 * If you intend to extend this code by more, please contact me to avoid duplicate work.
43 * There are already resources and code for TCP/IP configuration that are not
44 * mature enough for committing them to CVS yet.
45 */
46
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <stdarg.h>
50 #include <tchar.h>
51 #include <windows.h>
52 #include <iphlpapi.h>
53 #include <commctrl.h>
54 #include <cpl.h>
55
56 #include <debug.h>
57
58 #include "resource.h"
59 #include "ncpa.h"
60
61 #define NCF_VIRTUAL 0x1
62 #define NCF_SOFTWARE_ENUMERATED 0x2
63 #define NCF_PHYSICAL 0x4
64 #define NCF_HIDDEN 0x8
65 #define NCF_NO_SERVICE 0x10
66 #define NCF_NOT_USER_REMOVABLE 0x20
67 #define NCF_MULTIPORT_INSTANCED_ADAPTER 0x40
68 #define NCF_HAS_UI 0x80
69 #define NCF_FILTER 0x400
70 #define NCF_NDIS_PROTOCOL 0x4000
71
72 typedef void (ENUMREGKEYCALLBACK)(void *pCookie,HKEY hBaseKey,TCHAR *pszSubKey);
73
74 static LONG CALLBACK DisplayApplet(VOID);
75 static INT_PTR CALLBACK NetworkPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
76 void DisplayTCPIPProperties(HWND hParent,IP_ADAPTER_INFO *pInfo);
77
78 HINSTANCE hApplet = 0;
79
80 /* Applets */
81 static APPLET Applets[] =
82 {
83 {IDI_CPLSYSTEM, IDS_CPLSYSTEMNAME, IDS_CPLSYSTEMDESCRIPTION, DisplayApplet}
84 };
85
86
87 /* useful utilities */
88 static VOID
89 EnumRegKeys(ENUMREGKEYCALLBACK *pCallback,PVOID pCookie,HKEY hBaseKey,TCHAR *tpszRegPath)
90 {
91 HKEY hKey;
92 INT i;
93 LONG ret;
94 TCHAR tpszName[MAX_PATH];
95 DWORD dwNameLen = sizeof(tpszName);
96
97 if(RegOpenKeyEx(hBaseKey,tpszRegPath,0,KEY_ENUMERATE_SUB_KEYS,&hKey)!=ERROR_SUCCESS)
98 {
99 DPRINT("EnumRegKeys failed (key not found): %S\n", tpszRegPath);
100 return;
101 }
102
103 for(i=0;;i++)
104 {
105 TCHAR pszNewPath[MAX_PATH];
106 ret = RegEnumKeyEx(hKey,i,tpszName,&dwNameLen,NULL,NULL,NULL,NULL);
107 if(ret != ERROR_SUCCESS)
108 {
109 DPRINT("EnumRegKeys: RegEnumKeyEx failed for %S (rc 0x%lx)\n", tpszName, ret);
110 break;
111 }
112
113 _stprintf(pszNewPath,_T("%s\\%s"),tpszRegPath,tpszName);
114 DPRINT("EnumRegKeys: Calling user supplied enum function\n");
115 pCallback(pCookie,hBaseKey,pszNewPath);
116
117 dwNameLen = sizeof(tpszName);
118 }
119
120 RegCloseKey(hKey);
121 }
122
123 void
124 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc,LPARAM lParam)
125 {
126 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
127 psp->dwSize = sizeof(PROPSHEETPAGE);
128 psp->dwFlags = PSP_DEFAULT;
129 psp->hInstance = hApplet;
130 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
131 psp->pfnDlgProc = DlgProc;
132 psp->lParam = lParam;
133 }
134
135
136
137 static BOOL
138 FindNICClassKeyForCfgInstance(TCHAR *tpszCfgInst,TCHAR *tpszSubKeyOut)
139 {
140 int i;
141 TCHAR tpszSubKey[MAX_PATH];
142 TCHAR tpszCfgInst2[MAX_PATH];
143 HKEY hKey;
144 DWORD dwType,dwSize;
145
146 for (i = 0; i < 100; i++)
147 {
148 _stprintf(tpszSubKey,_T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%04d"),i);
149 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
150 continue;
151 dwType = REG_SZ;
152 dwSize = sizeof(tpszCfgInst2);
153 if(RegQueryValueEx(hKey,_T("NetCfgInstanceId"),NULL,&dwType,(BYTE*)tpszCfgInst2,&dwSize)!=ERROR_SUCCESS) {
154 RegCloseKey(hKey);
155 continue;
156 }
157 RegCloseKey(hKey);
158 if(_tcscmp(tpszCfgInst,tpszCfgInst2)==0) {
159 _tcscpy(tpszSubKeyOut,tpszSubKey);
160 return TRUE;
161 }
162 }
163 return FALSE;
164 }
165
166
167 static void
168 NICPropertyProtocolCallback(void *pCookie,HKEY hBaseKey,TCHAR *tpszSubKey)
169 {
170 HWND hwndDlg;
171 DWORD dwCharacteristics;
172 HKEY hKey,hNDIKey;
173 DWORD dwType,dwSize;
174 TCHAR tpszDescription[MAX_PATH];
175 TCHAR tpszNotifyObjectCLSID[MAX_PATH];
176 TCHAR *tpszSubKeyCopy;
177 int nIndex;
178
179 UNREFERENCED_PARAMETER(hBaseKey);
180
181 // CLSID CLSID_NotifObj;
182 // IUnknown *pUnk = NULL;
183 // INetCfgComponentControl *pNetCfg;
184 // INetCfgComponentPropertyUi *pNetCfgPropUI;
185 hwndDlg = (HWND)pCookie;
186
187 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
188 return;
189
190 dwType = REG_DWORD;
191 dwSize = sizeof(dwCharacteristics);
192 if(RegQueryValueEx(hKey,_T("Characteristics"),NULL,&dwType,(BYTE*)&dwCharacteristics,&dwSize)!= ERROR_SUCCESS)
193 return;
194
195 if(dwCharacteristics & NCF_HIDDEN)
196 {
197 RegCloseKey(hKey);
198 return;
199 }
200
201 dwType = REG_SZ;
202 dwSize = sizeof(tpszDescription);
203 if(RegQueryValueEx(hKey,_T("Description"),NULL,&dwType,(BYTE*)tpszDescription,&dwSize)!= ERROR_SUCCESS)
204 return;
205
206 RegOpenKeyEx(hKey,_T("Ndi"),0,KEY_QUERY_VALUE,&hNDIKey);
207 dwType = REG_SZ;
208 dwSize = sizeof(tpszNotifyObjectCLSID);
209 if(RegQueryValueEx(hNDIKey,_T("ClsId"),NULL,&dwType,(BYTE*)tpszNotifyObjectCLSID,&dwSize)!= ERROR_SUCCESS)
210 ;//return;
211
212 RegCloseKey(hNDIKey);
213
214 //
215 // This code works on Windows... but not on Reactos
216 //
217
218 // CLSIDFromString(tpszNotifyObjectCLSID,&CLSID_NotifObj);
219 // CoCreateInstance(&CLSID_NotifObj,NULL,CLSCTX_INPROC_SERVER,&IID_IUnknown,(void**)&pUnk);
220 // pUnk->lpVtbl->QueryInterface(pUnk,&IID_INetCfgComponentControl,(void**)&pNetCfg);
221 // pUnk->lpVtbl->QueryInterface(pUnk,&IID_INetCfgComponentPropertyUi,(void**)&pNetCfgPropUI);
222 {
223 /*
224 HRESULT hr;
225 hr = pNetCfg->lpVtbl->Initialize(pNetCfg,&NetCfgComponent,&NetCfg,FALSE);
226 hr = pNetCfgPropUI->lpVtbl->QueryPropertyUi(pNetCfgPropUI,(INetCfg*)&NetCfg);
227 hr = pNetCfgPropUI->lpVtbl->SetContext(pNetCfgPropUI,(INetCfg*)&NetCfgComponent);
228 DWORD dwNumPages = 10;
229 HPROPSHEETPAGE *bOut = NULL;
230 UINT nPages;
231 hr = pNetCfgPropUI->MergePropPages(&dwNumPages,(BYTE**)&bOut,&nPages,GetDesktopWindow(),NULL);
232 */
233 }
234
235 RegCloseKey(hKey);
236 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_COMPONENTSLIST,LB_ADDSTRING,0,(LPARAM)tpszDescription);
237 tpszSubKeyCopy = _tcsdup(tpszSubKey);
238 SendDlgItemMessage(hwndDlg,IDC_COMPONENTSLIST,LB_SETITEMDATA,nIndex,(LPARAM)tpszSubKeyCopy);
239 }
240
241
242
243 static INT_PTR CALLBACK
244 NICPropertyPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
245 {
246 PROPSHEETPAGE *pPage = (PROPSHEETPAGE *)GetWindowLongPtr(hwndDlg,GWL_USERDATA);
247 switch(uMsg)
248 {
249 case WM_INITDIALOG:
250 {
251 TCHAR *tpszCfgInstanceID;
252 DWORD dwType,dwSize;
253 TCHAR tpszSubKey[MAX_PATH];
254 TCHAR tpszDisplayName[MAX_PATH];
255 HKEY hKey;
256 pPage = (PROPSHEETPAGE *)lParam;
257 tpszCfgInstanceID = (TCHAR*)pPage->lParam;
258 if(!FindNICClassKeyForCfgInstance(tpszCfgInstanceID,tpszSubKey))
259 {
260 MessageBox(hwndDlg,_T("NIC Entry not found"),_T("Registry error"),MB_ICONSTOP);
261 MessageBox(hwndDlg,tpszCfgInstanceID,tpszSubKey,MB_ICONSTOP);
262 }
263
264 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
265 return 0;
266 dwType = REG_SZ;
267 dwSize = sizeof(tpszDisplayName);
268 if(RegQueryValueEx(hKey,_T("DriverDesc"),NULL,&dwType,(BYTE*)tpszDisplayName,&dwSize)!= ERROR_SUCCESS)
269 return 0;
270 RegCloseKey(hKey);
271
272 SetDlgItemText(hwndDlg,IDC_NETCARDNAME,tpszDisplayName);
273 EnableWindow(GetDlgItem(hwndDlg,IDC_CONFIGURE),FALSE);
274
275 SetWindowLongPtr(hwndDlg,GWL_USERDATA,(DWORD_PTR)lParam);
276 //SetDlgItemTextA(hwndDlg,IDC_NETCARDNAME,Info[pPage->lParam].Description);
277 EnumRegKeys(NICPropertyProtocolCallback,hwndDlg,HKEY_LOCAL_MACHINE,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E975-E325-11CE-BFC1-08002BE10318}"));
278
279 SendDlgItemMessage(hwndDlg, IDC_COMPONENTSLIST, LB_SETCURSEL, 0, 0);
280 SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_COMPONENTSLIST, LBN_SELCHANGE), 0);
281 }
282 break;
283 case WM_COMMAND:
284 switch(LOWORD(wParam))
285 {
286 case IDC_COMPONENTSLIST:
287 if(HIWORD(wParam)==LBN_SELCHANGE)
288 {
289 TCHAR *tpszSubKey;
290 TCHAR tpszHelpKey[MAX_PATH];
291 TCHAR tpszHelpText[MAX_PATH];
292 HKEY hNDIKey;
293 DWORD dwType,dwSize;
294 HWND hListBox = GetDlgItem(hwndDlg,IDC_COMPONENTSLIST);
295 tpszSubKey = (TCHAR*)SendMessage(hListBox,LB_GETITEMDATA,SendMessage(hListBox,LB_GETCURSEL,0,0),0);
296 if(!tpszSubKey)
297 break;
298 _stprintf(tpszHelpKey,_T("%s\\Ndi"),tpszSubKey);
299
300 RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszHelpKey,0,KEY_QUERY_VALUE,&hNDIKey);
301 dwType = REG_SZ;
302 dwSize = sizeof(tpszHelpText);
303 if(RegQueryValueEx(hNDIKey,_T("HelpText"),NULL,&dwType,(BYTE*)tpszHelpText,&dwSize)!= ERROR_SUCCESS)
304 ;//return;
305 RegCloseKey(hNDIKey);
306
307 SetDlgItemText(hwndDlg,IDC_DESCRIPTION,tpszHelpText);
308
309 }
310 if(HIWORD(wParam)!=LBN_DBLCLK)
311 break;
312 // drop though
313 case IDC_PROPERTIES:
314 {
315 TCHAR *tpszSubKey = NULL;
316 TCHAR tpszNDIKey[MAX_PATH];
317 TCHAR tpszClsIDText[MAX_PATH];
318 TCHAR *tpszTCPIPClsID = _T("{A907657F-6FDF-11D0-8EFB-00C04FD912B2}");
319 HKEY hNDIKey;
320 DWORD dwType,dwSize;
321 HWND hListBox = GetDlgItem(hwndDlg,IDC_COMPONENTSLIST);
322 int iListBoxIndex = (int) SendMessage(hListBox,LB_GETCURSEL,0,0);
323 if(iListBoxIndex != LB_ERR)
324 tpszSubKey = (TCHAR*)SendMessage(hListBox,LB_GETITEMDATA,iListBoxIndex,0);
325 if(!tpszSubKey)
326 break;
327 _stprintf(tpszNDIKey,_T("%s\\Ndi"),tpszSubKey);
328
329 RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszNDIKey,0,KEY_QUERY_VALUE,&hNDIKey);
330 dwSize = sizeof(tpszClsIDText);
331 if(RegQueryValueEx(hNDIKey,_T("ClsId"),NULL,&dwType,(BYTE*)tpszClsIDText,&dwSize)!= ERROR_SUCCESS || dwType != REG_SZ)
332 ;//return;
333 RegCloseKey(hNDIKey);
334
335 if(_tcscmp(tpszTCPIPClsID,tpszClsIDText)==0)
336 {
337 IP_ADAPTER_INFO Adapters[64];
338 IP_ADAPTER_INFO *pAdapter;
339 TCHAR *tpszCfgInstanceID;
340 ULONG ulSize = sizeof(Adapters);
341 memset(&Adapters,0x00,sizeof(Adapters));
342 if(GetAdaptersInfo(Adapters,&ulSize)!=ERROR_SUCCESS)
343 break;;
344 pAdapter = Adapters;
345 tpszCfgInstanceID = (TCHAR*)pPage->lParam;
346 while(pAdapter)
347 {
348 TCHAR tpszAdapterName[MAX_PATH];
349 swprintf(tpszAdapterName,L"%S",pAdapter->AdapterName);
350 DPRINT("IPHLPAPI returned: %S\n", tpszAdapterName);
351 if(_tcscmp(tpszAdapterName,tpszCfgInstanceID)==0)
352 {
353 DisplayTCPIPProperties(hwndDlg,pAdapter);
354 break;
355 } else
356 {
357 DPRINT("... which is not the TCPIP property sheet\n");
358 }
359 pAdapter = pAdapter->Next;
360 if(!pAdapter)
361 {
362 MessageBox(NULL,_T("If you see this, then the IPHLPAPI.DLL probably needs more work because GetAdaptersInfo did not return the expected data."),_T("Error"),MB_ICONSTOP);
363 }
364 }
365
366 } else
367 {
368 MessageBox(NULL,_T("This control panel is incomplete.\r\nUsually, the \"Notify Object\" for this Network component should be invoked here. Reactos lacks the infrastructure to do this right now.\r\n- C++\r\n- DDK Headers for notify objects\r\n- clean header structure, that allow Windows-Compatible COM C++ Code"),_T("Error"),MB_ICONSTOP);
369 }
370
371 }
372 break;
373 }
374 break;
375 }
376 return FALSE;
377 }
378
379
380 static void
381 DisplayNICProperties(HWND hParent,TCHAR *tpszCfgInstanceID)
382 {
383 PROPSHEETPAGE psp[1];
384 PROPSHEETHEADER psh;
385 TCHAR tpszSubKey[MAX_PATH];
386 HKEY hKey;
387 DWORD dwType = REG_SZ;
388 TCHAR tpszName[MAX_PATH];
389 DWORD dwSize = sizeof(tpszName);
390
391 // Get the "Name" for this Connection
392 _stprintf(tpszSubKey,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"),tpszCfgInstanceID);
393 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
394 return;
395 if(RegQueryValueEx(hKey,_T("Name"),NULL,&dwType,(BYTE*)tpszName,&dwSize)!=ERROR_SUCCESS)
396 _stprintf(tpszName,_T("[ERROR]"));
397 else
398 _tcscat(tpszName,_T(" Properties"));
399 RegCloseKey(hKey);
400
401
402 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
403 psh.dwSize = sizeof(PROPSHEETHEADER);
404 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
405 psh.hwndParent = hParent;
406 psh.hInstance = hApplet;
407 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
408 psh.pszCaption = tpszName;
409 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
410 psh.nStartPage = 0;
411 psh.ppsp = psp;
412 psh.pfnCallback = NULL;
413
414
415 InitPropSheetPage(&psp[0], IDD_NETPROPERTIES, NICPropertyPageProc,(LPARAM)tpszCfgInstanceID);
416 PropertySheet(&psh);
417 return;
418 }
419
420 static INT_PTR CALLBACK
421 NICStatusPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
422 {
423 switch(uMsg)
424 {
425 case WM_INITDIALOG:
426 {
427 PROPSHEETPAGE *psp= (PROPSHEETPAGE *)lParam;
428 EnableWindow(GetDlgItem(hwndDlg,IDC_ENDISABLE),FALSE);
429 SetWindowLongPtr(hwndDlg,DWL_USER,(DWORD_PTR)psp->lParam);
430 }
431 break;
432 case WM_COMMAND:
433 switch(LOWORD(wParam))
434 {
435 case IDC_PROPERTIES:
436 {
437 TCHAR *tpszCfgInstance;
438 tpszCfgInstance = (TCHAR*)GetWindowLong(hwndDlg,DWL_USER);
439 DisplayNICProperties(hwndDlg,tpszCfgInstance);
440 }
441 break;
442 }
443 break;
444 }
445 return FALSE;
446 }
447
448 static INT_PTR CALLBACK
449 NICSupportPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
450 {
451
452 switch(uMsg)
453 {
454 case WM_INITDIALOG:
455 {
456 TCHAR Buffer[64];
457
458 PIP_ADAPTER_INFO pAdapterInfo = NULL;
459 ULONG adaptOutBufLen;
460
461 DWORD ErrRet = 0;
462
463 pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );
464 adaptOutBufLen = sizeof(IP_ADAPTER_INFO);
465
466 if (GetAdaptersInfo( pAdapterInfo, &adaptOutBufLen) == ERROR_BUFFER_OVERFLOW)
467 {
468 free(pAdapterInfo);
469 pAdapterInfo = (IP_ADAPTER_INFO *) malloc (adaptOutBufLen);
470 }
471
472 if ((ErrRet = GetAdaptersInfo(pAdapterInfo, &adaptOutBufLen)) != NO_ERROR)
473 {
474 MessageBox(hwndDlg, _T("error adapterinfo") ,_T("ncpa.cpl"),MB_ICONSTOP);
475
476 if (pAdapterInfo) free(pAdapterInfo);
477 return FALSE;
478 }
479
480 if (pAdapterInfo)
481 {
482 /*FIXME: select the correct adapter info!!*/
483 _stprintf(Buffer, _T("%S"), pAdapterInfo->IpAddressList.IpAddress.String);
484 SendDlgItemMessage(hwndDlg, IDC_DETAILSIP, WM_SETTEXT, 0, (LPARAM)Buffer);
485 _stprintf(Buffer, _T("%S"), pAdapterInfo->IpAddressList.IpMask.String);
486 SendDlgItemMessage(hwndDlg, IDC_DETAILSSUBNET, WM_SETTEXT, 0, (LPARAM)Buffer);
487 _stprintf(Buffer, _T("%S"), pAdapterInfo->GatewayList.IpAddress.String);
488 SendDlgItemMessage(hwndDlg, IDC_DETAILSGATEWAY, WM_SETTEXT, 0, (LPARAM)Buffer);
489
490 free(pAdapterInfo);
491 }
492
493
494
495 }
496 break;
497 case WM_COMMAND:
498 switch(LOWORD(wParam))
499 {
500 case IDC_PROPERTIES:
501 {
502 }
503 break;
504 case IDC_DETAILS:
505 {
506 MessageBox(hwndDlg,_T("not implemented: show detail window"),_T("ncpa.cpl"),MB_ICONSTOP);
507 }
508 break;
509
510 }
511 break;
512 }
513 return FALSE;
514 }
515
516
517 static VOID
518 DisplayNICStatus(HWND hParent,TCHAR *tpszCfgInstanceID)
519 {
520 PROPSHEETPAGE psp[2];
521 PROPSHEETHEADER psh;
522 TCHAR tpszSubKey[MAX_PATH];
523 HKEY hKey;
524 DWORD dwType = REG_SZ;
525 TCHAR tpszName[MAX_PATH];
526 DWORD dwSize = sizeof(tpszName);
527
528 // Get the "Name" for this Connection
529 _stprintf(tpszSubKey,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"),tpszCfgInstanceID);
530 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
531 return;
532
533 if (RegQueryValueEx(hKey,_T("Name"),NULL,&dwType,(BYTE*)tpszName,&dwSize)!=ERROR_SUCCESS)
534 _stprintf(tpszName,_T("[ERROR]"));
535 //_stprintf(tpszName,_T("[ERROR]") _T(__FILE__) _T(" %d"),__LINE__ );
536 else
537 _tcscat(tpszName,_T(" Status"));
538 RegCloseKey(hKey);
539
540 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
541 psh.dwSize = sizeof(PROPSHEETHEADER);
542 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
543 psh.hwndParent = hParent;
544 psh.hInstance = hApplet;
545 // FIX THESE REACTOS HEADERS !!!!!!!!!
546 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
547 psh.pszCaption = tpszName;//Caption;
548 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
549 psh.nStartPage = 0;
550 psh.ppsp = psp;
551 psh.pfnCallback = NULL;
552
553 InitPropSheetPage(&psp[0], IDD_CARDPROPERTIES, NICStatusPageProc, (LPARAM)tpszCfgInstanceID);
554 InitPropSheetPage(&psp[1], IDD_CARDSUPPORT, NICSupportPageProc, (LPARAM)tpszCfgInstanceID);
555
556 PropertySheet(&psh);
557 return;
558 }
559
560 //
561 // IPHLPAPI does not provide a list of all adapters
562 //
563 #if 0
564 static VOID
565 EnumAdapters(HWND hwndDlg)
566 {
567 TCHAR pszText[MAX_ADAPTER_NAME_LENGTH + 4];
568 IP_ADAPTER_INFO *pInfo;
569 ULONG size;
570 INT nIndex;
571
572 size=sizeof(Info);
573 if(GetAdaptersInfo(Info,&size)!=ERROR_SUCCESS)
574 {
575 MessageBox(hwndDlg,L"IPHLPAPI.DLL failed to provide Adapter information",L"Error",MB_ICONSTOP);
576 return;
577 }
578
579 pInfo = &Info[0];
580 while(pInfo)
581 {
582 swprintf(pszText,L"%S",Info[0].Description);
583 nIndex = SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_ADDSTRING,0,(LPARAM)pszText);
584 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_SETITEMDATA,nIndex,(LPARAM)pInfo);
585 pInfo = pInfo->Next;
586 }
587 }
588 #endif
589
590
591
592 static void
593 NetAdapterCallback(void *pCookie,HKEY hBaseKey,TCHAR *tpszSubKey)
594 {
595 TCHAR tpszDisplayName[MAX_PATH];
596 //TCHAR tpszDeviceID[MAX_PATH];
597 TCHAR tpszCfgInstanceID[MAX_PATH];
598 TCHAR *ptpszCfgInstanceID;
599 HKEY hKey;
600 DWORD dwType = REG_SZ;
601 DWORD dwSize = sizeof(tpszDisplayName);
602 int nIndex;
603 HWND hwndDlg = (HWND)pCookie;
604 DWORD dwCharacteristics;
605
606 DPRINT("NetAdapterCallback: %S\n", tpszSubKey);
607
608 if(RegOpenKeyEx(hBaseKey,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
609 return;
610
611 DPRINT("NetAdapterCallback: Reading Characteristics\n");
612 dwType = REG_DWORD;
613 dwSize = sizeof(dwCharacteristics);
614 if(RegQueryValueEx(hKey,_T("Characteristics"),NULL,&dwType,(BYTE*)&dwCharacteristics,&dwSize)!=ERROR_SUCCESS)
615 dwCharacteristics = 0;
616
617 if (dwCharacteristics & NCF_HIDDEN)
618 return;
619
620 if (!(dwCharacteristics & NCF_VIRTUAL) && !(dwCharacteristics & NCF_PHYSICAL))
621 return;
622
623 DPRINT("NetAdapterCallback: Reading DriverDesc\n");
624 dwType = REG_SZ;
625 dwSize = sizeof(tpszDisplayName);
626 if (RegQueryValueEx(hKey,_T("DriverDesc"),NULL,&dwType,(BYTE*)tpszDisplayName,&dwSize)!= ERROR_SUCCESS)
627 _tcscpy(tpszDisplayName,_T("Unnamed Adapter"));
628
629 // get the link to the Enum Subkey (currently unused)
630 //dwType = REG_SZ;
631 //dwSize = sizeof(tpszDeviceID);
632 //if(RegQueryValueEx(hKey,_T("MatchingDeviceId"),NULL,&dwType,(BYTE*)tpszDeviceID,&dwSize) != ERROR_SUCCESS) {
633 // MessageBox(hwndDlg,_T("Missing MatchingDeviceId Entry"),_T("Registry Problem"),MB_ICONSTOP);
634 // return;
635 //}
636
637 // get the card configuration GUID
638 dwType = REG_SZ;
639 dwSize = sizeof(tpszCfgInstanceID);
640 if(RegQueryValueEx(hKey,_T("NetCfgInstanceId"),NULL,&dwType,(BYTE*)tpszCfgInstanceID,&dwSize) != ERROR_SUCCESS) {
641 MessageBox(hwndDlg,_T("Missing NetCfgInstanceId Entry"),_T("Registry Problem"),MB_ICONSTOP);
642 return;
643 }
644
645 ptpszCfgInstanceID = _tcsdup(tpszCfgInstanceID);
646 //
647 // **TODO** **FIXME** TBD
648 // At this point, we should verify, if the device listed here
649 // really represents a device that is currently connected to the system
650 //
651 // How is this done properly ?
652
653
654 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_ADDSTRING,0,(LPARAM)tpszDisplayName);
655 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_SETITEMDATA,nIndex,(LPARAM)ptpszCfgInstanceID);
656 RegCloseKey(hKey);
657 }
658
659
660 static void
661 EnumAdapters(HWND hwndDlg)
662 {
663 LPTSTR lpRegPath = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
664
665 EnumRegKeys(NetAdapterCallback,hwndDlg,HKEY_LOCAL_MACHINE,lpRegPath);
666 return;
667 }
668
669
670 static INT_PTR CALLBACK
671 NetworkPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
672 {
673 NMHDR* pnmh;
674 int nIndex;
675 switch(uMsg)
676 {
677 case WM_INITDIALOG:
678 {
679 EnableWindow(GetDlgItem(hwndDlg,IDC_ADD),FALSE);
680 EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVE),FALSE);
681
682 EnumAdapters(hwndDlg);
683 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_SETCURSEL,0,0);
684 }
685 break;
686
687 case WM_NOTIFY:
688 pnmh=(NMHDR*)lParam;
689 switch(pnmh->code)
690 {
691 case PSN_APPLY:
692 case PSN_RESET:
693 while(SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETCOUNT,0,0)>0)
694 {
695 TCHAR *tpszString;
696
697 tpszString = (TCHAR*)SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETITEMDATA,0,0);
698 if(tpszString)
699 free(tpszString);
700 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_DELETESTRING,0,0);
701 }
702 break;
703 }
704 break;
705
706 case WM_COMMAND:
707 switch(LOWORD(wParam))
708 {
709 case IDC_NETCARDLIST:
710 if(HIWORD(wParam)==LBN_DBLCLK) {
711 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETCURSEL,0,0);
712 if(nIndex!=-1)
713 DisplayNICStatus(hwndDlg,(TCHAR*)SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETITEMDATA,nIndex,0));
714 }
715 break;
716
717 case IDC_PROPERTIES:
718 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETCURSEL,0,0);
719 if(nIndex!=-1)
720 DisplayNICStatus(hwndDlg,(TCHAR*)SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETITEMDATA,nIndex,0));
721 break;
722 }
723 break;
724 }
725
726 return FALSE;
727 }
728
729
730
731 /* First Applet */
732 static LONG CALLBACK
733 DisplayApplet(VOID)
734 {
735 PROPSHEETPAGE psp[1];
736 PROPSHEETHEADER psh = {0};
737 TCHAR Caption[1024];
738
739 LoadString(hApplet, IDS_CPLSYSTEMNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
740
741 psh.dwSize = sizeof(PROPSHEETHEADER);
742 psh.dwFlags = PSH_PROPSHEETPAGE;
743 psh.hwndParent = NULL;
744 psh.hInstance = hApplet;
745 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
746 psh.pszCaption = Caption;
747 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
748 psh.nStartPage = 0;
749 psh.ppsp = psp;
750 psh.pfnCallback = NULL;
751
752 InitPropSheetPage(&psp[0], IDD_PROPPAGENETWORK, NetworkPageProc,0);
753
754 return (LONG)(PropertySheet(&psh) != -1);
755 }
756
757 /* Control Panel Callback */
758 LONG CALLBACK
759 CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
760 {
761 UNREFERENCED_PARAMETER(hwndCPl);
762 switch (uMsg)
763 {
764 case CPL_INIT:
765 {
766 return TRUE;
767 }
768
769 case CPL_GETCOUNT:
770 {
771 return sizeof(Applets)/sizeof(APPLET);
772 }
773
774 case CPL_INQUIRE:
775 {
776 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
777 CPlInfo->lData = 0;
778 CPlInfo->idIcon = Applets[(int)lParam1].idIcon;
779 CPlInfo->idName = Applets[(int)lParam1].idName;
780 CPlInfo->idInfo = Applets[(int)lParam1].idDescription;
781 break;
782 }
783
784 case CPL_DBLCLK:
785 {
786 Applets[(int)lParam1].AppletProc();
787 break;
788 }
789 }
790
791 return FALSE;
792 }
793
794
795 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
796 {
797 UNREFERENCED_PARAMETER(lpvReserved);
798
799 switch(dwReason)
800 {
801 case DLL_PROCESS_ATTACH:
802 case DLL_THREAD_ATTACH:
803 hApplet = hinstDLL;
804 break;
805 }
806
807 return TRUE;
808 }
809
810