1 /* 2 * PROJECT: ReactOS Shell 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: CLanStatus: Lan connection status dialog 5 * COPYRIGHT: Copyright 2008 Johannes Anderwald (johannes.anderwald@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 #include <winsock.h> 11 12 CLanStatus::CLanStatus() : 13 m_lpNetMan(NULL), 14 m_pHead(NULL) 15 { 16 } 17 18 VOID 19 UpdateLanStatusUiDlg( 20 HWND hwndDlg, 21 MIB_IFROW *IfEntry, 22 LANSTATUSUI_CONTEXT *pContext) 23 { 24 WCHAR szFormat[MAX_PATH] = {0}; 25 WCHAR szBuffer[MAX_PATH] = {0}; 26 SYSTEMTIME TimeConnected; 27 DWORD DurationSeconds; 28 WCHAR Buffer[100]; 29 WCHAR DayBuffer[30]; 30 WCHAR LocBuffer[50]; 31 32 #if 0 33 ULONGLONG Ticks; 34 #else 35 DWORD Ticks; 36 #endif 37 38 if (IfEntry->dwSpeed < 1000) 39 { 40 if (LoadStringW(netshell_hInstance, IDS_FORMAT_BIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 41 { 42 swprintf(szBuffer, szFormat, IfEntry->dwSpeed); 43 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 44 } 45 } 46 else if (IfEntry->dwSpeed < 1000000) 47 { 48 if (LoadStringW(netshell_hInstance, IDS_FORMAT_KBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 49 { 50 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000); 51 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 52 } 53 } 54 else if (IfEntry->dwSpeed < 1000000000) 55 { 56 if (LoadStringW(netshell_hInstance, IDS_FORMAT_MBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 57 { 58 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000000); 59 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 60 } 61 } 62 else 63 { 64 if (LoadStringW(netshell_hInstance, IDS_FORMAT_GBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 65 { 66 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000000000); 67 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 68 } 69 } 70 71 if (StrFormatByteSizeW(IfEntry->dwInOctets, szBuffer, sizeof(szFormat)/sizeof(WCHAR))) 72 { 73 SendDlgItemMessageW(hwndDlg, IDC_RECEIVED, WM_SETTEXT, 0, (LPARAM)szBuffer); 74 } 75 76 if (StrFormatByteSizeW(IfEntry->dwOutOctets, szBuffer, sizeof(szFormat)/sizeof(WCHAR))) 77 { 78 SendDlgItemMessageW(hwndDlg, IDC_SEND, WM_SETTEXT, 0, (LPARAM)szBuffer); 79 } 80 81 #if 0 82 Ticks = GetTickCount64(); 83 #else 84 Ticks = GetTickCount(); 85 #endif 86 87 DurationSeconds = Ticks / 1000; 88 TimeConnected.wSecond = (DurationSeconds % 60); 89 TimeConnected.wMinute = (DurationSeconds / 60) % 60; 90 TimeConnected.wHour = (DurationSeconds / (60 * 60)) % 24; 91 TimeConnected.wDay = DurationSeconds / (60 * 60 * 24); 92 93 if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &TimeConnected, L"HH':'mm':'ss", LocBuffer, sizeof(LocBuffer) / sizeof(LocBuffer[0]))) 94 return; 95 96 if (!TimeConnected.wDay) 97 { 98 SendDlgItemMessageW(hwndDlg, IDC_DURATION, WM_SETTEXT, 0, (LPARAM)LocBuffer); 99 } 100 else 101 { 102 if (TimeConnected.wDay == 1) 103 { 104 if (!LoadStringW(netshell_hInstance, IDS_DURATION_DAY, DayBuffer, sizeof(DayBuffer) / sizeof(DayBuffer[0]))) 105 DayBuffer[0] = L'\0'; 106 } 107 else 108 { 109 if (!LoadStringW(netshell_hInstance, IDS_DURATION_DAYS, DayBuffer, sizeof(DayBuffer) / sizeof(DayBuffer[0]))) 110 DayBuffer[0] = L'\0'; 111 } 112 swprintf(Buffer, DayBuffer, TimeConnected.wDay, LocBuffer); 113 SendDlgItemMessageW(hwndDlg, IDC_DURATION, WM_SETTEXT, 0, (LPARAM)Buffer); 114 } 115 116 } 117 118 VOID 119 UpdateLanStatus(HWND hwndDlg, LANSTATUSUI_CONTEXT * pContext) 120 { 121 MIB_IFROW IfEntry; 122 HICON hIcon, hOldIcon = NULL; 123 NOTIFYICONDATAW nid; 124 NETCON_PROPERTIES * pProperties = NULL; 125 126 ZeroMemory(&IfEntry, sizeof(IfEntry)); 127 IfEntry.dwIndex = pContext->dwAdapterIndex; 128 if (GetIfEntry(&IfEntry) != NO_ERROR) 129 { 130 return; 131 } 132 133 hIcon = NULL; 134 if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) 135 { 136 if (pContext->dwInOctets == IfEntry.dwInOctets && pContext->dwOutOctets == IfEntry.dwOutOctets && pContext->Status != 0) 137 { 138 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 32, 32, LR_SHARED); 139 pContext->Status = 0; 140 } 141 else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status != 1) 142 { 143 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANSREC), IMAGE_ICON, 32, 32, LR_SHARED); 144 pContext->Status = 1; 145 } 146 else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->Status != 2) 147 { 148 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_REC), IMAGE_ICON, 32, 32, LR_SHARED); 149 pContext->Status = 2; 150 } 151 else if (pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status != 3) 152 { 153 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANS), IMAGE_ICON, 32, 32, LR_SHARED); 154 pContext->Status = 3; 155 } 156 } 157 else if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_UNREACHABLE || IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_DISCONNECTED) 158 { 159 if (pContext->Status != 4) 160 { 161 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_SHARED); 162 pContext->Status = 4; 163 } 164 } 165 else if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_NON_OPERATIONAL) 166 { 167 if (pContext->Status != 5) 168 { 169 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_SHARED); 170 pContext->Status = 5; 171 } 172 } 173 174 if (hwndDlg && hIcon) 175 { 176 hOldIcon = (HICON)SendDlgItemMessageW(hwndDlg, IDC_NETSTAT, STM_SETICON, (WPARAM)hIcon, 0); 177 if (hOldIcon) 178 DestroyIcon(hOldIcon); 179 } 180 181 ZeroMemory(&nid, sizeof(nid)); 182 nid.cbSize = sizeof(nid); 183 nid.uID = pContext->uID; 184 nid.hWnd = pContext->hwndStatusDlg; 185 nid.uVersion = NOTIFYICON_VERSION; 186 187 if (pContext->pNet->GetProperties(&pProperties) == S_OK) 188 { 189 if (pProperties->dwCharacter & NCCF_SHOW_ICON) 190 { 191 if (hwndDlg) 192 nid.hIcon = (HICON)CopyImage(hIcon, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); 193 else 194 nid.hIcon = hIcon; 195 196 if (nid.hIcon) 197 nid.uFlags |= NIF_ICON; 198 199 nid.uFlags |= NIF_STATE; 200 nid.dwState = 0; 201 nid.dwStateMask = NIS_HIDDEN; 202 203 if (pProperties->pszwName) 204 { 205 if (wcslen(pProperties->pszwName) * sizeof(WCHAR) < sizeof(nid.szTip)) 206 { 207 nid.uFlags |= NIF_TIP; 208 wcscpy(nid.szTip, pProperties->pszwName); 209 } 210 else 211 { 212 CopyMemory(nid.szTip, pProperties->pszwName, sizeof(nid.szTip) - sizeof(WCHAR)); 213 nid.szTip[(sizeof(nid.szTip)/sizeof(WCHAR))-1] = L'\0'; 214 nid.uFlags |= NIF_TIP; 215 } 216 } 217 } 218 else 219 { 220 nid.uFlags |= NIF_STATE; 221 nid.dwState = NIS_HIDDEN; 222 nid.dwStateMask = NIS_HIDDEN; 223 224 } 225 NcFreeNetconProperties(pProperties); 226 } 227 228 Shell_NotifyIconW(NIM_MODIFY, &nid); 229 230 if (nid.uFlags & NIF_ICON) 231 DestroyIcon(nid.hIcon); 232 233 pContext->dwInOctets = IfEntry.dwInOctets; 234 pContext->dwOutOctets = IfEntry.dwOutOctets; 235 236 if (hwndDlg) 237 UpdateLanStatusUiDlg(hwndDlg, &IfEntry, pContext); 238 } 239 240 241 VOID 242 InitializeLANStatusUiDlg(HWND hwndDlg, LANSTATUSUI_CONTEXT * pContext) 243 { 244 WCHAR szBuffer[MAX_PATH] = {0}; 245 NETCON_PROPERTIES * pProperties; 246 247 if (pContext->pNet->GetProperties(&pProperties) != S_OK) 248 return; 249 250 if (pProperties->Status == NCS_DISCONNECTED) 251 LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, szBuffer, MAX_PATH); 252 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED) 253 LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, szBuffer, MAX_PATH); 254 else if (pProperties->Status == NCS_CONNECTING) 255 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, szBuffer, MAX_PATH); 256 else if (pProperties->Status == NCS_CONNECTED) 257 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, szBuffer, MAX_PATH); 258 259 SendDlgItemMessageW(hwndDlg, IDC_STATUS, WM_SETTEXT, 0, (LPARAM)szBuffer); 260 261 pContext->dwInOctets = 0; 262 pContext->dwOutOctets = 0; 263 264 /* update adapter info */ 265 pContext->Status = -1; 266 UpdateLanStatus(hwndDlg, pContext); 267 NcFreeNetconProperties(pProperties); 268 } 269 270 static 271 VOID 272 InsertColumnToListView( 273 HWND hDlgCtrl, 274 UINT ResId, 275 UINT SubItem, 276 UINT Size) 277 { 278 WCHAR szBuffer[200]; 279 LVCOLUMNW lc; 280 281 if (!LoadStringW(netshell_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 282 return; 283 284 memset(&lc, 0, sizeof(LV_COLUMN) ); 285 lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT; 286 lc.iSubItem = SubItem; 287 lc.fmt = LVCFMT_FIXED_WIDTH; 288 lc.cx = Size; 289 lc.cchTextMax = wcslen(szBuffer); 290 lc.pszText = szBuffer; 291 292 (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, SubItem, (LPARAM)&lc); 293 } 294 295 static 296 VOID 297 AddIPAddressToListView( 298 HWND hDlgCtrl, 299 PIP_ADDR_STRING pAddr, 300 INT Index) 301 { 302 LVITEMW li; 303 PIP_ADDR_STRING pCur; 304 WCHAR szBuffer[100]; 305 UINT SubIndex; 306 307 ZeroMemory(&li, sizeof(LVITEMW)); 308 li.mask = LVIF_TEXT; 309 li.iItem = Index; 310 pCur = pAddr; 311 SubIndex = 0; 312 313 do 314 { 315 if (SubIndex) 316 { 317 ZeroMemory(&li, sizeof(LVITEMW)); 318 li.mask = LVIF_TEXT; 319 li.iItem = Index; 320 li.iSubItem = 0; 321 li.pszText = (LPWSTR)L""; 322 li.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li); 323 } 324 325 if (MultiByteToWideChar(CP_ACP, 0, pCur->IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 326 { 327 li.pszText = szBuffer; 328 li.iSubItem = 1; 329 li.iItem = Index++; 330 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 331 } 332 SubIndex++; 333 pCur = pCur->Next; 334 } while (pCur && pCur->IpAddress.String[0]); 335 } 336 337 static 338 INT 339 InsertItemToListView( 340 HWND hDlgCtrl, 341 UINT ResId) 342 { 343 LVITEMW li; 344 WCHAR szBuffer[100]; 345 346 ZeroMemory(&li, sizeof(LVITEMW)); 347 li.mask = LVIF_TEXT; 348 li.iItem = ListView_GetItemCount(hDlgCtrl); 349 if (LoadStringW(netshell_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 350 { 351 li.pszText = szBuffer; 352 return (INT)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li); 353 } 354 return -1; 355 } 356 357 358 INT_PTR 359 CALLBACK 360 LANStatusUiDetailsDlg( 361 HWND hwndDlg, 362 UINT uMsg, 363 WPARAM wParam, 364 LPARAM lParam 365 ) 366 { 367 LANSTATUSUI_CONTEXT * pContext; 368 LVITEMW li; 369 WCHAR szBuffer[100]; 370 PIP_ADAPTER_INFO pAdapterInfo, pCurAdapter; 371 PIP_PER_ADAPTER_INFO pPerAdapter; 372 DWORD dwSize; 373 HWND hDlgCtrl; 374 RECT rect; 375 376 switch (uMsg) 377 { 378 case WM_INITDIALOG: 379 pContext = (LANSTATUSUI_CONTEXT*)lParam; 380 381 hDlgCtrl = GetDlgItem(hwndDlg, IDC_DETAILS); 382 383 /* get client rect */ 384 GetClientRect(hDlgCtrl, &rect); 385 386 /* calculate column width */ 387 dwSize = rect.right / 2; 388 389 InsertColumnToListView(hDlgCtrl, IDS_PROPERTY, 0, dwSize); 390 InsertColumnToListView(hDlgCtrl, IDS_VALUE, 1, dwSize); 391 392 dwSize = 0; 393 pCurAdapter = NULL; 394 pAdapterInfo = NULL; 395 if (GetAdaptersInfo(NULL, &dwSize) == ERROR_BUFFER_OVERFLOW) 396 { 397 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 398 if (pAdapterInfo) 399 { 400 if (GetAdaptersInfo(pAdapterInfo, &dwSize) == NO_ERROR) 401 { 402 pCurAdapter = pAdapterInfo; 403 while (pCurAdapter && pCurAdapter->Index != pContext->dwAdapterIndex) 404 pCurAdapter = pCurAdapter->Next; 405 406 if (pCurAdapter->Index != pContext->dwAdapterIndex) 407 pCurAdapter = NULL; 408 } 409 } 410 } 411 412 ZeroMemory(&li, sizeof(LVITEMW)); 413 li.mask = LVIF_TEXT; 414 li.iSubItem = 1; 415 li.pszText = szBuffer; 416 417 if (pCurAdapter) 418 { 419 li.iItem = InsertItemToListView(hDlgCtrl, IDS_PHYSICAL_ADDRESS); 420 if (li.iItem >= 0) 421 { 422 swprintf(szBuffer, L"%02x-%02x-%02x-%02x-%02x-%02x",pCurAdapter->Address[0], pCurAdapter->Address[1], 423 pCurAdapter->Address[2], pCurAdapter->Address[3], pCurAdapter->Address[4], pCurAdapter->Address[5]); 424 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 425 } 426 li.iItem = InsertItemToListView(hDlgCtrl, IDS_IP_ADDRESS); 427 if (li.iItem >= 0) 428 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 429 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 430 431 li.iItem = InsertItemToListView(hDlgCtrl, IDS_SUBNET_MASK); 432 if (li.iItem >= 0) 433 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpMask.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 434 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 435 436 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DEF_GATEWAY); 437 if (li.iItem >= 0 && pCurAdapter->GatewayList.IpAddress.String[0] != '0') 438 { 439 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->GatewayList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 440 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 441 } 442 #if 0 443 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_OBTAINED); 444 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_EXPIRES); 445 #endif 446 } 447 448 dwSize = 0; 449 if (GetPerAdapterInfo(pContext->dwAdapterIndex, NULL, &dwSize) == ERROR_BUFFER_OVERFLOW) 450 { 451 pPerAdapter = static_cast<PIP_PER_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 452 if (pPerAdapter) 453 { 454 if (GetPerAdapterInfo(pContext->dwAdapterIndex, pPerAdapter, &dwSize) == ERROR_SUCCESS) 455 { 456 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DNS_SERVERS); 457 if (li.iItem >= 0) 458 AddIPAddressToListView(hDlgCtrl, &pPerAdapter->DnsServerList, li.iItem); 459 } 460 CoTaskMemFree(pPerAdapter); 461 } 462 } 463 #if 0 464 if (pCurAdapter) 465 { 466 li.iItem = InsertItemToListView(hDlgCtrl, IDS_WINS_SERVERS); 467 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->PrimaryWinsServer, li.iItem); 468 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->SecondaryWinsServer, li.iItem+1); 469 } 470 #endif 471 CoTaskMemFree(pAdapterInfo); 472 break; 473 case WM_COMMAND: 474 if (LOWORD(wParam) == IDC_CLOSE) 475 { 476 EndDialog(hwndDlg, FALSE); 477 break; 478 } 479 } 480 return FALSE; 481 } 482 483 INT_PTR 484 CALLBACK 485 LANStatusUiAdvancedDlg( 486 HWND hwndDlg, 487 UINT uMsg, 488 WPARAM wParam, 489 LPARAM lParam) 490 { 491 WCHAR szBuffer[100] = {0}; 492 PROPSHEETPAGE *page; 493 LANSTATUSUI_CONTEXT * pContext; 494 DWORD dwIpAddr; 495 496 497 switch (uMsg) 498 { 499 case WM_INITDIALOG: 500 page = (PROPSHEETPAGE*)lParam; 501 pContext = (LANSTATUSUI_CONTEXT*)page->lParam; 502 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext); 503 if (pContext->DHCPEnabled) 504 LoadStringW(netshell_hInstance, IDS_ASSIGNED_DHCP, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)); 505 else 506 LoadStringW(netshell_hInstance, IDS_ASSIGNED_MANUAL, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)); 507 508 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0'; 509 SendDlgItemMessageW(hwndDlg, IDC_DETAILSTYPE, WM_SETTEXT, 0, (LPARAM)szBuffer); 510 511 512 dwIpAddr = ntohl(pContext->IpAddress); 513 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), 514 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr)); 515 SendDlgItemMessageW(hwndDlg, IDC_DETAILSIP, WM_SETTEXT, 0, (LPARAM)szBuffer); 516 517 dwIpAddr = ntohl(pContext->SubnetMask); 518 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), 519 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr)); 520 SendDlgItemMessageW(hwndDlg, IDC_DETAILSSUBNET, WM_SETTEXT, 0, (LPARAM)szBuffer); 521 522 dwIpAddr = ntohl(pContext->Gateway); 523 if (dwIpAddr) 524 { 525 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), 526 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr)); 527 SendDlgItemMessageW(hwndDlg, IDC_DETAILSGATEWAY, WM_SETTEXT, 0, (LPARAM)szBuffer); 528 } 529 return TRUE; 530 case WM_COMMAND: 531 if (LOWORD(wParam) == IDC_DETAILS) 532 { 533 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 534 if (pContext) 535 { 536 DialogBoxParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_LAN_NETSTATUSDETAILS), GetParent(hwndDlg), 537 LANStatusUiDetailsDlg, (LPARAM)pContext); 538 } 539 } 540 break; 541 default: 542 break; 543 } 544 return FALSE; 545 } 546 547 VOID 548 DisableNetworkAdapter(INetConnection * pNet, LANSTATUSUI_CONTEXT * pContext, HWND hwndDlg) 549 { 550 HRESULT hr = pNet->Disconnect(); 551 if (FAILED_UNEXPECTEDLY(hr)) 552 return; 553 554 NOTIFYICONDATAW nid; 555 556 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_CANCEL); 557 ZeroMemory(&nid, sizeof(nid)); 558 nid.cbSize = sizeof(nid); 559 nid.uID = pContext->uID; 560 nid.hWnd = pContext->hwndDlg; 561 nid.uFlags = NIF_STATE; 562 nid.dwState = NIS_HIDDEN; 563 nid.dwStateMask = NIS_HIDDEN; 564 565 Shell_NotifyIconW(NIM_MODIFY, &nid); 566 } 567 568 569 INT_PTR 570 CALLBACK 571 LANStatusUiDlg( 572 HWND hwndDlg, 573 UINT uMsg, 574 WPARAM wParam, 575 LPARAM lParam) 576 { 577 PROPSHEETPAGE *page; 578 LANSTATUSUI_CONTEXT * pContext; 579 LPPSHNOTIFY lppsn; 580 581 switch (uMsg) 582 { 583 case WM_INITDIALOG: 584 page = (PROPSHEETPAGE*)lParam; 585 pContext = (LANSTATUSUI_CONTEXT*)page->lParam; 586 pContext->hwndDlg = hwndDlg; 587 InitializeLANStatusUiDlg(hwndDlg, pContext); 588 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext); 589 return TRUE; 590 case WM_COMMAND: 591 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 592 if (LOWORD(wParam) == IDC_STATUS_PROPERTIES) 593 { 594 if (pContext) 595 { 596 ShowNetConnectionProperties(pContext->pNet, GetParent(pContext->hwndDlg)); 597 BringWindowToTop(GetParent(pContext->hwndDlg)); 598 } 599 break; 600 } 601 else if (LOWORD(wParam) == IDC_ENDISABLE) 602 { 603 DisableNetworkAdapter(pContext->pNet, pContext, hwndDlg); 604 break; 605 } 606 case WM_NOTIFY: 607 lppsn = (LPPSHNOTIFY) lParam; 608 if (lppsn->hdr.code == PSN_APPLY || lppsn->hdr.code == PSN_RESET) 609 { 610 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 611 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); 612 pContext->hwndDlg = NULL; 613 return TRUE; 614 } 615 break; 616 } 617 return FALSE; 618 } 619 620 VOID 621 InitializePropertyDialog( 622 LANSTATUSUI_CONTEXT * pContext, 623 NETCON_PROPERTIES * pProperties) 624 { 625 DWORD dwSize, dwAdapterIndex, dwResult; 626 LPOLESTR pStr; 627 IP_ADAPTER_INFO *pAdapterInfo, *pCurAdapter; 628 629 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pStr))) 630 { 631 return; 632 } 633 634 /* get the IfTable */ 635 dwSize = 0; 636 dwResult = GetAdaptersInfo(NULL, &dwSize); 637 if (dwResult!= ERROR_BUFFER_OVERFLOW) 638 { 639 CoTaskMemFree(pStr); 640 return; 641 } 642 643 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 644 if (!pAdapterInfo) 645 { 646 CoTaskMemFree(pAdapterInfo); 647 CoTaskMemFree(pStr); 648 return; 649 } 650 651 if (GetAdaptersInfo(pAdapterInfo, &dwSize) != NO_ERROR) 652 { 653 CoTaskMemFree(pAdapterInfo); 654 CoTaskMemFree(pStr); 655 return; 656 } 657 658 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, pStr, &dwAdapterIndex)) 659 { 660 CoTaskMemFree(pAdapterInfo); 661 CoTaskMemFree(pStr); 662 return; 663 } 664 665 pCurAdapter = pAdapterInfo; 666 while (pCurAdapter->Index != dwAdapterIndex) 667 pCurAdapter = pCurAdapter->Next; 668 669 670 pContext->IpAddress = inet_addr(pCurAdapter->IpAddressList.IpAddress.String); 671 pContext->SubnetMask = inet_addr(pCurAdapter->IpAddressList.IpMask.String); 672 pContext->Gateway = inet_addr(pCurAdapter->GatewayList.IpAddress.String); 673 pContext->DHCPEnabled = pCurAdapter->DhcpEnabled; 674 CoTaskMemFree(pStr); 675 CoTaskMemFree(pAdapterInfo); 676 pContext->dwAdapterIndex = dwAdapterIndex; 677 } 678 679 static int CALLBACK 680 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 681 { 682 // NOTE: This callback is needed to set large icon correctly. 683 HICON hIcon; 684 switch (uMsg) 685 { 686 case PSCB_INITIALIZED: 687 { 688 hIcon = LoadIconW(netshell_hInstance, MAKEINTRESOURCEW(IDI_NET_IDLE)); 689 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 690 break; 691 } 692 } 693 return 0; 694 } 695 696 VOID 697 ShowStatusPropertyDialog( 698 LANSTATUSUI_CONTEXT *pContext, 699 HWND hwndDlg) 700 { 701 HPROPSHEETPAGE hppages[2]; 702 PROPSHEETHEADERW pinfo; 703 NETCON_PROPERTIES * pProperties = NULL; 704 705 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW)); 706 ZeroMemory(hppages, sizeof(hppages)); 707 pinfo.dwSize = sizeof(PROPSHEETHEADERW); 708 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW | 709 PSH_USEICONID | PSH_USECALLBACK; 710 pinfo.phpage = hppages; 711 pinfo.hwndParent = hwndDlg; 712 pinfo.hInstance = netshell_hInstance; 713 pinfo.pszIcon = MAKEINTRESOURCEW(IDI_NET_IDLE); 714 pinfo.pfnCallback = PropSheetProc; 715 716 if (pContext->pNet->GetProperties(&pProperties) == S_OK) 717 { 718 if (pProperties->pszwName) 719 { 720 pinfo.pszCaption = pProperties->pszwName; 721 pinfo.dwFlags |= PSH_PROPTITLE; 722 } 723 InitializePropertyDialog(pContext, pProperties); 724 if (pProperties->MediaType == NCM_LAN && pProperties->Status == NCS_CONNECTED) 725 { 726 hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUS), LANStatusUiDlg, (LPARAM)pContext, NULL); 727 if (hppages[0]) 728 pinfo.nPages++; 729 730 hppages[pinfo.nPages] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUSADVANCED), LANStatusUiAdvancedDlg, (LPARAM)pContext, NULL); 731 if (hppages[pinfo.nPages]) 732 pinfo.nPages++; 733 734 if (pinfo.nPages) 735 { 736 PropertySheetW(&pinfo); 737 } 738 } 739 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED || 740 pProperties->Status == NCS_HARDWARE_DISABLED) 741 { 742 ShowNetConnectionProperties(pContext->pNet, pContext->hwndDlg); 743 } 744 745 NcFreeNetconProperties(pProperties); 746 } 747 } 748 749 INT_PTR 750 CALLBACK 751 LANStatusDlg( 752 HWND hwndDlg, 753 UINT uMsg, 754 WPARAM wParam, 755 LPARAM lParam) 756 { 757 LANSTATUSUI_CONTEXT * pContext; 758 759 switch (uMsg) 760 { 761 case WM_INITDIALOG: 762 pContext = (LANSTATUSUI_CONTEXT *)lParam; 763 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); 764 pContext->nIDEvent = SetTimer(hwndDlg, 0xFABC, 1000, NULL); 765 return TRUE; 766 case WM_TIMER: 767 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 768 if (wParam == (WPARAM)pContext->nIDEvent) 769 { 770 UpdateLanStatus(pContext->hwndDlg, pContext); 771 } 772 break; 773 case WM_SHOWSTATUSDLG: 774 if (LOWORD(lParam) == WM_LBUTTONDOWN) 775 { 776 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 777 if (!pContext) 778 break; 779 780 if (pContext->hwndDlg) 781 { 782 ShowWindow(GetParent(pContext->hwndDlg), SW_SHOW); 783 BringWindowToTop(GetParent(pContext->hwndDlg)); 784 } 785 else 786 { 787 ShowStatusPropertyDialog(pContext, hwndDlg); 788 } 789 break; 790 } 791 break; 792 } 793 return FALSE; 794 } 795 796 HRESULT 797 CLanStatus::InitializeNetTaskbarNotifications() 798 { 799 NOTIFYICONDATAW nid; 800 HWND hwndDlg; 801 CComPtr<INetConnectionManager> pNetConMan; 802 CComPtr<IEnumNetConnection> pEnumCon; 803 CComPtr<INetConnection> pNetCon; 804 NETCON_PROPERTIES* pProps; 805 HRESULT hr; 806 ULONG Count; 807 ULONG Index; 808 NOTIFICATION_ITEM * pItem, *pLast = NULL; 809 LANSTATUSUI_CONTEXT * pContext; 810 811 TRACE("InitializeNetTaskbarNotifications\n"); 812 813 if (m_pHead) 814 { 815 pItem = m_pHead; 816 while (pItem) 817 { 818 hr = pItem->pNet->GetProperties(&pProps); 819 if (SUCCEEDED(hr)) 820 { 821 ZeroMemory(&nid, sizeof(nid)); 822 nid.cbSize = sizeof(nid); 823 nid.uID = pItem->uID; 824 nid.hWnd = pItem->hwndDlg; 825 nid.uFlags = NIF_STATE; 826 if (pProps->dwCharacter & NCCF_SHOW_ICON) 827 nid.dwState = 0; 828 else 829 nid.dwState = NIS_HIDDEN; 830 831 nid.dwStateMask = NIS_HIDDEN; 832 Shell_NotifyIconW(NIM_MODIFY, &nid); 833 NcFreeNetconProperties(pProps); 834 } 835 pItem = pItem->pNext; 836 } 837 return S_OK; 838 } 839 /* get an instance to of IConnectionManager */ 840 hr = CNetConnectionManager_CreateInstance(IID_PPV_ARG(INetConnectionManager, &pNetConMan)); 841 if (FAILED_UNEXPECTEDLY(hr)) 842 return hr; 843 844 hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon); 845 if (FAILED_UNEXPECTEDLY(hr)) 846 return hr; 847 848 Index = 1; 849 while (TRUE) 850 { 851 hr = pEnumCon->Next(1, &pNetCon, &Count); 852 if (hr != S_OK) 853 break; 854 855 TRACE("new connection\n"); 856 pItem = static_cast<NOTIFICATION_ITEM*>(CoTaskMemAlloc(sizeof(NOTIFICATION_ITEM))); 857 if (!pItem) 858 break; 859 860 pContext = static_cast<LANSTATUSUI_CONTEXT*>(CoTaskMemAlloc(sizeof(LANSTATUSUI_CONTEXT))); 861 if (!pContext) 862 { 863 CoTaskMemFree(pItem); 864 break; 865 } 866 867 ZeroMemory(pContext, sizeof(LANSTATUSUI_CONTEXT)); 868 pContext->uID = Index; 869 pContext->pNet = pNetCon; 870 pItem->uID = Index; 871 pItem->pNext = NULL; 872 pItem->pNet = pNetCon; 873 pNetCon->AddRef(); 874 hwndDlg = CreateDialogParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_STATUS), NULL, LANStatusDlg, (LPARAM)pContext); 875 if (!hwndDlg) 876 { 877 ERR("CreateDialogParamW failed\n"); 878 continue; 879 } 880 881 ZeroMemory(&nid, sizeof(nid)); 882 nid.cbSize = sizeof(nid); 883 nid.uID = Index++; 884 nid.uFlags = NIF_MESSAGE; 885 nid.uVersion = NOTIFYICON_VERSION; 886 nid.uCallbackMessage = WM_SHOWSTATUSDLG; 887 nid.hWnd = hwndDlg; 888 889 hr = pNetCon->GetProperties(&pProps); 890 if (SUCCEEDED(hr)) 891 { 892 CopyMemory(&pItem->guidItem, &pProps->guidId, sizeof(GUID)); 893 if (!(pProps->dwCharacter & NCCF_SHOW_ICON)) 894 { 895 nid.dwState = NIS_HIDDEN; 896 nid.dwStateMask = NIS_HIDDEN; 897 nid.uFlags |= NIF_STATE; 898 } 899 if (pProps->Status == NCS_MEDIA_DISCONNECTED || pProps->Status == NCS_DISCONNECTED || pProps->Status == NCS_HARDWARE_DISABLED) 900 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF)); 901 else if (pProps->Status == NCS_CONNECTED) 902 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE)); 903 904 if (nid.hIcon) 905 nid.uFlags |= NIF_ICON; 906 907 wcscpy(nid.szTip, pProps->pszwName); 908 nid.uFlags |= NIF_TIP; 909 } 910 pContext->hwndStatusDlg = hwndDlg; 911 pItem->hwndDlg = hwndDlg; 912 913 if (Shell_NotifyIconW(NIM_ADD, &nid)) 914 { 915 if (pLast) 916 pLast->pNext = pItem; 917 else 918 m_pHead = pItem; 919 920 pLast = pItem; 921 Index++; 922 } 923 else 924 { 925 ERR("Shell_NotifyIconW failed\n"); 926 CoTaskMemFree(pItem); 927 } 928 929 if (nid.uFlags & NIF_ICON) 930 DestroyIcon(nid.hIcon); 931 } 932 933 m_lpNetMan = pNetConMan; 934 return S_OK; 935 } 936 937 HRESULT 938 CLanStatus::ShowStatusDialogByCLSID(const GUID *pguidCmdGroup) 939 { 940 NOTIFICATION_ITEM *pItem; 941 942 pItem = m_pHead; 943 while (pItem) 944 { 945 if (IsEqualGUID(pItem->guidItem, *pguidCmdGroup)) 946 { 947 SendMessageW(pItem->hwndDlg, WM_SHOWSTATUSDLG, 0, WM_LBUTTONDOWN); 948 return S_OK; 949 } 950 pItem = pItem->pNext; 951 } 952 953 ERR("not found\n"); 954 return E_FAIL; 955 } 956 957 HRESULT 958 WINAPI 959 CLanStatus::QueryStatus( 960 const GUID *pguidCmdGroup, 961 ULONG cCmds, 962 OLECMD *prgCmds, 963 OLECMDTEXT *pCmdText) 964 { 965 MessageBoxW(NULL, pCmdText->rgwz, L"IOleCommandTarget_fnQueryStatus", MB_OK); 966 return E_NOTIMPL; 967 } 968 969 HRESULT 970 WINAPI 971 CLanStatus::Exec( 972 const GUID *pguidCmdGroup, 973 DWORD nCmdID, 974 DWORD nCmdexecopt, 975 VARIANT *pvaIn, 976 VARIANT *pvaOut) 977 { 978 if (pguidCmdGroup) 979 { 980 if (IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject)) 981 { 982 return InitializeNetTaskbarNotifications(); 983 } 984 else 985 { 986 /* invoke status dialog */ 987 return ShowStatusDialogByCLSID(pguidCmdGroup); 988 } 989 } 990 return S_OK; 991 } 992