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