2 * Copyright 2004 Gero Kuehn
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.
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.
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
19 * PROJECT: ReactOS Network Control Panel
20 * FILE: lib/cpl/system/ncpa.c
21 * PURPOSE: ReactOS Network Control Panel
22 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
30 * This file contains a first attempt for reactos network configuration
32 * - It is not complete.
33 * - It does not work the way it works on Windows.
35 * A lot of code that can be found here now, will probably be relocated into the OS core or some
36 * protocol Co-Installers or Notify Objects later when all the required COM
37 * and "netcfgx.dll" infrastructure (esp. headers and Interfaces) get implemented step by step.
39 * This code is only a first approach to provide a usable network configuration dialogs for
40 * the new network support in Reactos.
42 * If you intend to extend this code by more, please contact me to avoid duplicate work.
43 * There are already resources and code for TCP/IP configuration that are not
44 * mature enough for committing them to CVS yet.
56 #include <wine/debug.h>
57 WINE_DEFAULT_DEBUG_CHANNEL(ncpa
);
59 #define debugstr_aw debugstr_a
61 #define debugstr_aw debugstr_w
67 #define NCF_VIRTUAL 0x1
68 #define NCF_SOFTWARE_ENUMERATED 0x2
69 #define NCF_PHYSICAL 0x4
70 #define NCF_HIDDEN 0x8
71 #define NCF_NO_SERVICE 0x10
72 #define NCF_NOT_USER_REMOVABLE 0x20
73 #define NCF_MULTIPORT_INSTANCED_ADAPTER 0x40
74 #define NCF_HAS_UI 0x80
75 #define NCF_FILTER 0x400
76 #define NCF_NDIS_PROTOCOL 0x4000
78 typedef void (ENUMREGKEYCALLBACK
)(void *pCookie
,HKEY hBaseKey
,TCHAR
*pszSubKey
);
80 static LONG CALLBACK
DisplayApplet(VOID
);
81 static INT_PTR CALLBACK
NetworkPageProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
82 void DisplayTCPIPProperties(HWND hParent
,IP_ADAPTER_INFO
*pInfo
);
84 HINSTANCE hApplet
= 0;
87 static APPLET Applets
[] =
89 {IDI_CPLSYSTEM
, IDS_CPLSYSTEMNAME
, IDS_CPLSYSTEMDESCRIPTION
, DisplayApplet
}
93 /* useful utilities */
95 EnumRegKeys(ENUMREGKEYCALLBACK
*pCallback
,PVOID pCookie
,HKEY hBaseKey
,TCHAR
*tpszRegPath
)
100 TCHAR tpszName
[MAX_PATH
];
101 DWORD dwNameLen
= sizeof(tpszName
);
103 if(RegOpenKeyEx(hBaseKey
,tpszRegPath
,0,KEY_ENUMERATE_SUB_KEYS
,&hKey
)!=ERROR_SUCCESS
)
105 WARN("EnumRegKeys failed (key not found): %S\n", tpszRegPath
);
111 TCHAR pszNewPath
[MAX_PATH
];
112 ret
= RegEnumKeyEx(hKey
,i
,tpszName
,&dwNameLen
,NULL
,NULL
,NULL
,NULL
);
113 if(ret
!= ERROR_SUCCESS
)
115 WARN("EnumRegKeys: RegEnumKeyEx failed for %S (rc 0x%lx)\n", tpszName
, ret
);
119 _stprintf(pszNewPath
,_T("%s\\%s"),tpszRegPath
,tpszName
);
120 TRACE("EnumRegKeys: Calling user supplied enum function\n");
121 pCallback(pCookie
,hBaseKey
,pszNewPath
);
123 dwNameLen
= sizeof(tpszName
);
130 InitPropSheetPage(PROPSHEETPAGE
*psp
, WORD idDlg
, DLGPROC DlgProc
,LPARAM lParam
)
132 ZeroMemory(psp
, sizeof(PROPSHEETPAGE
));
133 psp
->dwSize
= sizeof(PROPSHEETPAGE
);
134 psp
->dwFlags
= PSP_DEFAULT
;
135 psp
->hInstance
= hApplet
;
136 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
137 psp
->pfnDlgProc
= DlgProc
;
138 psp
->lParam
= lParam
;
144 FindNICClassKeyForCfgInstance(TCHAR
*tpszCfgInst
,TCHAR
*tpszSubKeyOut
)
147 TCHAR tpszSubKey
[MAX_PATH
];
148 TCHAR tpszCfgInst2
[MAX_PATH
];
152 for (i
= 0; i
< 100; i
++)
154 _stprintf(tpszSubKey
,_T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%04d"),i
);
155 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
,tpszSubKey
,0,KEY_QUERY_VALUE
,&hKey
)!=ERROR_SUCCESS
)
158 dwSize
= sizeof(tpszCfgInst2
);
159 if(RegQueryValueEx(hKey
,_T("NetCfgInstanceId"),NULL
,&dwType
,(BYTE
*)tpszCfgInst2
,&dwSize
)!=ERROR_SUCCESS
) {
164 if(_tcscmp(tpszCfgInst
,tpszCfgInst2
)==0) {
165 _tcscpy(tpszSubKeyOut
,tpszSubKey
);
174 NICPropertyProtocolCallback(void *pCookie
,HKEY hBaseKey
,TCHAR
*tpszSubKey
)
177 DWORD dwCharacteristics
;
180 TCHAR tpszDescription
[MAX_PATH
];
181 TCHAR tpszNotifyObjectCLSID
[MAX_PATH
];
182 TCHAR
*tpszSubKeyCopy
;
185 UNREFERENCED_PARAMETER(hBaseKey
);
187 // CLSID CLSID_NotifObj;
188 // IUnknown *pUnk = NULL;
189 // INetCfgComponentControl *pNetCfg;
190 // INetCfgComponentPropertyUi *pNetCfgPropUI;
191 hwndDlg
= (HWND
)pCookie
;
193 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
,tpszSubKey
,0,KEY_QUERY_VALUE
,&hKey
)!=ERROR_SUCCESS
)
197 dwSize
= sizeof(dwCharacteristics
);
198 if(RegQueryValueEx(hKey
,_T("Characteristics"),NULL
,&dwType
,(BYTE
*)&dwCharacteristics
,&dwSize
)!= ERROR_SUCCESS
)
201 if(dwCharacteristics
& NCF_HIDDEN
)
208 dwSize
= sizeof(tpszDescription
);
209 if(RegQueryValueEx(hKey
,_T("Description"),NULL
,&dwType
,(BYTE
*)tpszDescription
,&dwSize
)!= ERROR_SUCCESS
)
212 RegOpenKeyEx(hKey
,_T("Ndi"),0,KEY_QUERY_VALUE
,&hNDIKey
);
214 dwSize
= sizeof(tpszNotifyObjectCLSID
);
215 if(RegQueryValueEx(hNDIKey
,_T("ClsId"),NULL
,&dwType
,(BYTE
*)tpszNotifyObjectCLSID
,&dwSize
)!= ERROR_SUCCESS
)
218 RegCloseKey(hNDIKey
);
221 // This code works on Windows... but not on Reactos
224 // CLSIDFromString(tpszNotifyObjectCLSID,&CLSID_NotifObj);
225 // CoCreateInstance(&CLSID_NotifObj,NULL,CLSCTX_INPROC_SERVER,&IID_IUnknown,(void**)&pUnk);
226 // pUnk->lpVtbl->QueryInterface(pUnk,&IID_INetCfgComponentControl,(void**)&pNetCfg);
227 // pUnk->lpVtbl->QueryInterface(pUnk,&IID_INetCfgComponentPropertyUi,(void**)&pNetCfgPropUI);
231 hr = pNetCfg->lpVtbl->Initialize(pNetCfg,&NetCfgComponent,&NetCfg,FALSE);
232 hr = pNetCfgPropUI->lpVtbl->QueryPropertyUi(pNetCfgPropUI,(INetCfg*)&NetCfg);
233 hr = pNetCfgPropUI->lpVtbl->SetContext(pNetCfgPropUI,(INetCfg*)&NetCfgComponent);
234 DWORD dwNumPages = 10;
235 HPROPSHEETPAGE *bOut = NULL;
237 hr = pNetCfgPropUI->MergePropPages(&dwNumPages,(BYTE**)&bOut,&nPages,GetDesktopWindow(),NULL);
242 nIndex
= (int) SendDlgItemMessage(hwndDlg
,IDC_COMPONENTSLIST
,LB_ADDSTRING
,0,(LPARAM
)tpszDescription
);
243 tpszSubKeyCopy
= _tcsdup(tpszSubKey
);
244 SendDlgItemMessage(hwndDlg
,IDC_COMPONENTSLIST
,LB_SETITEMDATA
,nIndex
,(LPARAM
)tpszSubKeyCopy
);
249 static INT_PTR CALLBACK
250 NICPropertyPageProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
252 PGLOBAL_NCPA_DATA pGlobalData
= (PGLOBAL_NCPA_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
259 TCHAR tpszSubKey
[MAX_PATH
];
260 TCHAR tpszDisplayName
[MAX_PATH
];
263 pGlobalData
= (PGLOBAL_NCPA_DATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
264 if (pGlobalData
== NULL
)
267 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
269 if(!FindNICClassKeyForCfgInstance(pGlobalData
->CurrentAdapterName
, tpszSubKey
))
271 WARN("NIC Entry not found for '%s'\n", debugstr_w(pGlobalData
->CurrentAdapterName
));
272 MessageBox(hwndDlg
,_T("NIC Entry not found"),_T("Registry error"),MB_ICONSTOP
);
273 MessageBox(hwndDlg
,pGlobalData
->CurrentAdapterName
,tpszSubKey
,MB_ICONSTOP
);
276 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
,tpszSubKey
,0,KEY_QUERY_VALUE
,&hKey
)!=ERROR_SUCCESS
)
279 dwSize
= sizeof(tpszDisplayName
);
280 if(RegQueryValueEx(hKey
,_T("DriverDesc"),NULL
,&dwType
,(BYTE
*)tpszDisplayName
,&dwSize
)!= ERROR_SUCCESS
)
284 SetDlgItemText(hwndDlg
,IDC_NETCARDNAME
,tpszDisplayName
);
285 EnableWindow(GetDlgItem(hwndDlg
,IDC_CONFIGURE
),FALSE
);
287 //SetDlgItemTextA(hwndDlg,IDC_NETCARDNAME,Info[pPage->lParam].Description);
288 EnumRegKeys(NICPropertyProtocolCallback
,hwndDlg
,HKEY_LOCAL_MACHINE
,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E975-E325-11CE-BFC1-08002BE10318}"));
290 SendDlgItemMessage(hwndDlg
, IDC_COMPONENTSLIST
, LB_SETCURSEL
, 0, 0);
291 SendMessage(hwndDlg
, WM_COMMAND
, MAKEWPARAM(IDC_COMPONENTSLIST
, LBN_SELCHANGE
), 0);
295 switch(LOWORD(wParam
))
297 case IDC_COMPONENTSLIST
:
298 if(HIWORD(wParam
)==LBN_SELCHANGE
)
301 TCHAR tpszHelpKey
[MAX_PATH
];
302 TCHAR tpszHelpText
[MAX_PATH
];
305 HWND hListBox
= GetDlgItem(hwndDlg
,IDC_COMPONENTSLIST
);
306 tpszSubKey
= (TCHAR
*)SendMessage(hListBox
,LB_GETITEMDATA
,SendMessage(hListBox
,LB_GETCURSEL
,0,0),0);
309 _stprintf(tpszHelpKey
,_T("%s\\Ndi"),tpszSubKey
);
311 RegOpenKeyEx(HKEY_LOCAL_MACHINE
,tpszHelpKey
,0,KEY_QUERY_VALUE
,&hNDIKey
);
313 dwSize
= sizeof(tpszHelpText
);
314 if(RegQueryValueEx(hNDIKey
,_T("HelpText"),NULL
,&dwType
,(BYTE
*)tpszHelpText
,&dwSize
)!= ERROR_SUCCESS
)
316 RegCloseKey(hNDIKey
);
318 SetDlgItemText(hwndDlg
,IDC_DESCRIPTION
,tpszHelpText
);
320 if(HIWORD(wParam
)!=LBN_DBLCLK
)
325 if(pGlobalData
->pCurrentAdapterInfo
)
327 DisplayTCPIPProperties(hwndDlg
, pGlobalData
->pCurrentAdapterInfo
);
331 FIXME("If you see this, then the IPHLPAPI.DLL probably needs more work because GetAdaptersInfo did not return the expected data.\n");
332 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
);
344 DisplayNICProperties(HWND hParent
, GLOBAL_NCPA_DATA
* pGlobalData
)
346 PROPSHEETPAGE psp
[1];
348 TCHAR tpszSubKey
[MAX_PATH
];
350 DWORD dwType
= REG_SZ
;
351 TCHAR tpszName
[MAX_PATH
];
352 DWORD dwSize
= sizeof(tpszName
);
353 TCHAR tpszCfgInstanceID
[MAX_ADAPTER_NAME_LENGTH
];
356 WideCharToMultiByte(CP_UTF8
, 0, pGlobalData
->CurrentAdapterName
, -1, tpszCfgInstanceID
, MAX_ADAPTER_NAME_LENGTH
, 0, 0);
358 wcscpy(tpszCfgInstanceID
, pGlobalData
->CurrentAdapterName
);
361 // Get the "Name" for this Connection
362 _stprintf(tpszSubKey
,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"),tpszCfgInstanceID
);
363 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
,tpszSubKey
,0,KEY_QUERY_VALUE
,&hKey
)!=ERROR_SUCCESS
)
365 if(RegQueryValueEx(hKey
,_T("Name"),NULL
,&dwType
,(BYTE
*)tpszName
,&dwSize
)!=ERROR_SUCCESS
)
366 _stprintf(tpszName
,_T("[ERROR]"));
368 _tcscat(tpszName
,_T(" Properties"));
371 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
372 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
373 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_NOAPPLYNOW
;
374 psh
.hwndParent
= hParent
;
375 psh
.hInstance
= hApplet
;
376 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_CPLSYSTEM
));
377 psh
.pszCaption
= tpszName
;
378 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
381 psh
.pfnCallback
= NULL
;
383 InitPropSheetPage(&psp
[0], IDD_NETPROPERTIES
, NICPropertyPageProc
, (LPARAM
)pGlobalData
);
388 void RefreshNICInfo(HWND hwndDlg
, PGLOBAL_NCPA_DATA pGlobalData
)
393 if (pGlobalData
->pFirstAdapterInfo
)
394 HeapFree(GetProcessHeap(), 0, pGlobalData
->pFirstAdapterInfo
);
396 BufferSize
= sizeof(IP_ADAPTER_INFO
);
397 pGlobalData
->pFirstAdapterInfo
= (PIP_ADAPTER_INFO
) HeapAlloc(GetProcessHeap(), 0, BufferSize
);
399 if (GetAdaptersInfo(pGlobalData
->pFirstAdapterInfo
, &BufferSize
) == ERROR_BUFFER_OVERFLOW
)
401 HeapFree(GetProcessHeap(), 0, pGlobalData
->pFirstAdapterInfo
);
402 pGlobalData
->pFirstAdapterInfo
= (PIP_ADAPTER_INFO
) HeapAlloc(GetProcessHeap(), 0, BufferSize
);
405 if ((ErrRet
= GetAdaptersInfo(pGlobalData
->pFirstAdapterInfo
, &BufferSize
)) != NO_ERROR
)
407 ERR("error adapterinfo\n");
408 MessageBox(hwndDlg
, _T("error adapterinfo") ,_T("ncpa.cpl"),MB_ICONSTOP
);
410 if (pGlobalData
->pFirstAdapterInfo
)
411 HeapFree(GetProcessHeap(), 0, pGlobalData
->pFirstAdapterInfo
);
415 void UpdateCurrentAdapterInfo(HWND hwndDlg
, PGLOBAL_NCPA_DATA pGlobalData
)
417 PIP_INTERFACE_INFO pInfo
;
418 ULONG BufferSize
= 0;
421 if (!pGlobalData
->pCurrentAdapterInfo
)
424 BufferSize
= sizeof(IP_INTERFACE_INFO
);
425 pInfo
= (PIP_INTERFACE_INFO
) HeapAlloc(GetProcessHeap(), 0, BufferSize
);
426 if (ERROR_INSUFFICIENT_BUFFER
== GetInterfaceInfo(pInfo
, &BufferSize
))
428 HeapFree(GetProcessHeap(), 0, pInfo
);
429 pInfo
= (PIP_INTERFACE_INFO
) HeapAlloc(GetProcessHeap(), 0, BufferSize
);
432 dwRetVal
= GetInterfaceInfo(pInfo
, &BufferSize
);
433 if (NO_ERROR
== dwRetVal
)
437 for (i
= 0; i
< pInfo
->NumAdapters
; i
++)
439 if (0 == wcscmp(pGlobalData
->CurrentAdapterName
, pInfo
->Adapter
[i
].Name
))
441 if (pInfo
->Adapter
[i
].Index
!= pGlobalData
->pCurrentAdapterInfo
->Index
)
443 RefreshNICInfo(hwndDlg
, pGlobalData
);
445 pGlobalData
->pCurrentAdapterInfo
= pGlobalData
->pFirstAdapterInfo
;
446 while (pGlobalData
->pCurrentAdapterInfo
)
448 if (pGlobalData
->pCurrentAdapterInfo
->Index
== pInfo
->Adapter
[i
].Index
)
451 pGlobalData
->pCurrentAdapterInfo
= pGlobalData
->pCurrentAdapterInfo
->Next
;
457 else if (ERROR_NO_DATA
== dwRetVal
)
458 WARN("There are no network adapters with IPv4 enabled on the local system\n");
460 ERR("GetInterfaceInfo failed.\n");
464 UpdateNICStatusData(HWND hwndDlg
, PGLOBAL_NCPA_DATA pGlobalData
)
466 DWORD dwRet
= NO_ERROR
;
468 if (pGlobalData
->pCurrentAdapterInfo
)
470 if (NULL
== pGlobalData
->pIfTable
)
472 pGlobalData
->IfTableSize
= sizeof(MIB_IFTABLE
);
473 pGlobalData
->pIfTable
= (PMIB_IFTABLE
)HeapAlloc(GetProcessHeap(), 0, pGlobalData
->IfTableSize
);
474 if (NULL
== pGlobalData
->pIfTable
)
476 static BOOL firstError
= TRUE
;
480 WARN("Out of memory - could not allocate MIB_IFTABLE(1)");
486 /* Call GetIfTable once to see if we have a large enough buffer */
487 dwRet
= GetIfTable(pGlobalData
->pIfTable
, &pGlobalData
->IfTableSize
, FALSE
);
488 if (ERROR_INSUFFICIENT_BUFFER
== dwRet
)
490 HeapFree(GetProcessHeap(), 0, pGlobalData
->pIfTable
);
492 pGlobalData
->pIfTable
= (PMIB_IFTABLE
)HeapAlloc(GetProcessHeap(), 0, pGlobalData
->IfTableSize
);
493 if (NULL
== pGlobalData
->pIfTable
)
495 static BOOL firstError
= TRUE
;
499 WARN("Out of memory - could not allocate MIB_IFTABLE(2)");
502 pGlobalData
->IfTableSize
= 0;
506 dwRet
= GetIfTable(pGlobalData
->pIfTable
, &pGlobalData
->IfTableSize
, FALSE
);
507 if (NO_ERROR
!= dwRet
)
509 HeapFree(GetProcessHeap(), 0, pGlobalData
->pIfTable
);
510 pGlobalData
->pIfTable
= NULL
;
511 pGlobalData
->IfTableSize
= 0;
517 if (NO_ERROR
== dwRet
)
523 DWORD OperStatus
= IF_OPER_STATUS_DISCONNECTED
;
524 PMIB_IFROW pIfRow
= NULL
;
525 TCHAR Buffer
[256], LocBuffer
[256];
526 SYSTEMTIME TimeConnected
;
528 memset(&TimeConnected
, 0, sizeof(TimeConnected
));
530 if (pGlobalData
->pCurrentAdapterInfo
)
532 UpdateCurrentAdapterInfo(hwndDlg
, pGlobalData
);
534 for (i
= 0; i
< pGlobalData
->pIfTable
->dwNumEntries
; i
++)
536 pIfRow
= (PMIB_IFROW
)&pGlobalData
->pIfTable
->table
[i
];
538 if (pIfRow
->dwIndex
== pGlobalData
->pCurrentAdapterInfo
->Index
)
540 DWORD DurationSeconds
;
541 SYSTEMTIME SystemTime
;
542 FILETIME SystemFileTime
;
543 ULARGE_INTEGER LargeSystemTime
;
545 PktsOut
= pIfRow
->dwOutUcastPkts
;
546 PktsIn
= pIfRow
->dwInUcastPkts
;
547 Mbps
= pIfRow
->dwSpeed
;
548 OperStatus
= pIfRow
->dwOperStatus
;
550 /* TODO: For some unknown reason, this doesn't correspond to the Windows duration */
551 GetSystemTime(&SystemTime
);
552 SystemTimeToFileTime(&SystemTime
, &SystemFileTime
);
553 LargeSystemTime
= *(ULARGE_INTEGER
*)&SystemFileTime
;
554 LargeSystemTime
.QuadPart
/= 100000ULL;
555 DurationSeconds
= ((LargeSystemTime
.LowPart
- pIfRow
->dwLastChange
) / 100);
556 TimeConnected
.wSecond
= (DurationSeconds
% 60);
557 TimeConnected
.wMinute
= (DurationSeconds
/ 60) % 60;
558 TimeConnected
.wHour
= (DurationSeconds
/ (60 * 60)) % 24;
559 TimeConnected
.wDay
= DurationSeconds
/ (60 * 60 * 24);
566 _stprintf(Buffer
, L
"%u", PktsOut
);
567 GetNumberFormat(LOCALE_USER_DEFAULT
, 0, Buffer
, NULL
, LocBuffer
, sizeof(LocBuffer
) / sizeof(LocBuffer
[0]));
568 SendDlgItemMessage(hwndDlg
, IDC_SEND
, WM_SETTEXT
, 0, (LPARAM
)LocBuffer
);
570 _stprintf(Buffer
, L
"%u", PktsIn
);
571 GetNumberFormat(LOCALE_USER_DEFAULT
, 0, Buffer
, NULL
, LocBuffer
, sizeof(LocBuffer
) / sizeof(LocBuffer
[0]));
572 SendDlgItemMessage(hwndDlg
, IDC_RECEIVED
, WM_SETTEXT
, 0, (LPARAM
)LocBuffer
);
576 case IF_OPER_STATUS_NON_OPERATIONAL
:
577 OperStatus
= IDS_STATUS_NON_OPERATIONAL
;
580 case IF_OPER_STATUS_UNREACHABLE
:
581 OperStatus
= IDS_STATUS_UNREACHABLE
;
584 case IF_OPER_STATUS_DISCONNECTED
:
585 OperStatus
= IDS_STATUS_DISCONNECTED
;
588 case IF_OPER_STATUS_CONNECTING
:
589 OperStatus
= IDS_STATUS_CONNECTING
;
592 case IF_OPER_STATUS_CONNECTED
:
593 OperStatus
= IDS_STATUS_CONNECTED
;
596 case IF_OPER_STATUS_OPERATIONAL
:
597 /* TODO: Find sub status, waiting for DHCP address, etc. */
598 OperStatus
= IDS_STATUS_OPERATIONAL
;
602 WARN("Unknown operation status: %d\n", OperStatus
);
603 OperStatus
= IDS_STATUS_OPERATIONAL
;
606 LoadString(hApplet
, OperStatus
, LocBuffer
, sizeof(LocBuffer
) / sizeof(LocBuffer
[0]));
607 SendDlgItemMessage(hwndDlg
, IDC_STATUS
, WM_SETTEXT
, 0, (LPARAM
)LocBuffer
);
609 GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &TimeConnected
, L
"HH':'mm':'ss", LocBuffer
, sizeof(LocBuffer
) / sizeof(LocBuffer
[0]));
610 if (0 == TimeConnected
.wDay
)
612 SendDlgItemMessage(hwndDlg
, IDC_DURATION
, WM_SETTEXT
, 0, (LPARAM
)LocBuffer
);
616 TCHAR DayBuffer
[256];
617 if (1 == TimeConnected
.wDay
)
619 LoadString(hApplet
, IDS_DURATION_DAY
, DayBuffer
, sizeof(DayBuffer
) / sizeof(DayBuffer
[0]));
623 LoadString(hApplet
, IDS_DURATION_DAYS
, DayBuffer
, sizeof(DayBuffer
) / sizeof(DayBuffer
[0]));
625 _sntprintf(Buffer
, 256, DayBuffer
, TimeConnected
.wDay
, LocBuffer
);
626 SendDlgItemMessage(hwndDlg
, IDC_DURATION
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
629 LoadString(hApplet
, IDS_SPEED_MBPS
, LocBuffer
, sizeof(LocBuffer
) / sizeof(LocBuffer
[0]));
630 _sntprintf(Buffer
, 256, LocBuffer
, Mbps
/ 1000000);
631 SendDlgItemMessage(hwndDlg
, IDC_SPEED
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
635 static BOOL firstError
= TRUE
;
639 ERR("GetIfTable failed with error code: %d\n", dwRet
);
645 static INT_PTR CALLBACK
646 NICStatusPageProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
648 PGLOBAL_NCPA_DATA pGlobalData
;
649 pGlobalData
= (PGLOBAL_NCPA_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
655 pGlobalData
= (PGLOBAL_NCPA_DATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
656 if (pGlobalData
== NULL
)
659 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
661 EnableWindow(GetDlgItem(hwndDlg
,IDC_ENDISABLE
),FALSE
);
662 pGlobalData
->hStatsUpdateTimer
= SetTimer(hwndDlg
, 1, 1000, NULL
);
663 UpdateNICStatusData(hwndDlg
, pGlobalData
);
667 switch(LOWORD(wParam
))
671 DisplayNICProperties(hwndDlg
, pGlobalData
);
678 UpdateNICStatusData(hwndDlg
, pGlobalData
);
683 KillTimer(hwndDlg
, pGlobalData
->hStatsUpdateTimer
);
684 pGlobalData
->hStatsUpdateTimer
= 0;
686 if (pGlobalData
->pIfTable
)
688 HeapFree(GetProcessHeap(), 0, pGlobalData
->pIfTable
);
689 pGlobalData
->pIfTable
= NULL
;
690 pGlobalData
->IfTableSize
= 0;
698 static INT_PTR CALLBACK
699 NICSupportPageProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
701 PGLOBAL_NCPA_DATA pGlobalData
;
702 pGlobalData
= (PGLOBAL_NCPA_DATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
708 pGlobalData
= (PGLOBAL_NCPA_DATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
709 if (pGlobalData
== NULL
)
712 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
714 if (pGlobalData
->pCurrentAdapterInfo
)
718 if (pGlobalData
->pCurrentAdapterInfo
->DhcpEnabled
)
719 LoadString(hApplet
, IDS_ASSIGNED_DHCP
, Buffer
, sizeof(Buffer
) / sizeof(TCHAR
));
721 LoadString(hApplet
, IDS_ASSIGNED_MANUAL
, Buffer
, sizeof(Buffer
) / sizeof(TCHAR
));
723 SendDlgItemMessage(hwndDlg
, IDC_DETAILSTYPE
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
724 _stprintf(Buffer
, _T("%S"), pGlobalData
->pCurrentAdapterInfo
->IpAddressList
.IpAddress
.String
);
725 SendDlgItemMessage(hwndDlg
, IDC_DETAILSIP
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
726 _stprintf(Buffer
, _T("%S"), pGlobalData
->pCurrentAdapterInfo
->IpAddressList
.IpMask
.String
);
727 SendDlgItemMessage(hwndDlg
, IDC_DETAILSSUBNET
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
728 _stprintf(Buffer
, _T("%S"), pGlobalData
->pCurrentAdapterInfo
->GatewayList
.IpAddress
.String
);
729 SendDlgItemMessage(hwndDlg
, IDC_DETAILSGATEWAY
, WM_SETTEXT
, 0, (LPARAM
)Buffer
);
734 switch(LOWORD(wParam
))
742 FIXME("Not implemented: show detail window\n");
743 MessageBox(hwndDlg
,_T("not implemented: show detail window"),_T("ncpa.cpl"),MB_ICONSTOP
);
753 DisplayNICStatus(HWND hParent
,TCHAR
*tpszCfgInstanceID
)
755 PROPSHEETPAGE psp
[2];
757 TCHAR tpszSubKey
[MAX_PATH
];
759 DWORD dwType
= REG_SZ
;
760 TCHAR tpszName
[MAX_PATH
];
761 DWORD dwSize
= sizeof(tpszName
);
762 PGLOBAL_NCPA_DATA pGlobalData
;
763 PIP_ADAPTER_INFO pInfo
;
764 WCHAR wcsAdapterName
[MAX_ADAPTER_NAME
];
766 pGlobalData
= (PGLOBAL_NCPA_DATA
)GetWindowLongPtr(hParent
, DWLP_USER
);
769 MultiByteToWideChar(CP_UTF8
, 0, tpszCfgInstanceID
, -1, pGlobalData
->CurrentAdapterName
, MAX_ADAPTER_NAME
);
771 wcscpy(pGlobalData
->CurrentAdapterName
, tpszCfgInstanceID
);
774 // Get the "Name" for this Connection
775 _stprintf(tpszSubKey
,_T("System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"),tpszCfgInstanceID
);
776 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,tpszSubKey
,0,KEY_QUERY_VALUE
,&hKey
)!=ERROR_SUCCESS
)
779 if (RegQueryValueEx(hKey
,_T("Name"),NULL
,&dwType
,(BYTE
*)tpszName
,&dwSize
)!=ERROR_SUCCESS
)
780 _stprintf(tpszName
,_T("[ERROR]"));
781 //_stprintf(tpszName,_T("[ERROR]") _T(__FILE__) _T(" %d"),__LINE__ );
783 _tcscat(tpszName
,_T(" Status"));
786 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
787 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
788 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_NOAPPLYNOW
;
789 psh
.hwndParent
= hParent
;
790 psh
.hInstance
= hApplet
;
791 // FIX THESE REACTOS HEADERS !!!!!!!!!
792 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_CPLSYSTEM
));
793 psh
.pszCaption
= tpszName
;//Caption;
794 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
797 psh
.pfnCallback
= NULL
;
799 RefreshNICInfo(hParent
, pGlobalData
);
801 pGlobalData
->pCurrentAdapterInfo
= NULL
;
802 pInfo
= pGlobalData
->pFirstAdapterInfo
;
805 MultiByteToWideChar(CP_UTF8
, 0, pInfo
->AdapterName
, -1, wcsAdapterName
, MAX_ADAPTER_NAME
);
806 if (0 == wcscmp(wcsAdapterName
, pGlobalData
->CurrentAdapterName
))
808 pGlobalData
->pCurrentAdapterInfo
= pInfo
;
815 InitPropSheetPage(&psp
[0], IDD_CARDPROPERTIES
, NICStatusPageProc
, (LPARAM
)pGlobalData
);
816 InitPropSheetPage(&psp
[1], IDD_CARDSUPPORT
, NICSupportPageProc
, (LPARAM
)pGlobalData
);
823 // IPHLPAPI does not provide a list of all adapters
827 EnumAdapters(HWND hwndDlg
)
829 TCHAR pszText
[MAX_ADAPTER_NAME_LENGTH
+ 4];
830 IP_ADAPTER_INFO
*pInfo
;
835 if(GetAdaptersInfo(Info
,&size
)!=ERROR_SUCCESS
)
837 WARN("IPHLPAPI.DLL failed to provide Adapter information\n");
838 MessageBox(hwndDlg
,L
"IPHLPAPI.DLL failed to provide Adapter information",L
"Error",MB_ICONSTOP
);
845 swprintf(pszText
,L
"%S",Info
[0].Description
);
846 nIndex
= SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_ADDSTRING
,0,(LPARAM
)pszText
);
847 SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_SETITEMDATA
,nIndex
,(LPARAM
)pInfo
);
856 NetAdapterCallback(void *pCookie
,HKEY hBaseKey
,TCHAR
*tpszSubKey
)
858 TCHAR tpszDisplayName
[MAX_PATH
];
859 //TCHAR tpszDeviceID[MAX_PATH];
860 TCHAR tpszCfgInstanceID
[MAX_PATH
];
861 TCHAR
*ptpszCfgInstanceID
;
863 DWORD dwType
= REG_SZ
;
864 DWORD dwSize
= sizeof(tpszDisplayName
);
866 HWND hwndDlg
= (HWND
)pCookie
;
867 DWORD dwCharacteristics
;
869 TRACE("NetAdapterCallback: %s\n", debugstr_aw(tpszSubKey
));
871 if(RegOpenKeyEx(hBaseKey
,tpszSubKey
,0,KEY_QUERY_VALUE
,&hKey
)!=ERROR_SUCCESS
)
874 TRACE("NetAdapterCallback: Reading Characteristics\n");
876 dwSize
= sizeof(dwCharacteristics
);
877 if(RegQueryValueEx(hKey
,_T("Characteristics"),NULL
,&dwType
,(BYTE
*)&dwCharacteristics
,&dwSize
)!=ERROR_SUCCESS
)
878 dwCharacteristics
= 0;
879 if (dwCharacteristics
& NCF_HIDDEN
)
881 if (!(dwCharacteristics
& NCF_VIRTUAL
) && !(dwCharacteristics
& NCF_PHYSICAL
))
884 TRACE("NetAdapterCallback: Reading DriverDesc\n");
886 dwSize
= sizeof(tpszDisplayName
);
887 if (RegQueryValueEx(hKey
,_T("DriverDesc"),NULL
,&dwType
,(BYTE
*)tpszDisplayName
,&dwSize
)!= ERROR_SUCCESS
)
888 _tcscpy(tpszDisplayName
,_T("Unnamed Adapter"));
889 TRACE("Network card: '%s'\n", debugstr_aw(tpszDisplayName
));
891 // get the link to the Enum Subkey (currently unused)
893 //dwSize = sizeof(tpszDeviceID);
894 //if(RegQueryValueEx(hKey,_T("MatchingDeviceId"),NULL,&dwType,(BYTE*)tpszDeviceID,&dwSize) != ERROR_SUCCESS) {
895 // WARN("Missing MatchingDeviceId Entry\n");
896 // MessageBox(hwndDlg,_T("Missing MatchingDeviceId Entry"),_T("Registry Problem"),MB_ICONSTOP);
900 // get the card configuration GUID
902 dwSize
= sizeof(tpszCfgInstanceID
);
903 if(RegQueryValueEx(hKey
,_T("NetCfgInstanceId"),NULL
,&dwType
,(BYTE
*)tpszCfgInstanceID
,&dwSize
) != ERROR_SUCCESS
)
905 ERR("Missing NetCfgInstanceId Entry\n");
906 MessageBox(hwndDlg
,_T("Missing NetCfgInstanceId Entry"),_T("Registry Problem"),MB_ICONSTOP
);
910 ptpszCfgInstanceID
= _tcsdup(tpszCfgInstanceID
);
912 // **TODO** **FIXME** TBD
913 // At this point, we should verify, if the device listed here
914 // really represents a device that is currently connected to the system
916 // How is this done properly ?
918 nIndex
= (int) SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_ADDSTRING
,0,(LPARAM
)tpszDisplayName
);
919 SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_SETITEMDATA
,nIndex
,(LPARAM
)ptpszCfgInstanceID
);
925 EnumAdapters(HWND hwndDlg
)
927 LPTSTR lpRegPath
= _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
929 EnumRegKeys(NetAdapterCallback
,hwndDlg
,HKEY_LOCAL_MACHINE
,lpRegPath
);
934 static INT_PTR CALLBACK
935 NetworkPageProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
943 PGLOBAL_NCPA_DATA pGlobalData
= (PGLOBAL_NCPA_DATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
944 if (pGlobalData
== NULL
)
947 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
949 EnableWindow(GetDlgItem(hwndDlg
,IDC_ADD
),FALSE
);
950 EnableWindow(GetDlgItem(hwndDlg
,IDC_REMOVE
),FALSE
);
952 EnumAdapters(hwndDlg
);
953 SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_SETCURSEL
,0,0);
963 while(SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_GETCOUNT
,0,0)>0)
967 tpszString
= (TCHAR
*)SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_GETITEMDATA
,0,0);
970 SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_DELETESTRING
,0,0);
977 switch(LOWORD(wParam
))
979 case IDC_NETCARDLIST
:
980 if(HIWORD(wParam
)==LBN_DBLCLK
) {
981 nIndex
= (int) SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_GETCURSEL
,0,0);
983 DisplayNICStatus(hwndDlg
,(TCHAR
*)SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_GETITEMDATA
,nIndex
,0));
988 nIndex
= (int) SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_GETCURSEL
,0,0);
990 DisplayNICStatus(hwndDlg
,(TCHAR
*)SendDlgItemMessage(hwndDlg
,IDC_NETCARDLIST
,LB_GETITEMDATA
,nIndex
,0));
1002 static LONG CALLBACK
1005 PGLOBAL_NCPA_DATA pGlobalData
;
1006 PROPSHEETPAGE psp
[1];
1007 PROPSHEETHEADER psh
= {0};
1008 TCHAR Caption
[1024];
1011 LoadString(hApplet
, IDS_CPLSYSTEMNAME
, Caption
, sizeof(Caption
) / sizeof(TCHAR
));
1013 pGlobalData
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(GLOBAL_NCPA_DATA
));
1014 if (pGlobalData
== NULL
)
1017 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1018 psh
.dwFlags
= PSH_PROPSHEETPAGE
;
1019 psh
.hwndParent
= NULL
;
1020 psh
.hInstance
= hApplet
;
1021 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDI_CPLSYSTEM
));
1022 psh
.pszCaption
= Caption
;
1023 psh
.nPages
= sizeof(psp
) / sizeof(PROPSHEETPAGE
);
1026 psh
.pfnCallback
= NULL
;
1028 InitPropSheetPage(&psp
[0], IDD_PROPPAGENETWORK
, NetworkPageProc
, (LPARAM
)pGlobalData
);
1030 Ret
= PropertySheet(&psh
);
1032 HeapFree(GetProcessHeap(), 0, pGlobalData
);
1034 return (LONG
)(Ret
!= -1);
1037 /* Control Panel Callback */
1039 CPlApplet(HWND hwndCPl
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
1041 UNREFERENCED_PARAMETER(hwndCPl
);
1051 return sizeof(Applets
)/sizeof(APPLET
);
1056 CPLINFO
*CPlInfo
= (CPLINFO
*)lParam2
;
1058 CPlInfo
->idIcon
= Applets
[(int)lParam1
].idIcon
;
1059 CPlInfo
->idName
= Applets
[(int)lParam1
].idName
;
1060 CPlInfo
->idInfo
= Applets
[(int)lParam1
].idDescription
;
1066 Applets
[(int)lParam1
].AppletProc();
1075 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD dwReason
, LPVOID lpvReserved
)
1077 UNREFERENCED_PARAMETER(lpvReserved
);
1081 case DLL_PROCESS_ATTACH
:
1082 case DLL_THREAD_ATTACH
: