-fixed some msvc /W4 warnings and errors
[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
62 #define NCF_HIDDEN 0x08
63 #define NCF_HAS_UI 0x80
64
65 typedef void (ENUMREGKEYCALLBACK)(void *pCookie,HKEY hBaseKey,TCHAR *pszSubKey);
66
67 static LONG CALLBACK DisplayApplet(VOID);
68 static INT_PTR CALLBACK NetworkPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
69 void DisplayTCPIPProperties(HWND hParent,IP_ADAPTER_INFO *pInfo);
70
71 HINSTANCE hApplet = 0;
72
73 /* Applets */
74 static APPLET Applets[] =
75 {
76 {IDI_CPLSYSTEM, IDS_CPLSYSTEMNAME, IDS_CPLSYSTEMDESCRIPTION, DisplayApplet}
77 };
78
79
80
81 /* useful utilities */
82 static VOID
83 EnumRegKeys(ENUMREGKEYCALLBACK *pCallback,PVOID pCookie,HKEY hBaseKey,TCHAR *tpszRegPath)
84 {
85 HKEY hKey;
86 INT i;
87 LONG ret;
88 TCHAR tpszName[MAX_PATH];
89 DWORD dwNameLen = sizeof(tpszName);
90
91 if(RegOpenKeyEx(hBaseKey,tpszRegPath,0,KEY_ENUMERATE_SUB_KEYS,&hKey)!=ERROR_SUCCESS)
92 {
93 DPRINT("EnumRegKeys failed (key not found): %S\n", tpszRegPath);
94 return;
95 }
96
97 for(i=0;;i++)
98 {
99 TCHAR pszNewPath[MAX_PATH];
100 ret = RegEnumKeyEx(hKey,i,tpszName,&dwNameLen,NULL,NULL,NULL,NULL);
101 if(ret != ERROR_SUCCESS)
102 {
103 DPRINT("EnumRegKeys: RegEnumKeyEx failed for %S (rc 0x%lx)\n", tpszName, ret);
104 break;
105 }
106
107 _stprintf(pszNewPath,_T("%s\\%s"),tpszRegPath,tpszName);
108 DPRINT("EnumRegKeys: Calling user supplied enum function\n");
109 pCallback(pCookie,hBaseKey,pszNewPath);
110
111 dwNameLen = sizeof(tpszName);
112 }
113
114 RegCloseKey(hKey);
115 }
116
117 void
118 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DLGPROC DlgProc,LPARAM lParam)
119 {
120 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
121 psp->dwSize = sizeof(PROPSHEETPAGE);
122 psp->dwFlags = PSP_DEFAULT;
123 psp->hInstance = hApplet;
124 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
125 psp->pfnDlgProc = DlgProc;
126 psp->lParam = lParam;
127 }
128
129
130
131 static BOOL
132 FindNICClassKeyForCfgInstance(TCHAR *tpszCfgInst,TCHAR *tpszSubKeyOut)
133 {
134 int i;
135 TCHAR tpszSubKey[MAX_PATH];
136 TCHAR tpszCfgInst2[MAX_PATH];
137 HKEY hKey;
138 DWORD dwType,dwSize;
139
140 for (i = 0; i < 100; i++)
141 {
142 _stprintf(tpszSubKey,_T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%04d"),i);
143 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
144 continue;
145 dwType = REG_SZ;
146 dwSize = sizeof(tpszCfgInst2);
147 if(RegQueryValueEx(hKey,_T("NetCfgInstanceId"),NULL,&dwType,(BYTE*)tpszCfgInst2,&dwSize)!=ERROR_SUCCESS) {
148 RegCloseKey(hKey);
149 continue;
150 }
151 RegCloseKey(hKey);
152 if(_tcscmp(tpszCfgInst,tpszCfgInst2)==0) {
153 _tcscpy(tpszSubKeyOut,tpszSubKey);
154 return TRUE;
155 }
156 }
157 return FALSE;
158 }
159
160
161 static void
162 NICPropertyProtocolCallback(void *pCookie,HKEY hBaseKey,TCHAR *tpszSubKey)
163 {
164 HWND hwndDlg;
165 DWORD dwCharacteristics;
166 HKEY hKey,hNDIKey;
167 DWORD dwType,dwSize;
168 TCHAR tpszDescription[MAX_PATH];
169 TCHAR tpszNotifyObjectCLSID[MAX_PATH];
170 TCHAR *tpszSubKeyCopy;
171 int nIndex;
172
173 UNREFERENCED_PARAMETER(hBaseKey);
174
175 // CLSID CLSID_NotifObj;
176 // IUnknown *pUnk = NULL;
177 // INetCfgComponentControl *pNetCfg;
178 // INetCfgComponentPropertyUi *pNetCfgPropUI;
179 hwndDlg = (HWND)pCookie;
180
181 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
182 return;
183
184 dwType = REG_DWORD;
185 dwSize = sizeof(dwCharacteristics);
186 if(RegQueryValueEx(hKey,_T("Characteristics"),NULL,&dwType,(BYTE*)&dwCharacteristics,&dwSize)!= ERROR_SUCCESS)
187 return;
188
189 if(dwCharacteristics & NCF_HIDDEN)
190 {
191 RegCloseKey(hKey);
192 return;
193 }
194
195 dwType = REG_SZ;
196 dwSize = sizeof(tpszDescription);
197 if(RegQueryValueEx(hKey,_T("Description"),NULL,&dwType,(BYTE*)tpszDescription,&dwSize)!= ERROR_SUCCESS)
198 return;
199
200 RegOpenKeyEx(hKey,_T("Ndi"),0,KEY_QUERY_VALUE,&hNDIKey);
201 dwType = REG_SZ;
202 dwSize = sizeof(tpszNotifyObjectCLSID);
203 if(RegQueryValueEx(hNDIKey,_T("ClsId"),NULL,&dwType,(BYTE*)tpszNotifyObjectCLSID,&dwSize)!= ERROR_SUCCESS)
204 ;//return;
205
206 RegCloseKey(hNDIKey);
207
208 //
209 // This code works on Windows... but not on Reactos
210 //
211
212 // CLSIDFromString(tpszNotifyObjectCLSID,&CLSID_NotifObj);
213 // CoCreateInstance(&CLSID_NotifObj,NULL,CLSCTX_INPROC_SERVER,&IID_IUnknown,(void**)&pUnk);
214 // pUnk->lpVtbl->QueryInterface(pUnk,&IID_INetCfgComponentControl,(void**)&pNetCfg);
215 // pUnk->lpVtbl->QueryInterface(pUnk,&IID_INetCfgComponentPropertyUi,(void**)&pNetCfgPropUI);
216 {
217 /*
218 HRESULT hr;
219 hr = pNetCfg->lpVtbl->Initialize(pNetCfg,&NetCfgComponent,&NetCfg,FALSE);
220 hr = pNetCfgPropUI->lpVtbl->QueryPropertyUi(pNetCfgPropUI,(INetCfg*)&NetCfg);
221 hr = pNetCfgPropUI->lpVtbl->SetContext(pNetCfgPropUI,(INetCfg*)&NetCfgComponent);
222 DWORD dwNumPages = 10;
223 HPROPSHEETPAGE *bOut = NULL;
224 UINT nPages;
225 hr = pNetCfgPropUI->MergePropPages(&dwNumPages,(BYTE**)&bOut,&nPages,GetDesktopWindow(),NULL);
226 */
227 }
228
229 RegCloseKey(hKey);
230 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_COMPONENTSLIST,LB_ADDSTRING,0,(LPARAM)tpszDescription);
231 tpszSubKeyCopy = _tcsdup(tpszSubKey);
232 SendDlgItemMessage(hwndDlg,IDC_COMPONENTSLIST,LB_SETITEMDATA,nIndex,(LPARAM)tpszSubKeyCopy);
233 }
234
235
236
237 static INT_PTR CALLBACK
238 NICPropertyPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
239 {
240 PROPSHEETPAGE *pPage = (PROPSHEETPAGE *)GetWindowLongPtr(hwndDlg,GWL_USERDATA);
241 switch(uMsg)
242 {
243 case WM_INITDIALOG:
244 {
245 TCHAR *tpszCfgInstanceID;
246 DWORD dwType,dwSize;
247 TCHAR tpszSubKey[MAX_PATH];
248 TCHAR tpszDisplayName[MAX_PATH];
249 HKEY hKey;
250 pPage = (PROPSHEETPAGE *)lParam;
251 tpszCfgInstanceID = (TCHAR*)pPage->lParam;
252 if(!FindNICClassKeyForCfgInstance(tpszCfgInstanceID,tpszSubKey))
253 {
254 MessageBox(hwndDlg,_T("NIC Entry not found"),_T("Registry error"),MB_ICONSTOP);
255 MessageBox(hwndDlg,tpszCfgInstanceID,tpszSubKey,MB_ICONSTOP);
256 }
257
258 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
259 return 0;
260 dwType = REG_SZ;
261 dwSize = sizeof(tpszDisplayName);
262 if(RegQueryValueEx(hKey,_T("DriverDesc"),NULL,&dwType,(BYTE*)tpszDisplayName,&dwSize)!= ERROR_SUCCESS)
263 return 0;
264 RegCloseKey(hKey);
265
266 SetDlgItemText(hwndDlg,IDC_NETCARDNAME,tpszDisplayName);
267 EnableWindow(GetDlgItem(hwndDlg,IDC_CONFIGURE),FALSE);
268
269 SetWindowLongPtr(hwndDlg,GWL_USERDATA,(DWORD_PTR)lParam);
270 //SetDlgItemTextA(hwndDlg,IDC_NETCARDNAME,Info[pPage->lParam].Description);
271 EnumRegKeys(NICPropertyProtocolCallback,hwndDlg,HKEY_LOCAL_MACHINE,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E975-E325-11CE-BFC1-08002BE10318}"));
272
273 SendDlgItemMessage(hwndDlg, IDC_COMPONENTSLIST, LB_SETCURSEL, 0, 0);
274 }
275 break;
276 case WM_COMMAND:
277 switch(LOWORD(wParam))
278 {
279 case IDC_COMPONENTSLIST:
280 if(HIWORD(wParam)==LBN_SELCHANGE)
281 {
282 TCHAR *tpszSubKey;
283 TCHAR tpszHelpKey[MAX_PATH];
284 TCHAR tpszHelpText[MAX_PATH];
285 HKEY hNDIKey;
286 DWORD dwType,dwSize;
287 HWND hListBox = GetDlgItem(hwndDlg,IDC_COMPONENTSLIST);
288 tpszSubKey = (TCHAR*)SendMessage(hListBox,LB_GETITEMDATA,SendMessage(hListBox,LB_GETCURSEL,0,0),0);
289 if(!tpszSubKey)
290 break;
291 _stprintf(tpszHelpKey,_T("%s\\Ndi"),tpszSubKey);
292
293 RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszHelpKey,0,KEY_QUERY_VALUE,&hNDIKey);
294 dwType = REG_SZ;
295 dwSize = sizeof(tpszHelpText);
296 if(RegQueryValueEx(hNDIKey,_T("HelpText"),NULL,&dwType,(BYTE*)tpszHelpText,&dwSize)!= ERROR_SUCCESS)
297 ;//return;
298 RegCloseKey(hNDIKey);
299
300 SetDlgItemText(hwndDlg,IDC_DESCRIPTION,tpszHelpText);
301
302 }
303 if(HIWORD(wParam)!=LBN_DBLCLK)
304 break;
305 // drop though
306 case IDC_PROPERTIES:
307 {
308 TCHAR *tpszSubKey = NULL;
309 TCHAR tpszNDIKey[MAX_PATH];
310 TCHAR tpszClsIDText[MAX_PATH];
311 TCHAR *tpszTCPIPClsID = _T("{A907657F-6FDF-11D0-8EFB-00C04FD912B2}");
312 HKEY hNDIKey;
313 DWORD dwType,dwSize;
314 HWND hListBox = GetDlgItem(hwndDlg,IDC_COMPONENTSLIST);
315 int iListBoxIndex = (int) SendMessage(hListBox,LB_GETCURSEL,0,0);
316 if(iListBoxIndex != LB_ERR)
317 tpszSubKey = (TCHAR*)SendMessage(hListBox,LB_GETITEMDATA,iListBoxIndex,0);
318 if(!tpszSubKey)
319 break;
320 _stprintf(tpszNDIKey,_T("%s\\Ndi"),tpszSubKey);
321
322 RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszNDIKey,0,KEY_QUERY_VALUE,&hNDIKey);
323 dwSize = sizeof(tpszClsIDText);
324 if(RegQueryValueEx(hNDIKey,_T("ClsId"),NULL,&dwType,(BYTE*)tpszClsIDText,&dwSize)!= ERROR_SUCCESS || dwType != REG_SZ)
325 ;//return;
326 RegCloseKey(hNDIKey);
327
328 if(_tcscmp(tpszTCPIPClsID,tpszClsIDText)==0)
329 {
330 IP_ADAPTER_INFO Adapters[64];
331 IP_ADAPTER_INFO *pAdapter;
332 TCHAR *tpszCfgInstanceID;
333 DWORD dwSize = sizeof(Adapters);
334 memset(&Adapters,0x00,sizeof(Adapters));
335 if(GetAdaptersInfo(Adapters,&dwSize)!=ERROR_SUCCESS)
336 break;;
337 pAdapter = Adapters;
338 tpszCfgInstanceID = (TCHAR*)pPage->lParam;
339 while(pAdapter)
340 {
341 TCHAR tpszAdatperName[MAX_PATH];
342 swprintf(tpszAdatperName,L"%S",pAdapter->AdapterName);
343 DPRINT("IPHLPAPI returned: %S\n", tpszAdatperName);
344 if(_tcscmp(tpszAdatperName,tpszCfgInstanceID)==0)
345 {
346 DisplayTCPIPProperties(hwndDlg,pAdapter);
347 break;
348 } else
349 {
350 DPRINT("... which is not the TCPIP property sheet\n");
351 }
352 pAdapter = pAdapter->Next;
353 if(!pAdapter)
354 {
355 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);
356 }
357 }
358
359 } else
360 {
361 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);
362 }
363
364 }
365 break;
366 }
367 break;
368 }
369 return FALSE;
370 }
371
372
373 static void
374 DisplayNICProperties(HWND hParent,TCHAR *tpszCfgInstanceID)
375 {
376 PROPSHEETPAGE psp[1];
377 PROPSHEETHEADER psh;
378 TCHAR tpszSubKey[MAX_PATH];
379 HKEY hKey;
380 DWORD dwType = REG_SZ;
381 TCHAR tpszName[MAX_PATH];
382 DWORD dwSize = sizeof(tpszName);
383
384 // Get the "Name" for this Connection
385 _stprintf(tpszSubKey,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"),tpszCfgInstanceID);
386 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
387 return;
388 if(RegQueryValueEx(hKey,_T("Name"),NULL,&dwType,(BYTE*)tpszName,&dwSize)!=ERROR_SUCCESS)
389 _stprintf(tpszName,_T("[ERROR]"));
390 else
391 _tcscat(tpszName,_T(" Properties"));
392 RegCloseKey(hKey);
393
394
395 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
396 psh.dwSize = sizeof(PROPSHEETHEADER);
397 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
398 psh.hwndParent = hParent;
399 psh.hInstance = hApplet;
400 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
401 psh.pszCaption = tpszName;
402 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
403 psh.nStartPage = 0;
404 psh.ppsp = psp;
405 psh.pfnCallback = NULL;
406
407
408 InitPropSheetPage(&psp[0], IDD_NETPROPERTIES, NICPropertyPageProc,(LPARAM)tpszCfgInstanceID);
409 PropertySheet(&psh);
410 return;
411 }
412
413
414
415 static INT_PTR CALLBACK
416 NICStatusPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
417 {
418 switch(uMsg)
419 {
420 case WM_INITDIALOG:
421 {
422 PROPSHEETPAGE *psp= (PROPSHEETPAGE *)lParam;
423 EnableWindow(GetDlgItem(hwndDlg,IDC_ENDISABLE),FALSE);
424 SetWindowLongPtr(hwndDlg,DWL_USER,(DWORD_PTR)psp->lParam);
425 }
426 break;
427 case WM_COMMAND:
428 switch(LOWORD(wParam))
429 {
430 case IDC_PROPERTIES:
431 {
432 TCHAR *tpszCfgInstance;
433 tpszCfgInstance = (TCHAR*)GetWindowLong(hwndDlg,DWL_USER);
434 DisplayNICProperties(hwndDlg,tpszCfgInstance);
435 }
436 break;
437 }
438 break;
439 }
440 return FALSE;
441 }
442
443 static VOID
444 DisplayNICStatus(HWND hParent,TCHAR *tpszCfgInstanceID)
445 {
446 PROPSHEETPAGE psp[1];
447 PROPSHEETHEADER psh;
448 TCHAR tpszSubKey[MAX_PATH];
449 HKEY hKey;
450 DWORD dwType = REG_SZ;
451 TCHAR tpszName[MAX_PATH];
452 DWORD dwSize = sizeof(tpszName);
453
454 // Get the "Name" for this Connection
455 _stprintf(tpszSubKey,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"),tpszCfgInstanceID);
456 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
457 return;
458
459 if (RegQueryValueEx(hKey,_T("Name"),NULL,&dwType,(BYTE*)tpszName,&dwSize)!=ERROR_SUCCESS)
460 _stprintf(tpszName,_T("[ERROR]"));
461 //_stprintf(tpszName,_T("[ERROR]") _T(__FILE__) _T(" %d"),__LINE__ );
462 else
463 _tcscat(tpszName,_T(" Status"));
464 RegCloseKey(hKey);
465
466 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
467 psh.dwSize = sizeof(PROPSHEETHEADER);
468 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
469 psh.hwndParent = hParent;
470 psh.hInstance = hApplet;
471 // FIX THESE REACTOS HEADERS !!!!!!!!!
472 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
473 psh.pszCaption = tpszName;//Caption;
474 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
475 psh.nStartPage = 0;
476 psh.ppsp = psp;
477 psh.pfnCallback = NULL;
478
479
480 InitPropSheetPage(&psp[0], IDD_CARDPROPERTIES, NICStatusPageProc,(LPARAM)tpszCfgInstanceID);
481 PropertySheet(&psh);
482 return;
483 }
484
485 //
486 // IPHLPAPI does not provide a list of all adapters
487 //
488 #if 0
489 static VOID
490 EnumAdapters(HWND hwndDlg)
491 {
492 TCHAR pszText[MAX_ADAPTER_NAME_LENGTH + 4];
493 IP_ADAPTER_INFO *pInfo;
494 ULONG size;
495 INT nIndex;
496
497 size=sizeof(Info);
498 if(GetAdaptersInfo(Info,&size)!=ERROR_SUCCESS)
499 {
500 MessageBox(hwndDlg,L"IPHLPAPI.DLL failed to provide Adapter information",L"Error",MB_ICONSTOP);
501 return;
502 }
503
504 pInfo = &Info[0];
505 while(pInfo)
506 {
507 swprintf(pszText,L"%S",Info[0].Description);
508 nIndex = SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_ADDSTRING,0,(LPARAM)pszText);
509 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_SETITEMDATA,nIndex,(LPARAM)pInfo);
510 pInfo = pInfo->Next;
511 }
512 }
513 #endif
514
515
516
517 static void
518 NetAdapterCallback(void *pCookie,HKEY hBaseKey,TCHAR *tpszSubKey)
519 {
520 TCHAR tpszDisplayName[MAX_PATH];
521 //TCHAR tpszDeviceID[MAX_PATH];
522 TCHAR tpszCfgInstanceID[MAX_PATH];
523 TCHAR *ptpszCfgInstanceID;
524 HKEY hKey;
525 DWORD dwType = REG_SZ;
526 DWORD dwSize = sizeof(tpszDisplayName);
527 int nIndex;
528 HWND hwndDlg = (HWND)pCookie;
529 DWORD dwCharacteristics;
530
531 DPRINT("NetAdapterCallback: %S\n", tpszSubKey);
532 if(RegOpenKeyEx(hBaseKey,tpszSubKey,0,KEY_QUERY_VALUE,&hKey)!=ERROR_SUCCESS)
533 return;
534
535 DPRINT("NetAdapterCallback: Reading Characteristics\n");
536 dwType = REG_DWORD;
537 dwSize = sizeof(dwCharacteristics);
538 if(RegQueryValueEx(hKey,_T("Characteristics"),NULL,&dwType,(BYTE*)&dwCharacteristics,&dwSize)!=ERROR_SUCCESS)
539 dwCharacteristics = 0;
540
541
542 if (dwCharacteristics & NCF_HIDDEN)
543 return;
544 // if (!(dwCharacteristics & NCF_HAS_UI))
545 // return;
546
547 DPRINT("NetAdapterCallback: Reading DriverDesc\n");
548 dwType = REG_SZ;
549 dwSize = sizeof(tpszDisplayName);
550 if (RegQueryValueEx(hKey,_T("DriverDesc"),NULL,&dwType,(BYTE*)tpszDisplayName,&dwSize)!= ERROR_SUCCESS)
551 _tcscpy(tpszDisplayName,_T("Unnamed Adapter"));
552
553 // get the link to the Enum Subkey (currently unused)
554 //dwType = REG_SZ;
555 //dwSize = sizeof(tpszDeviceID);
556 //if(RegQueryValueEx(hKey,_T("MatchingDeviceId"),NULL,&dwType,(BYTE*)tpszDeviceID,&dwSize) != ERROR_SUCCESS) {
557 // MessageBox(hwndDlg,_T("Missing MatchingDeviceId Entry"),_T("Registry Problem"),MB_ICONSTOP);
558 // return;
559 //}
560
561 // get the card configuration GUID
562 dwType = REG_SZ;
563 dwSize = sizeof(tpszCfgInstanceID);
564 if(RegQueryValueEx(hKey,_T("NetCfgInstanceId"),NULL,&dwType,(BYTE*)tpszCfgInstanceID,&dwSize) != ERROR_SUCCESS) {
565 MessageBox(hwndDlg,_T("Missing NetCfgInstanceId Entry"),_T("Registry Problem"),MB_ICONSTOP);
566 return;
567 }
568
569 ptpszCfgInstanceID = _tcsdup(tpszCfgInstanceID);
570 //
571 // **TODO** **FIXME** TBD
572 // At this point, we should verify, if the device listed here
573 // really represents a device that is currently connected to the system
574 //
575 // How is this done properly ?
576
577
578 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_ADDSTRING,0,(LPARAM)tpszDisplayName);
579 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_SETITEMDATA,nIndex,(LPARAM)ptpszCfgInstanceID);
580 RegCloseKey(hKey);
581 }
582
583
584 static void
585 EnumAdapters(HWND hwndDlg)
586 {
587 LPTSTR lpRegPath = _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
588
589 EnumRegKeys(NetAdapterCallback,hwndDlg,HKEY_LOCAL_MACHINE,lpRegPath);
590 return;
591 }
592
593
594 static INT_PTR CALLBACK
595 NetworkPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
596 {
597 NMHDR* pnmh;
598 int nIndex;
599 switch(uMsg)
600 {
601 case WM_INITDIALOG:
602 {
603 EnableWindow(GetDlgItem(hwndDlg,IDC_ADD),FALSE);
604 EnableWindow(GetDlgItem(hwndDlg,IDC_REMOVE),FALSE);
605
606 EnumAdapters(hwndDlg);
607 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_SETCURSEL,0,0);
608 }
609 break;
610
611 case WM_NOTIFY:
612 pnmh=(NMHDR*)lParam;
613 switch(pnmh->code)
614 {
615 case PSN_APPLY:
616 case PSN_RESET:
617 while(SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETCOUNT,0,0)>0)
618 {
619 TCHAR *tpszString;
620
621 tpszString = (TCHAR*)SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETITEMDATA,0,0);
622 if(tpszString)
623 free(tpszString);
624 SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_DELETESTRING,0,0);
625 }
626 break;
627 }
628 break;
629
630 case WM_COMMAND:
631 switch(LOWORD(wParam))
632 {
633 case IDC_NETCARDLIST:
634 if(HIWORD(wParam)==LBN_DBLCLK) {
635 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETCURSEL,0,0);
636 if(nIndex!=-1)
637 DisplayNICStatus(hwndDlg,(TCHAR*)SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETITEMDATA,nIndex,0));
638 }
639 break;
640
641 case IDC_PROPERTIES:
642 nIndex = (int) SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETCURSEL,0,0);
643 if(nIndex!=-1)
644 DisplayNICStatus(hwndDlg,(TCHAR*)SendDlgItemMessage(hwndDlg,IDC_NETCARDLIST,LB_GETITEMDATA,nIndex,0));
645 break;
646 }
647 break;
648 }
649
650 return FALSE;
651 }
652
653
654
655 /* First Applet */
656 static LONG CALLBACK
657 DisplayApplet(VOID)
658 {
659 PROPSHEETPAGE psp[1];
660 PROPSHEETHEADER psh = {0};
661 TCHAR Caption[1024];
662
663 LoadString(hApplet, IDS_CPLSYSTEMNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
664
665 psh.dwSize = sizeof(PROPSHEETHEADER);
666 psh.dwFlags = PSH_PROPSHEETPAGE;
667 psh.hwndParent = NULL;
668 psh.hInstance = hApplet;
669 psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDI_CPLSYSTEM));
670 psh.pszCaption = Caption;
671 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
672 psh.nStartPage = 0;
673 psh.ppsp = psp;
674 psh.pfnCallback = NULL;
675
676 InitPropSheetPage(&psp[0], IDD_PROPPAGENETWORK, NetworkPageProc,0);
677
678 return (LONG)(PropertySheet(&psh) != -1);
679 }
680
681 /* Control Panel Callback */
682 LONG CALLBACK
683 CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
684 {
685 UNREFERENCED_PARAMETER(hwndCPl);
686 switch (uMsg)
687 {
688 case CPL_INIT:
689 {
690 return TRUE;
691 }
692
693 case CPL_GETCOUNT:
694 {
695 return sizeof(Applets)/sizeof(APPLET);
696 }
697
698 case CPL_INQUIRE:
699 {
700 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
701 CPlInfo->lData = 0;
702 CPlInfo->idIcon = Applets[(int)lParam1].idIcon;
703 CPlInfo->idName = Applets[(int)lParam1].idName;
704 CPlInfo->idInfo = Applets[(int)lParam1].idDescription;
705 break;
706 }
707
708 case CPL_DBLCLK:
709 {
710 Applets[(int)lParam1].AppletProc();
711 break;
712 }
713 }
714
715 return FALSE;
716 }
717
718
719 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
720 {
721 UNREFERENCED_PARAMETER(lpvReserved);
722
723 switch(dwReason)
724 {
725 case DLL_PROCESS_ATTACH:
726 case DLL_THREAD_ATTACH:
727 hApplet = hinstDLL;
728 break;
729 }
730
731 return TRUE;
732 }
733