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