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