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