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