1 /* 2 * PROJECT: ReactOS Shell 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: CNetConnectionPropertyUi: Network connection configuration dialog 5 * COPYRIGHT: Copyright 2008 Johannes Anderwald (johannes.anderwald@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 CNetConnectionPropertyUi::CNetConnectionPropertyUi() : 11 m_pProperties(NULL) 12 { 13 } 14 15 CNetConnectionPropertyUi::~CNetConnectionPropertyUi() 16 { 17 if (m_pNCfg) 18 m_pNCfg->Uninitialize(); 19 20 if (m_pProperties) 21 NcFreeNetconProperties(m_pProperties); 22 } 23 24 VOID 25 AddItemToListView(HWND hDlgCtrl, PNET_ITEM pItem, LPWSTR szName, BOOL bChecked) 26 { 27 LVITEMW lvItem; 28 29 ZeroMemory(&lvItem, sizeof(lvItem)); 30 lvItem.mask = LVIF_TEXT | LVIF_PARAM; 31 lvItem.pszText = szName; 32 lvItem.lParam = (LPARAM)pItem; 33 lvItem.iItem = ListView_GetItemCount(hDlgCtrl); 34 lvItem.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&lvItem); 35 ListView_SetCheckState(hDlgCtrl, lvItem.iItem, bChecked); 36 } 37 38 BOOL 39 CNetConnectionPropertyUi::GetINetCfgComponent(INetCfg *pNCfg, INetCfgComponent ** pOut) 40 { 41 LPWSTR pName; 42 HRESULT hr; 43 ULONG Fetched; 44 CComPtr<IEnumNetCfgComponent> pEnumCfg; 45 46 hr = pNCfg->EnumComponents(&GUID_DEVCLASS_NET, &pEnumCfg); 47 if (FAILED_UNEXPECTEDLY(hr)) 48 return FALSE; 49 50 while (TRUE) 51 { 52 CComPtr<INetCfgComponent> pNCg; 53 hr = pEnumCfg->Next(1, &pNCg, &Fetched); 54 if (hr != S_OK) 55 break; 56 57 hr = pNCg->GetDisplayName(&pName); 58 if (SUCCEEDED(hr)) 59 { 60 if (!_wcsicmp(pName, m_pProperties->pszwDeviceName)) 61 { 62 *pOut = pNCg.Detach(); 63 return TRUE; 64 } 65 CoTaskMemFree(pName); 66 } 67 } 68 return FALSE; 69 } 70 71 VOID 72 CNetConnectionPropertyUi::EnumComponents(HWND hDlgCtrl, INetCfg *pNCfg, const GUID *CompGuid, UINT Type) 73 { 74 HRESULT hr; 75 CComPtr<IEnumNetCfgComponent> pENetCfg; 76 ULONG Num; 77 DWORD dwCharacteristics; 78 LPOLESTR pDisplayName, pHelpText; 79 PNET_ITEM pItem; 80 BOOL bChecked; 81 82 hr = pNCfg->EnumComponents(CompGuid, &pENetCfg); 83 if (FAILED_UNEXPECTEDLY(hr)) 84 return; 85 86 while (TRUE) 87 { 88 CComPtr<INetCfgComponent> pNCfgComp; 89 CComPtr<INetCfgComponentBindings> pCompBind; 90 CComPtr<INetCfgComponent> pAdapterCfgComp; 91 92 hr = pENetCfg->Next(1, &pNCfgComp, &Num); 93 if (hr != S_OK) 94 break; 95 96 hr = pNCfgComp->GetCharacteristics(&dwCharacteristics); 97 if (SUCCEEDED(hr) && (dwCharacteristics & NCF_HIDDEN)) 98 continue; 99 100 pDisplayName = NULL; 101 pHelpText = NULL; 102 hr = pNCfgComp->GetDisplayName(&pDisplayName); 103 hr = pNCfgComp->GetHelpText(&pHelpText); 104 bChecked = FALSE; 105 hr = pNCfgComp->QueryInterface(IID_PPV_ARG(INetCfgComponentBindings, &pCompBind)); 106 if (SUCCEEDED(hr)) 107 { 108 if (GetINetCfgComponent(pNCfg, &pAdapterCfgComp)) 109 { 110 hr = pCompBind->IsBoundTo(pAdapterCfgComp); 111 if (hr == S_OK) 112 bChecked = TRUE; 113 } 114 } 115 116 pItem = static_cast<NET_ITEM*>(CoTaskMemAlloc(sizeof(NET_ITEM))); 117 if (!pItem) 118 continue; 119 120 pItem->dwCharacteristics = dwCharacteristics; 121 pItem->szHelp = pHelpText; 122 pItem->Type = (NET_TYPE)Type; 123 pItem->pNCfgComp = pNCfgComp.Detach(); 124 pItem->NumPropDialogOpen = 0; 125 126 AddItemToListView(hDlgCtrl, pItem, pDisplayName, bChecked); 127 CoTaskMemFree(pDisplayName); 128 } 129 } 130 131 VOID 132 CNetConnectionPropertyUi::InitializeLANPropertiesUIDlg(HWND hwndDlg) 133 { 134 HRESULT hr; 135 CComPtr<INetCfg> pNCfg; 136 CComPtr<INetCfgLock> pNCfgLock; 137 HWND hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMPONENTSLIST); 138 LVCOLUMNW lc; 139 RECT rc; 140 DWORD dwStyle; 141 LPWSTR pDisplayName; 142 LVITEMW li; 143 144 SendDlgItemMessageW(hwndDlg, IDC_NETCARDNAME, WM_SETTEXT, 0, (LPARAM)m_pProperties->pszwDeviceName); 145 if (m_pProperties->dwCharacter & NCCF_SHOW_ICON) 146 { 147 /* check show item on taskbar*/ 148 SendDlgItemMessageW(hwndDlg, IDC_SHOWTASKBAR, BM_SETCHECK, BST_CHECKED, 0); 149 } 150 if (m_pProperties->dwCharacter & NCCF_NOTIFY_DISCONNECTED) 151 { 152 /* check notify item */ 153 SendDlgItemMessageW(hwndDlg, IDC_NOTIFYNOCONNECTION, BM_SETCHECK, BST_CHECKED, 0); 154 } 155 156 memset(&lc, 0, sizeof(LV_COLUMN)); 157 lc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT; 158 lc.fmt = LVCFMT_FIXED_WIDTH; 159 if (GetClientRect(hDlgCtrl, &rc)) 160 { 161 lc.mask |= LVCF_WIDTH; 162 lc.cx = rc.right - rc.left; 163 } 164 lc.pszText = (LPWSTR)L""; 165 (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&lc); 166 dwStyle = (DWORD) SendMessage(hDlgCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0); 167 dwStyle = dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES; 168 SendMessage(hDlgCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle); 169 170 hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(INetCfg, &pNCfg)); 171 if (FAILED(hr)) 172 return; 173 174 hr = pNCfg->QueryInterface(IID_PPV_ARG(INetCfgLock, &pNCfgLock)); 175 hr = pNCfgLock->AcquireWriteLock(100, L"", &pDisplayName); 176 if (hr == S_FALSE) 177 { 178 CoTaskMemFree(pDisplayName); 179 return; 180 } 181 182 hr = pNCfg->Initialize(NULL); 183 if (FAILED_UNEXPECTEDLY(hr)) 184 return; 185 186 m_pNCfg = pNCfg; 187 m_NCfgLock = pNCfgLock; 188 189 EnumComponents(hDlgCtrl, pNCfg, &GUID_DEVCLASS_NETCLIENT, NET_TYPE_CLIENT); 190 EnumComponents(hDlgCtrl, pNCfg, &GUID_DEVCLASS_NETSERVICE, NET_TYPE_SERVICE); 191 EnumComponents(hDlgCtrl, pNCfg, &GUID_DEVCLASS_NETTRANS, NET_TYPE_PROTOCOL); 192 193 ZeroMemory(&li, sizeof(li)); 194 li.mask = LVIF_STATE; 195 li.stateMask = (UINT)-1; 196 li.state = LVIS_FOCUSED|LVIS_SELECTED; 197 (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 198 } 199 200 VOID 201 CNetConnectionPropertyUi::ShowNetworkComponentProperties(HWND hwndDlg) 202 { 203 LVITEMW lvItem; 204 HWND hDlgCtrl; 205 UINT Index, Count; 206 HRESULT hr; 207 INetCfgComponent *pNCfgComp; 208 PNET_ITEM pItem; 209 210 hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMPONENTSLIST); 211 Count = ListView_GetItemCount(hDlgCtrl); 212 if (!Count) 213 return; 214 215 ZeroMemory(&lvItem, sizeof(LVITEMW)); 216 lvItem.mask = LVIF_PARAM | LVIF_STATE; 217 lvItem.stateMask = (UINT)-1; 218 for (Index = 0; Index < Count; Index++) 219 { 220 lvItem.iItem = Index; 221 if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&lvItem)) 222 { 223 if (lvItem.state & LVIS_SELECTED) 224 break; 225 } 226 } 227 228 if (!(lvItem.state & LVIS_SELECTED)) 229 { 230 return; 231 } 232 233 pItem = (PNET_ITEM)lvItem.lParam; 234 pNCfgComp = (INetCfgComponent*)pItem->pNCfgComp; 235 hr = pNCfgComp->RaisePropertyUi(GetParent(hwndDlg), NCRP_QUERY_PROPERTY_UI, (INetConnectionConnectUi*)this); 236 if (SUCCEEDED(hr)) 237 { 238 hr = pNCfgComp->RaisePropertyUi(GetParent(hwndDlg), NCRP_SHOW_PROPERTY_UI, (INetConnectionConnectUi*)this); 239 } 240 } 241 242 INT_PTR 243 CALLBACK 244 CNetConnectionPropertyUi::LANPropertiesUIDlg( 245 HWND hwndDlg, 246 UINT uMsg, 247 WPARAM wParam, 248 LPARAM lParam) 249 { 250 PROPSHEETPAGE *page; 251 LPNMLISTVIEW lppl; 252 LVITEMW li; 253 PNET_ITEM pItem; 254 CNetConnectionPropertyUi * This; 255 LPPSHNOTIFY lppsn; 256 DWORD dwShowIcon, dwNotifyDisconnect; 257 HRESULT hr; 258 WCHAR szKey[200]; 259 LPOLESTR pStr; 260 HKEY hKey; 261 262 switch (uMsg) 263 { 264 case WM_INITDIALOG: 265 page = (PROPSHEETPAGE*)lParam; 266 This = (CNetConnectionPropertyUi*)page->lParam; 267 This->InitializeLANPropertiesUIDlg(hwndDlg); 268 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)This); 269 return TRUE; 270 case WM_NOTIFY: 271 lppl = (LPNMLISTVIEW) lParam; 272 lppsn = (LPPSHNOTIFY) lParam; 273 if (lppsn->hdr.code == PSN_APPLY) 274 { 275 This = (CNetConnectionPropertyUi*)GetWindowLongPtr(hwndDlg, DWLP_USER); 276 if (This->m_pNCfg) 277 { 278 hr = This->m_pNCfg->Apply(); 279 if (FAILED(hr)) 280 return PSNRET_INVALID; 281 } 282 283 if (SendDlgItemMessageW(hwndDlg, IDC_SHOWTASKBAR, BM_GETCHECK, 0, 0) == BST_CHECKED) 284 dwShowIcon = 1; 285 else 286 dwShowIcon = 0; 287 288 if (SendDlgItemMessageW(hwndDlg, IDC_NOTIFYNOCONNECTION, BM_GETCHECK, 0, 0) == BST_CHECKED) 289 dwNotifyDisconnect = 1; 290 else 291 dwNotifyDisconnect = 0; 292 293 //NOTE: Windows write these setting with the undocumented INetLanConnection::SetInfo 294 if (StringFromCLSID((CLSID)This->m_pProperties->guidId, &pStr) == ERROR_SUCCESS) 295 { 296 swprintf(szKey, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pStr); 297 CoTaskMemFree(pStr); 298 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKey, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) 299 { 300 RegSetValueExW(hKey, L"ShowIcon", 0, REG_DWORD, (LPBYTE)&dwShowIcon, sizeof(DWORD)); 301 RegSetValueExW(hKey, L"IpCheckingEnabled", 0, REG_DWORD, (LPBYTE)&dwNotifyDisconnect, sizeof(DWORD)); 302 RegCloseKey(hKey); 303 } 304 } 305 306 return PSNRET_NOERROR; 307 } 308 #if 0 309 else if (lppsn->hdr.code == PSN_CANCEL) 310 { 311 This = (CNetConnectionPropertyUi*)GetWindowLongPtr(hwndDlg, DWLP_USER); 312 if (This->m_pNCfg) 313 { 314 hr = This->m_pNCfg->Cancel(); 315 if (SUCCEEDED(hr)) 316 return PSNRET_NOERROR; 317 else 318 return PSNRET_INVALID; 319 } 320 return PSNRET_NOERROR; 321 } 322 #endif 323 if (lppl->hdr.code == LVN_ITEMCHANGING) 324 { 325 ZeroMemory(&li, sizeof(li)); 326 li.mask = LVIF_PARAM; 327 li.iItem = lppl->iItem; 328 if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&li)) 329 return TRUE; 330 331 pItem = (PNET_ITEM)li.lParam; 332 if (!pItem) 333 return TRUE; 334 335 if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED)) 336 { 337 /* new focused item */ 338 if (pItem->dwCharacteristics & NCF_NOT_USER_REMOVABLE) 339 EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALL), FALSE); 340 else 341 EnableWindow(GetDlgItem(hwndDlg, IDC_UNINSTALL), TRUE); 342 343 if (pItem->dwCharacteristics & NCF_HAS_UI) 344 EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTIES), TRUE); 345 else 346 EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTIES), FALSE); 347 348 SendDlgItemMessageW(hwndDlg, IDC_DESCRIPTION, WM_SETTEXT, 0, (LPARAM)pItem->szHelp); 349 } 350 } 351 break; 352 case WM_COMMAND: 353 if (LOWORD(wParam) == IDC_PROPERTIES) 354 { 355 This = (CNetConnectionPropertyUi*) GetWindowLongPtr(hwndDlg, DWLP_USER); 356 This->ShowNetworkComponentProperties(hwndDlg); 357 return FALSE; 358 } 359 else if (LOWORD(wParam) == IDC_CONFIGURE) 360 { 361 LPOLESTR DeviceInstanceID; 362 This = (CNetConnectionPropertyUi*)GetWindowLongPtr(hwndDlg, DWLP_USER); 363 364 if (This->GetDeviceInstanceID(&DeviceInstanceID)) 365 { 366 WCHAR wszCmd[2*MAX_PATH]; 367 StringCbPrintfW(wszCmd, sizeof(wszCmd), L"rundll32.exe devmgr.dll,DeviceProperties_RunDLL /DeviceID %s", DeviceInstanceID); 368 CoTaskMemFree(DeviceInstanceID); 369 370 STARTUPINFOW si; 371 PROCESS_INFORMATION pi; 372 ZeroMemory(&si, sizeof(si)); 373 si.cb = sizeof(si); 374 if (!CreateProcessW(NULL, wszCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 375 break; 376 377 CloseHandle(pi.hProcess); 378 CloseHandle(pi.hThread); 379 } 380 } 381 break; 382 } 383 return FALSE; 384 } 385 386 BOOL 387 CNetConnectionPropertyUi::GetDeviceInstanceID( 388 OUT LPOLESTR *DeviceInstanceID) 389 { 390 LPOLESTR pStr, pResult; 391 HKEY hKey; 392 DWORD dwInstanceID; 393 WCHAR szKeyName[2*MAX_PATH]; 394 WCHAR szInstanceID[2*MAX_PATH]; 395 396 if (StringFromCLSID(m_pProperties->guidId, &pStr) != ERROR_SUCCESS) 397 { 398 // failed to convert guid to string 399 return FALSE; 400 } 401 402 StringCbPrintfW(szKeyName, sizeof(szKeyName), L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pStr); 403 CoTaskMemFree(pStr); 404 405 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 406 { 407 // failed to open key 408 return FALSE; 409 } 410 411 dwInstanceID = sizeof(szInstanceID); 412 if (RegGetValueW(hKey, NULL, L"PnpInstanceId", RRF_RT_REG_SZ, NULL, (PVOID)szInstanceID, &dwInstanceID) == ERROR_SUCCESS) 413 { 414 szInstanceID[MAX_PATH-1] = L'\0'; 415 pResult = static_cast<LPOLESTR>(CoTaskMemAlloc((wcslen(szInstanceID) + 1) * sizeof(WCHAR))); 416 if (pResult != 0) 417 { 418 wcscpy(pResult, szInstanceID); 419 *DeviceInstanceID = pResult; 420 RegCloseKey(hKey); 421 return TRUE; 422 } 423 } 424 RegCloseKey(hKey); 425 return FALSE; 426 } 427 428 HRESULT 429 WINAPI 430 CNetConnectionPropertyUi::AddPages( 431 HWND hwndParent, 432 LPFNADDPROPSHEETPAGE pfnAddPage, 433 LPARAM lParam) 434 { 435 HPROPSHEETPAGE hProp; 436 BOOL ret; 437 HRESULT hr = E_FAIL; 438 INITCOMMONCONTROLSEX initEx; 439 440 initEx.dwSize = sizeof(initEx); 441 initEx.dwICC = ICC_LISTVIEW_CLASSES; 442 if (!InitCommonControlsEx(&initEx)) 443 return E_FAIL; 444 445 hr = m_pCon->GetProperties(&m_pProperties); 446 if (FAILED_UNEXPECTEDLY(hr)) 447 return hr; 448 449 hProp = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_NETPROPERTIES), LANPropertiesUIDlg, reinterpret_cast<LPARAM>(this), NULL); 450 if (hProp) 451 { 452 ret = (*pfnAddPage)(hProp, lParam); 453 if (ret) 454 { 455 hr = NOERROR; 456 } 457 else 458 { 459 DestroyPropertySheetPage(hProp); 460 } 461 } 462 return hr; 463 } 464 465 HRESULT 466 WINAPI 467 CNetConnectionPropertyUi::GetIcon( 468 DWORD dwSize, 469 HICON *phIcon) 470 { 471 return E_NOTIMPL; 472 } 473 474 HRESULT 475 WINAPI 476 CNetConnectionPropertyUi::GetDeviceGuid(GUID *pGuid) 477 { 478 CopyMemory(pGuid, &m_pProperties->guidId, sizeof(GUID)); 479 return S_OK; 480 } 481 482 HRESULT 483 WINAPI 484 CNetConnectionPropertyUi::SetConnection(INetConnection* pCon) 485 { 486 if (!pCon) 487 return E_POINTER; 488 489 m_pCon = pCon; 490 return S_OK; 491 } 492 493 HRESULT 494 WINAPI 495 CNetConnectionPropertyUi::Connect( 496 HWND hwndParent, 497 DWORD dwFlags) 498 { 499 if (!m_pCon) 500 return E_POINTER; //FIXME 501 502 if (dwFlags & NCUC_NO_UI) 503 return m_pCon->Connect(); 504 505 return E_FAIL; 506 } 507 508 HRESULT 509 WINAPI 510 CNetConnectionPropertyUi::Disconnect( 511 HWND hwndParent, 512 DWORD dwFlags) 513 { 514 WCHAR szBuffer[100]; 515 swprintf(szBuffer, L"INetConnectionConnectUi_fnDisconnect flags %x\n", dwFlags); 516 MessageBoxW(NULL, szBuffer, NULL, MB_OK); 517 518 return S_OK; 519 } 520