Reactos
at master 1271 lines 40 kB view raw
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#define NETTIMERID 0xFABC 13 14CLanStatus::CLanStatus() : 15 m_lpNetMan(NULL), 16 m_pHead(NULL) 17{ 18} 19 20VOID 21UpdateLanStatusUiDlg( 22 HWND hwndDlg, 23 MIB_IFROW *IfEntry, 24 LANSTATUSUI_CONTEXT *pContext) 25{ 26 WCHAR szFormat[MAX_PATH] = {0}; 27 WCHAR szBuffer[MAX_PATH] = {0}; 28 SYSTEMTIME TimeConnected; 29 DWORD DurationSeconds; 30 WCHAR Buffer[100]; 31 WCHAR DayBuffer[30]; 32 WCHAR LocBuffer[50]; 33 34#if 0 35 ULONGLONG Ticks; 36#else 37 DWORD Ticks; 38#endif 39 40 if (IfEntry->dwSpeed < 1000) 41 { 42 if (LoadStringW(netshell_hInstance, IDS_FORMAT_BIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 43 { 44 swprintf(szBuffer, szFormat, IfEntry->dwSpeed); 45 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 46 } 47 } 48 else if (IfEntry->dwSpeed < 1000000) 49 { 50 if (LoadStringW(netshell_hInstance, IDS_FORMAT_KBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 51 { 52 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000); 53 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 54 } 55 } 56 else if (IfEntry->dwSpeed < 1000000000) 57 { 58 if (LoadStringW(netshell_hInstance, IDS_FORMAT_MBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 59 { 60 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000000); 61 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 62 } 63 } 64 else 65 { 66 if (LoadStringW(netshell_hInstance, IDS_FORMAT_GBIT, szFormat, sizeof(szFormat)/sizeof(WCHAR))) 67 { 68 swprintf(szBuffer, szFormat, IfEntry->dwSpeed/1000000000); 69 SendDlgItemMessageW(hwndDlg, IDC_SPEED, WM_SETTEXT, 0, (LPARAM)szBuffer); 70 } 71 } 72 73 if (StrFormatByteSizeW(IfEntry->dwInOctets, szBuffer, sizeof(szFormat)/sizeof(WCHAR))) 74 { 75 SendDlgItemMessageW(hwndDlg, IDC_RECEIVED, WM_SETTEXT, 0, (LPARAM)szBuffer); 76 } 77 78 if (StrFormatByteSizeW(IfEntry->dwOutOctets, szBuffer, sizeof(szFormat)/sizeof(WCHAR))) 79 { 80 SendDlgItemMessageW(hwndDlg, IDC_SEND, WM_SETTEXT, 0, (LPARAM)szBuffer); 81 } 82 83#if 0 84 Ticks = GetTickCount64(); 85#else 86 Ticks = GetTickCount(); 87#endif 88 89 DurationSeconds = Ticks / 1000; 90 TimeConnected.wSecond = (DurationSeconds % 60); 91 TimeConnected.wMinute = (DurationSeconds / 60) % 60; 92 TimeConnected.wHour = (DurationSeconds / (60 * 60)) % 24; 93 TimeConnected.wDay = DurationSeconds / (60 * 60 * 24); 94 95 if (!GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &TimeConnected, L"HH':'mm':'ss", LocBuffer, sizeof(LocBuffer) / sizeof(LocBuffer[0]))) 96 return; 97 98 if (!TimeConnected.wDay) 99 { 100 SendDlgItemMessageW(hwndDlg, IDC_DURATION, WM_SETTEXT, 0, (LPARAM)LocBuffer); 101 } 102 else 103 { 104 if (TimeConnected.wDay == 1) 105 { 106 if (!LoadStringW(netshell_hInstance, IDS_DURATION_DAY, DayBuffer, sizeof(DayBuffer) / sizeof(DayBuffer[0]))) 107 DayBuffer[0] = L'\0'; 108 } 109 else 110 { 111 if (!LoadStringW(netshell_hInstance, IDS_DURATION_DAYS, DayBuffer, sizeof(DayBuffer) / sizeof(DayBuffer[0]))) 112 DayBuffer[0] = L'\0'; 113 } 114 swprintf(Buffer, DayBuffer, TimeConnected.wDay, LocBuffer); 115 SendDlgItemMessageW(hwndDlg, IDC_DURATION, WM_SETTEXT, 0, (LPARAM)Buffer); 116 } 117 118} 119 120VOID 121UpdateLanStatus(HWND hwndDlg, LANSTATUSUI_CONTEXT * pContext) 122{ 123 MIB_IFROW IfEntry; 124 HICON hIcon, hOldIcon = NULL; 125 NOTIFYICONDATAW nid; 126 NETCON_PROPERTIES * pProperties = NULL; 127 128 ZeroMemory(&IfEntry, sizeof(IfEntry)); 129 IfEntry.dwIndex = pContext->dwAdapterIndex; 130 if (GetIfEntry(&IfEntry) != NO_ERROR) 131 { 132 return; 133 } 134 135 if (pContext->Status == (UINT)-1) 136 { 137 /* 138 * On first execution, pContext->dw[In|Out]Octets will be zero while 139 * the interface info is already refreshed with non-null data, so a 140 * gap is normal and does not correspond to an effective TX or RX packet. 141 */ 142 pContext->dwInOctets = IfEntry.dwInOctets; 143 pContext->dwOutOctets = IfEntry.dwOutOctets; 144 } 145 146 hIcon = NULL; 147 if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL) 148 { 149 if (pContext->dwInOctets == IfEntry.dwInOctets && pContext->dwOutOctets == IfEntry.dwOutOctets && pContext->Status != 0) 150 { 151 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 32, 32, LR_SHARED); 152 pContext->Status = 0; 153 } 154 else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status != 1) 155 { 156 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANSREC), IMAGE_ICON, 32, 32, LR_SHARED); 157 pContext->Status = 1; 158 } 159 else if (pContext->dwInOctets != IfEntry.dwInOctets && pContext->Status != 2) 160 { 161 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_REC), IMAGE_ICON, 32, 32, LR_SHARED); 162 pContext->Status = 2; 163 } 164 else if (pContext->dwOutOctets != IfEntry.dwOutOctets && pContext->Status != 3) 165 { 166 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_TRANS), IMAGE_ICON, 32, 32, LR_SHARED); 167 pContext->Status = 3; 168 } 169 } 170 else if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_UNREACHABLE || IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_DISCONNECTED) 171 { 172 if (pContext->Status != 4) 173 { 174 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_SHARED); 175 pContext->Status = 4; 176 } 177 } 178 else if (IfEntry.dwOperStatus == MIB_IF_OPER_STATUS_NON_OPERATIONAL) 179 { 180 if (pContext->Status != 5) 181 { 182 hIcon = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_SHARED); 183 pContext->Status = 5; 184 } 185 } 186 187 if (hwndDlg && hIcon) 188 { 189 hOldIcon = (HICON)SendDlgItemMessageW(hwndDlg, IDC_NETSTAT, STM_SETICON, (WPARAM)hIcon, 0); 190 if (hOldIcon) 191 DestroyIcon(hOldIcon); 192 } 193 194 ZeroMemory(&nid, sizeof(nid)); 195 nid.cbSize = sizeof(nid); 196 nid.uID = pContext->uID; 197 nid.hWnd = pContext->hwndStatusDlg; 198 nid.uVersion = NOTIFYICON_VERSION; 199 200 if (pContext->pNet->GetProperties(&pProperties) == S_OK) 201 { 202 if (pProperties->dwCharacter & NCCF_SHOW_ICON) 203 { 204 if (hwndDlg) 205 nid.hIcon = (HICON)CopyImage(hIcon, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); 206 else 207 nid.hIcon = hIcon; 208 209 if (nid.hIcon) 210 nid.uFlags |= NIF_ICON; 211 212 nid.uFlags |= NIF_STATE; 213 nid.dwState = 0; 214 nid.dwStateMask = NIS_HIDDEN; 215 216 if (pProperties->pszwName) 217 { 218 if (wcslen(pProperties->pszwName) * sizeof(WCHAR) < sizeof(nid.szTip)) 219 { 220 nid.uFlags |= NIF_TIP; 221 wcscpy(nid.szTip, pProperties->pszwName); 222 } 223 else 224 { 225 CopyMemory(nid.szTip, pProperties->pszwName, sizeof(nid.szTip) - sizeof(WCHAR)); 226 nid.szTip[(sizeof(nid.szTip)/sizeof(WCHAR))-1] = L'\0'; 227 nid.uFlags |= NIF_TIP; 228 } 229 } 230 } 231 else 232 { 233 nid.uFlags |= NIF_STATE; 234 nid.dwState = NIS_HIDDEN; 235 nid.dwStateMask = NIS_HIDDEN; 236 237 } 238 NcFreeNetconProperties(pProperties); 239 } 240 241 Shell_NotifyIconW(NIM_MODIFY, &nid); 242 243 if (nid.uFlags & NIF_ICON) 244 DestroyIcon(nid.hIcon); 245 246 pContext->dwInOctets = IfEntry.dwInOctets; 247 pContext->dwOutOctets = IfEntry.dwOutOctets; 248 249 if (hwndDlg) 250 UpdateLanStatusUiDlg(hwndDlg, &IfEntry, pContext); 251} 252 253 254VOID 255InitializeLANStatusUiDlg(HWND hwndDlg, LANSTATUSUI_CONTEXT * pContext) 256{ 257 WCHAR szBuffer[MAX_PATH] = {0}; 258 NETCON_PROPERTIES * pProperties; 259 260 if (pContext->pNet->GetProperties(&pProperties) != S_OK) 261 return; 262 263 if (pProperties->Status == NCS_DISCONNECTED) 264 LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, szBuffer, MAX_PATH); 265 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED) 266 LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, szBuffer, MAX_PATH); 267 else if (pProperties->Status == NCS_CONNECTING) 268 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, szBuffer, MAX_PATH); 269 else if (pProperties->Status == NCS_CONNECTED) 270 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, szBuffer, MAX_PATH); 271 272 SendDlgItemMessageW(hwndDlg, IDC_STATUS, WM_SETTEXT, 0, (LPARAM)szBuffer); 273 274 pContext->dwInOctets = 0; 275 pContext->dwOutOctets = 0; 276 277 /* update adapter info */ 278 pContext->Status = -1; 279 UpdateLanStatus(hwndDlg, pContext); 280 NcFreeNetconProperties(pProperties); 281} 282 283static 284VOID 285InsertColumnToListView( 286 HWND hDlgCtrl, 287 UINT ResId, 288 UINT SubItem, 289 UINT Size) 290{ 291 WCHAR szBuffer[200]; 292 LVCOLUMNW lc; 293 294 if (!LoadStringW(netshell_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 295 return; 296 297 memset(&lc, 0, sizeof(LV_COLUMN) ); 298 lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT; 299 lc.iSubItem = SubItem; 300 lc.fmt = LVCFMT_FIXED_WIDTH; 301 lc.cx = Size; 302 lc.cchTextMax = wcslen(szBuffer); 303 lc.pszText = szBuffer; 304 305 (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, SubItem, (LPARAM)&lc); 306} 307 308static 309VOID 310AddIPAddressToListView( 311 HWND hDlgCtrl, 312 PIP_ADDR_STRING pAddr, 313 INT Index) 314{ 315 LVITEMW li; 316 PIP_ADDR_STRING pCur; 317 WCHAR szBuffer[100]; 318 UINT SubIndex; 319 320 ZeroMemory(&li, sizeof(LVITEMW)); 321 li.mask = LVIF_TEXT; 322 li.iItem = Index; 323 pCur = pAddr; 324 SubIndex = 0; 325 326 do 327 { 328 if (SubIndex) 329 { 330 ZeroMemory(&li, sizeof(LVITEMW)); 331 li.mask = LVIF_TEXT; 332 li.iItem = Index; 333 li.iSubItem = 0; 334 li.pszText = (LPWSTR)L""; 335 li.iItem = SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li); 336 } 337 338 if (MultiByteToWideChar(CP_ACP, 0, pCur->IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 339 { 340 li.pszText = szBuffer; 341 li.iSubItem = 1; 342 li.iItem = Index++; 343 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 344 } 345 SubIndex++; 346 pCur = pCur->Next; 347 } while (pCur && pCur->IpAddress.String[0]); 348} 349 350static 351INT 352InsertItemToListView( 353 HWND hDlgCtrl, 354 UINT ResId) 355{ 356 LVITEMW li; 357 WCHAR szBuffer[100]; 358 359 ZeroMemory(&li, sizeof(LVITEMW)); 360 li.mask = LVIF_TEXT; 361 li.iItem = ListView_GetItemCount(hDlgCtrl); 362 if (LoadStringW(netshell_hInstance, ResId, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 363 { 364 li.pszText = szBuffer; 365 return (INT)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li); 366 } 367 return -1; 368} 369 370static 371BOOL 372tmToStr( 373 IN struct tm *pTM, 374 OUT LPWSTR szBuffer, 375 IN UINT nBufferSize) 376{ 377 SYSTEMTIME st; 378 CString strBufferDate; 379 CString strBufferTime; 380 UINT nCharDate, nCharTime; 381 BOOL bResult = FALSE; 382 383 st.wYear = pTM->tm_year + 1900; 384 st.wMonth = pTM->tm_mon + 1; 385 st.wDay = pTM->tm_mday; 386 st.wHour = pTM->tm_hour; 387 st.wMinute = pTM->tm_min; 388 st.wSecond = pTM->tm_sec; 389 390 /* Check required size before cpy/cat */ 391 nCharDate = GetDateFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) + 1; 392 nCharTime = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, NULL, 0) + 1; 393 394 if (GetDateFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, strBufferDate.GetBuffer(nCharDate), nCharDate) && 395 GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, strBufferTime.GetBuffer(nCharTime), nCharTime)) 396 { 397 StringCbCopy(szBuffer, nBufferSize, strBufferDate); 398 StringCbCat(szBuffer, nBufferSize, L" "); 399 StringCbCat(szBuffer, nBufferSize, strBufferTime); 400 bResult = TRUE; 401 } 402 strBufferDate.ReleaseBuffer(); 403 strBufferTime.ReleaseBuffer(); 404 405 return bResult; 406} 407 408INT_PTR 409CALLBACK 410LANStatusUiDetailsDlg( 411 HWND hwndDlg, 412 UINT uMsg, 413 WPARAM wParam, 414 LPARAM lParam 415) 416{ 417 LANSTATUSUI_CONTEXT * pContext; 418 LVITEMW li; 419 WCHAR szBuffer[100]; 420 PIP_ADAPTER_INFO pAdapterInfo, pCurAdapter; 421 PIP_PER_ADAPTER_INFO pPerAdapter; 422 DWORD dwSize; 423 HWND hDlgCtrl; 424 RECT rect; 425 426 switch (uMsg) 427 { 428 case WM_INITDIALOG: 429 pContext = (LANSTATUSUI_CONTEXT*)lParam; 430 431 hDlgCtrl = GetDlgItem(hwndDlg, IDC_DETAILS); 432 433 /* get client rect */ 434 GetClientRect(hDlgCtrl, &rect); 435 436 /* calculate column width */ 437 dwSize = rect.right / 2; 438 439 InsertColumnToListView(hDlgCtrl, IDS_PROPERTY, 0, dwSize); 440 InsertColumnToListView(hDlgCtrl, IDS_VALUE, 1, dwSize); 441 442 dwSize = 0; 443 pCurAdapter = NULL; 444 pAdapterInfo = NULL; 445 if (GetAdaptersInfo(NULL, &dwSize) == ERROR_BUFFER_OVERFLOW) 446 { 447 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 448 if (pAdapterInfo) 449 { 450 if (GetAdaptersInfo(pAdapterInfo, &dwSize) == NO_ERROR) 451 { 452 pCurAdapter = pAdapterInfo; 453 while (pCurAdapter && pCurAdapter->Index != pContext->dwAdapterIndex) 454 pCurAdapter = pCurAdapter->Next; 455 456 if (pCurAdapter->Index != pContext->dwAdapterIndex) 457 pCurAdapter = NULL; 458 } 459 } 460 } 461 462 ZeroMemory(&li, sizeof(LVITEMW)); 463 li.mask = LVIF_TEXT; 464 li.iSubItem = 1; 465 li.pszText = szBuffer; 466 467 if (pCurAdapter) 468 { 469 li.iItem = InsertItemToListView(hDlgCtrl, IDS_PHYSICAL_ADDRESS); 470 if (li.iItem >= 0) 471 { 472 swprintf(szBuffer, L"%02x-%02x-%02x-%02x-%02x-%02x",pCurAdapter->Address[0], pCurAdapter->Address[1], 473 pCurAdapter->Address[2], pCurAdapter->Address[3], pCurAdapter->Address[4], pCurAdapter->Address[5]); 474 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 475 } 476 li.iItem = InsertItemToListView(hDlgCtrl, IDS_IP_ADDRESS); 477 if (li.iItem >= 0) 478 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 479 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 480 481 li.iItem = InsertItemToListView(hDlgCtrl, IDS_SUBNET_MASK); 482 if (li.iItem >= 0) 483 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->IpAddressList.IpMask.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 484 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 485 486 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DEF_GATEWAY); 487 if (li.iItem >= 0 && pCurAdapter->GatewayList.IpAddress.String[0] != '0') 488 { 489 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->GatewayList.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 490 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 491 } 492 493 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DHCP_SERVER); 494 if (li.iItem >= 0 && pCurAdapter->DhcpServer.IpAddress.String[0] != '0') 495 { 496 if (MultiByteToWideChar(CP_ACP, 0, pCurAdapter->DhcpServer.IpAddress.String, -1, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 497 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 498 } 499 500 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_OBTAINED); 501 if (li.iItem >= 0 && pCurAdapter->LeaseObtained != NULL) 502 { 503 struct tm *leaseOptained; 504 505 leaseOptained = localtime(&pCurAdapter->LeaseObtained); 506 507 if (tmToStr(leaseOptained, szBuffer, _countof(szBuffer))) 508 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 509 } 510 511 li.iItem = InsertItemToListView(hDlgCtrl, IDS_LEASE_EXPIRES); 512 if (li.iItem >= 0 && pCurAdapter->LeaseExpires != NULL) 513 { 514 struct tm *leaseExpire; 515 516 leaseExpire = localtime(&pCurAdapter->LeaseExpires); 517 518 if (tmToStr(leaseExpire, szBuffer, _countof(szBuffer))) 519 SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li); 520 } 521 } 522 523 dwSize = 0; 524 li.iItem = InsertItemToListView(hDlgCtrl, IDS_DNS_SERVERS); 525 if (GetPerAdapterInfo(pContext->dwAdapterIndex, NULL, &dwSize) == ERROR_BUFFER_OVERFLOW) 526 { 527 pPerAdapter = static_cast<PIP_PER_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 528 if (pPerAdapter) 529 { 530 if (GetPerAdapterInfo(pContext->dwAdapterIndex, pPerAdapter, &dwSize) == ERROR_SUCCESS) 531 { 532 if (li.iItem >= 0) 533 AddIPAddressToListView(hDlgCtrl, &pPerAdapter->DnsServerList, li.iItem); 534 } 535 CoTaskMemFree(pPerAdapter); 536 } 537 } 538 539 if (pCurAdapter) 540 { 541 li.iItem = InsertItemToListView(hDlgCtrl, IDS_WINS_SERVERS); 542 if (pCurAdapter->HaveWins) 543 { 544 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->PrimaryWinsServer, li.iItem); 545 AddIPAddressToListView(hDlgCtrl, &pCurAdapter->SecondaryWinsServer, li.iItem+1); 546 } 547 } 548 549 CoTaskMemFree(pAdapterInfo); 550 break; 551 552 case WM_COMMAND: 553 if (LOWORD(wParam) == IDC_CLOSE) 554 { 555 EndDialog(hwndDlg, FALSE); 556 break; 557 } 558 } 559 560 return FALSE; 561} 562 563INT_PTR 564CALLBACK 565LANStatusUiAdvancedDlg( 566 HWND hwndDlg, 567 UINT uMsg, 568 WPARAM wParam, 569 LPARAM lParam) 570{ 571 WCHAR szBuffer[100] = {0}; 572 PROPSHEETPAGE *page; 573 LANSTATUSUI_CONTEXT * pContext; 574 DWORD dwIpAddr; 575 576 577 switch (uMsg) 578 { 579 case WM_INITDIALOG: 580 page = (PROPSHEETPAGE*)lParam; 581 pContext = (LANSTATUSUI_CONTEXT*)page->lParam; 582 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext); 583 if (pContext->DHCPEnabled) 584 LoadStringW(netshell_hInstance, IDS_ASSIGNED_DHCP, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)); 585 else 586 LoadStringW(netshell_hInstance, IDS_ASSIGNED_MANUAL, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)); 587 588 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0'; 589 SendDlgItemMessageW(hwndDlg, IDC_DETAILSTYPE, WM_SETTEXT, 0, (LPARAM)szBuffer); 590 591 592 dwIpAddr = ntohl(pContext->IpAddress); 593 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), 594 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr)); 595 SendDlgItemMessageW(hwndDlg, IDC_DETAILSIP, WM_SETTEXT, 0, (LPARAM)szBuffer); 596 597 dwIpAddr = ntohl(pContext->SubnetMask); 598 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), 599 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr)); 600 SendDlgItemMessageW(hwndDlg, IDC_DETAILSSUBNET, WM_SETTEXT, 0, (LPARAM)szBuffer); 601 602 dwIpAddr = ntohl(pContext->Gateway); 603 if (dwIpAddr) 604 { 605 swprintf(szBuffer, L"%u.%u.%u.%u", FIRST_IPADDRESS(dwIpAddr), SECOND_IPADDRESS(dwIpAddr), 606 THIRD_IPADDRESS(dwIpAddr), FOURTH_IPADDRESS(dwIpAddr)); 607 SendDlgItemMessageW(hwndDlg, IDC_DETAILSGATEWAY, WM_SETTEXT, 0, (LPARAM)szBuffer); 608 } 609 return TRUE; 610 case WM_COMMAND: 611 if (LOWORD(wParam) == IDC_DETAILS) 612 { 613 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 614 if (pContext) 615 { 616 DialogBoxParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_LAN_NETSTATUSDETAILS), GetParent(hwndDlg), 617 LANStatusUiDetailsDlg, (LPARAM)pContext); 618 } 619 } 620 break; 621 default: 622 break; 623 } 624 return FALSE; 625} 626 627VOID 628DisableNetworkAdapter(INetConnection * pNet, LANSTATUSUI_CONTEXT * pContext, HWND hwndDlg) 629{ 630 HRESULT hr = pNet->Disconnect(); 631 if (FAILED_UNEXPECTEDLY(hr)) 632 return; 633 634 NOTIFYICONDATAW nid; 635 636 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_CANCEL); 637 ZeroMemory(&nid, sizeof(nid)); 638 nid.cbSize = sizeof(nid); 639 nid.uID = pContext->uID; 640 nid.hWnd = pContext->hwndDlg; 641 nid.uFlags = NIF_STATE; 642 nid.dwState = NIS_HIDDEN; 643 nid.dwStateMask = NIS_HIDDEN; 644 645 Shell_NotifyIconW(NIM_MODIFY, &nid); 646} 647 648 649INT_PTR 650CALLBACK 651LANStatusUiDlg( 652 HWND hwndDlg, 653 UINT uMsg, 654 WPARAM wParam, 655 LPARAM lParam) 656{ 657 PROPSHEETPAGE *page; 658 LANSTATUSUI_CONTEXT * pContext; 659 LPPSHNOTIFY lppsn; 660 661 switch (uMsg) 662 { 663 case WM_INITDIALOG: 664 page = (PROPSHEETPAGE*)lParam; 665 pContext = (LANSTATUSUI_CONTEXT*)page->lParam; 666 pContext->hwndDlg = hwndDlg; 667 InitializeLANStatusUiDlg(hwndDlg, pContext); 668 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pContext); 669 return TRUE; 670 case WM_COMMAND: 671 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 672 if (LOWORD(wParam) == IDC_STATUS_PROPERTIES) 673 { 674 if (pContext) 675 { 676 ShowNetConnectionProperties(pContext->pNet, GetParent(pContext->hwndDlg)); 677 BringWindowToTop(GetParent(pContext->hwndDlg)); 678 } 679 break; 680 } 681 else if (LOWORD(wParam) == IDC_ENDISABLE) 682 { 683 DisableNetworkAdapter(pContext->pNet, pContext, hwndDlg); 684 break; 685 } 686 case WM_NOTIFY: 687 lppsn = (LPPSHNOTIFY) lParam; 688 if (lppsn->hdr.code == PSN_APPLY || lppsn->hdr.code == PSN_RESET) 689 { 690 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 691 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); 692 pContext->hwndDlg = NULL; 693 return TRUE; 694 } 695 break; 696 } 697 return FALSE; 698} 699 700VOID 701InitializePropertyDialog( 702 LANSTATUSUI_CONTEXT * pContext, 703 NETCON_PROPERTIES * pProperties) 704{ 705 DWORD dwSize, dwAdapterIndex, dwResult; 706 LPOLESTR pStr; 707 IP_ADAPTER_INFO *pAdapterInfo, *pCurAdapter; 708 709 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pStr))) 710 { 711 return; 712 } 713 714 /* get the IfTable */ 715 dwSize = 0; 716 dwResult = GetAdaptersInfo(NULL, &dwSize); 717 if (dwResult!= ERROR_BUFFER_OVERFLOW) 718 { 719 CoTaskMemFree(pStr); 720 return; 721 } 722 723 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize)); 724 if (!pAdapterInfo) 725 { 726 CoTaskMemFree(pAdapterInfo); 727 CoTaskMemFree(pStr); 728 return; 729 } 730 731 if (GetAdaptersInfo(pAdapterInfo, &dwSize) != NO_ERROR) 732 { 733 CoTaskMemFree(pAdapterInfo); 734 CoTaskMemFree(pStr); 735 return; 736 } 737 738 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, pStr, &dwAdapterIndex)) 739 { 740 CoTaskMemFree(pAdapterInfo); 741 CoTaskMemFree(pStr); 742 return; 743 } 744 745 pCurAdapter = pAdapterInfo; 746 while (pCurAdapter->Index != dwAdapterIndex) 747 pCurAdapter = pCurAdapter->Next; 748 749 750 pContext->IpAddress = inet_addr(pCurAdapter->IpAddressList.IpAddress.String); 751 pContext->SubnetMask = inet_addr(pCurAdapter->IpAddressList.IpMask.String); 752 pContext->Gateway = inet_addr(pCurAdapter->GatewayList.IpAddress.String); 753 pContext->DHCPEnabled = pCurAdapter->DhcpEnabled; 754 CoTaskMemFree(pStr); 755 CoTaskMemFree(pAdapterInfo); 756 pContext->dwAdapterIndex = dwAdapterIndex; 757} 758 759static int CALLBACK 760PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 761{ 762 // NOTE: This callback is needed to set large icon correctly. 763 HICON hIcon; 764 switch (uMsg) 765 { 766 case PSCB_INITIALIZED: 767 { 768 hIcon = LoadIconW(netshell_hInstance, MAKEINTRESOURCEW(IDI_NET_IDLE)); 769 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 770 break; 771 } 772 } 773 return 0; 774} 775 776VOID 777ShowStatusPropertyDialog( 778 LANSTATUSUI_CONTEXT *pContext, 779 HWND hwndDlg) 780{ 781 HPROPSHEETPAGE hppages[2]; 782 PROPSHEETHEADERW pinfo; 783 NETCON_PROPERTIES * pProperties = NULL; 784 785 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW)); 786 ZeroMemory(hppages, sizeof(hppages)); 787 pinfo.dwSize = sizeof(PROPSHEETHEADERW); 788 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW | 789 PSH_USEICONID | PSH_USECALLBACK; 790 pinfo.phpage = hppages; 791 pinfo.hwndParent = hwndDlg; 792 pinfo.hInstance = netshell_hInstance; 793 pinfo.pszIcon = MAKEINTRESOURCEW(IDI_NET_IDLE); 794 pinfo.pfnCallback = PropSheetProc; 795 796 if (pContext->pNet->GetProperties(&pProperties) == S_OK) 797 { 798 if (pProperties->pszwName) 799 { 800 pinfo.pszCaption = pProperties->pszwName; 801 pinfo.dwFlags |= PSH_PROPTITLE; 802 } 803 InitializePropertyDialog(pContext, pProperties); 804 if (pProperties->MediaType == NCM_LAN && pProperties->Status == NCS_CONNECTED) 805 { 806 hppages[0] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUS), LANStatusUiDlg, (LPARAM)pContext, NULL); 807 if (hppages[0]) 808 pinfo.nPages++; 809 810 hppages[pinfo.nPages] = InitializePropertySheetPage(MAKEINTRESOURCEW(IDD_LAN_NETSTATUSADVANCED), LANStatusUiAdvancedDlg, (LPARAM)pContext, NULL); 811 if (hppages[pinfo.nPages]) 812 pinfo.nPages++; 813 814 if (pinfo.nPages) 815 { 816 PropertySheetW(&pinfo); 817 } 818 } 819 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED || 820 pProperties->Status == NCS_HARDWARE_DISABLED) 821 { 822 ShowNetConnectionProperties(pContext->pNet, pContext->hwndDlg); 823 } 824 825 NcFreeNetconProperties(pProperties); 826 } 827} 828 829VOID ShowNetworkIconContextMenu( 830 _In_ HWND hwndOwner, 831 _In_ LANSTATUSUI_CONTEXT *pContext) 832{ 833 if (!pContext || !pContext->pNet) 834 return; 835 836 HMENU hMenu = CreatePopupMenu(); 837 if (!hMenu) 838 return; 839 840 POINT pt; 841 GetCursorPos(&pt); 842 843 SetForegroundWindow(hwndOwner); 844 845 // The context menu items, set to their default values. 846 struct 847 { 848 UINT uID; 849 UINT uFlags; 850 UINT_PTR uIDNewItem; 851 } MenuItems[] = 852 { 853 {IDS_NET_ACTIVATE, MF_GRAYED, IDM_NETICON_ENABLE}, 854 {IDS_NET_STATUS, MF_GRAYED, IDM_NETICON_STATUS}, 855 {IDS_NET_REPAIR, MF_GRAYED, IDM_NETICON_REPAIR}, 856 {UINT_MAX, 0, 0}, // Separator 857 {IDS_NET_OPEN_CONNECTIONS, MF_ENABLED, IDM_NETICON_OPEN_CONNECTIONS}, 858 {IDS_NET_PROPERTIES, MF_ENABLED | MFS_DEFAULT, IDM_NETICON_PROPERTIES}, 859 }; 860 861 NETCON_PROPERTIES *pProps = NULL; 862 HRESULT hr = pContext->pNet->GetProperties(&pProps); 863 if (SUCCEEDED(hr) && pProps) 864 { 865 if (pProps->Status == NCS_HARDWARE_DISABLED || 866 pProps->Status == NCS_MEDIA_DISCONNECTED || 867 pProps->Status == NCS_DISCONNECTED) 868 { 869 MenuItems[0].uID = IDS_NET_ACTIVATE; 870 MenuItems[0].uFlags = MF_ENABLED | MFS_DEFAULT; 871 MenuItems[0].uIDNewItem = IDM_NETICON_ENABLE; 872 MenuItems[5].uFlags = MF_ENABLED; 873 } 874 else 875 { 876 MenuItems[0].uID = IDS_NET_DEACTIVATE; 877 MenuItems[0].uFlags = MF_ENABLED; 878 MenuItems[0].uIDNewItem = IDM_NETICON_DISABLE; 879 } 880 881 if (pProps->Status == NCS_CONNECTED) 882 { 883 MenuItems[1].uFlags = MF_ENABLED; 884 MenuItems[2].uFlags = MF_ENABLED; 885 } 886 else if (pProps->Status == NCS_CONNECTING) 887 { 888 MenuItems[1].uFlags = MF_ENABLED; 889 MenuItems[2].uFlags = MF_GRAYED; 890 } 891 else 892 { 893 MenuItems[1].uFlags = MF_GRAYED; 894 MenuItems[2].uFlags = MF_GRAYED; 895 } 896 897 NcFreeNetconProperties(pProps); 898 pProps = NULL; 899 } 900 else 901 { 902 MenuItems[0].uFlags = MF_GRAYED; 903 MenuItems[1].uFlags = MF_GRAYED; 904 MenuItems[2].uFlags = MF_GRAYED; 905 MenuItems[5].uFlags = MF_GRAYED; 906 } 907 908 // Set the "Properties" item as default, if the Network "Enable/Disable" item isn't. 909 if (!(MenuItems[0].uFlags & MFS_DEFAULT)) 910 MenuItems[5].uFlags |= MFS_DEFAULT; 911 912 WCHAR szMenuItem[128]; 913 914 for (USHORT i = 0; i < _countof(MenuItems); ++i) 915 { 916 if (MenuItems[i].uID != UINT_MAX) 917 { 918 if (LoadStringW(netshell_hInstance, MenuItems[i].uID, szMenuItem, _countof(szMenuItem))) 919 AppendMenuW(hMenu, MF_STRING | MenuItems[i].uFlags, MenuItems[i].uIDNewItem, szMenuItem); 920 } 921 else 922 { 923 AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); 924 } 925 } 926 927 TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, hwndOwner, NULL); 928 929 PostMessage(hwndOwner, WM_NULL, 0, 0); 930 931 DestroyMenu(hMenu); 932} 933 934HRESULT RepairConnection(INetConnection *pNet, HWND hwndOwner) 935{ 936 SHELL_ErrorBox(hwndOwner, HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)); 937 938 return E_NOTIMPL; 939} 940 941INT_PTR 942CALLBACK 943LANStatusDlg( 944 HWND hwndDlg, 945 UINT uMsg, 946 WPARAM wParam, 947 LPARAM lParam) 948{ 949 LANSTATUSUI_CONTEXT * pContext; 950 951 switch (uMsg) 952 { 953 case WM_INITDIALOG: 954 pContext = (LANSTATUSUI_CONTEXT *)lParam; 955 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam); 956 pContext->hwndStatusDlg = hwndDlg; 957 pContext->nIDEvent = SetTimer(hwndDlg, NETTIMERID, 1000, NULL); 958 return TRUE; 959 960 case WM_DESTROY: 961 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 962 if (pContext && pContext->nIDEvent) 963 { 964 KillTimer(hwndDlg, pContext->nIDEvent); 965 pContext->nIDEvent = 0; 966 } 967 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)NULL); 968 break; 969 970 case WM_TIMER: 971 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 972 if (wParam == (WPARAM)pContext->nIDEvent) 973 { 974 UpdateLanStatus(pContext->hwndDlg, pContext); 975 } 976 break; 977 978 case WM_SHOWSTATUSDLG: 979 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 980 if (!pContext) 981 break; 982 983 switch (LOWORD(lParam)) 984 { 985 case WM_LBUTTONUP: 986 if (pContext->hwndDlg) 987 { 988 HWND hwndSheet = GetParent(pContext->hwndDlg); 989 if (hwndSheet) 990 { 991 ShowWindow(hwndSheet, SW_RESTORE); 992 SetForegroundWindow(hwndSheet); 993 BringWindowToTop(hwndSheet); 994 } 995 } 996 else 997 { 998 ShowStatusPropertyDialog(pContext, hwndDlg); 999 } 1000 break; 1001 1002 if (pContext->hwndDlg) 1003 { 1004 ShowWindow(GetParent(pContext->hwndDlg), SW_SHOW); 1005 BringWindowToTop(GetParent(pContext->hwndDlg)); 1006 } 1007 else 1008 { 1009 ShowStatusPropertyDialog(pContext, hwndDlg); 1010 } 1011 break; 1012 1013 case WM_RBUTTONUP: 1014 case WM_CONTEXTMENU: 1015 ShowNetworkIconContextMenu(hwndDlg, pContext); 1016 break; 1017 } 1018 break; 1019 1020 case WM_COMMAND: 1021 { 1022 pContext = (LANSTATUSUI_CONTEXT*)GetWindowLongPtr(hwndDlg, DWLP_USER); 1023 if (!pContext || !pContext->pNet) 1024 break; 1025 1026 switch (LOWORD(wParam)) 1027 { 1028 case IDM_NETICON_ENABLE: 1029 pContext->pNet->Connect(); 1030 UpdateLanStatus(NULL, pContext); 1031 break; 1032 1033 case IDM_NETICON_DISABLE: 1034 pContext->pNet->Disconnect(); 1035 UpdateLanStatus(NULL, pContext); 1036 break; 1037 1038 case IDM_NETICON_STATUS: 1039 if (pContext->hwndDlg) 1040 { 1041 HWND hwndSheet = GetParent(pContext->hwndDlg); 1042 if (hwndSheet) 1043 { 1044 ShowWindow(hwndSheet, SW_RESTORE); 1045 SetForegroundWindow(hwndSheet); 1046 BringWindowToTop(hwndSheet); 1047 } 1048 } 1049 else 1050 { 1051 ShowStatusPropertyDialog(pContext, hwndDlg); 1052 } 1053 break; 1054 1055 case IDM_NETICON_REPAIR: 1056 RepairConnection(pContext->pNet, hwndDlg); 1057 break; 1058 1059 case IDM_NETICON_PROPERTIES: 1060 ShowNetConnectionProperties(pContext->pNet, hwndDlg); 1061 break; 1062 1063 case IDM_NETICON_OPEN_CONNECTIONS: 1064 ShellExecuteW(hwndDlg, NULL, L"control", L"netconnections", NULL, SW_SHOWNORMAL); 1065 break; 1066 } 1067 break; 1068 } 1069 } 1070 return FALSE; 1071} 1072 1073HRESULT 1074CLanStatus::InitializeNetTaskbarNotifications() 1075{ 1076 NOTIFYICONDATAW nid; 1077 HWND hwndDlg; 1078 CComPtr<INetConnectionManager> pNetConMan; 1079 CComPtr<IEnumNetConnection> pEnumCon; 1080 CComPtr<INetConnection> pNetCon; 1081 NETCON_PROPERTIES* pProps; 1082 HRESULT hr; 1083 ULONG Count; 1084 ULONG Index; 1085 NOTIFICATION_ITEM * pItem, *pLast = NULL; 1086 LANSTATUSUI_CONTEXT * pContext; 1087 1088 TRACE("InitializeNetTaskbarNotifications\n"); 1089 1090 if (m_pHead) 1091 { 1092 pItem = m_pHead; 1093 while (pItem) 1094 { 1095 hr = pItem->pNet->GetProperties(&pProps); 1096 if (SUCCEEDED(hr)) 1097 { 1098 ZeroMemory(&nid, sizeof(nid)); 1099 nid.cbSize = sizeof(nid); 1100 nid.uID = pItem->uID; 1101 nid.hWnd = pItem->hwndDlg; 1102 nid.uFlags = NIF_STATE; 1103 if (pProps->dwCharacter & NCCF_SHOW_ICON) 1104 nid.dwState = 0; 1105 else 1106 nid.dwState = NIS_HIDDEN; 1107 1108 nid.dwStateMask = NIS_HIDDEN; 1109 Shell_NotifyIconW(NIM_MODIFY, &nid); 1110 NcFreeNetconProperties(pProps); 1111 } 1112 pItem = pItem->pNext; 1113 } 1114 return S_OK; 1115 } 1116 /* get an instance to of IConnectionManager */ 1117 hr = CNetConnectionManager_CreateInstance(IID_PPV_ARG(INetConnectionManager, &pNetConMan)); 1118 if (FAILED_UNEXPECTEDLY(hr)) 1119 return hr; 1120 1121 hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon); 1122 if (FAILED_UNEXPECTEDLY(hr)) 1123 return hr; 1124 1125 Index = 1; 1126 while (TRUE) 1127 { 1128 pNetCon.Release(); 1129 hr = pEnumCon->Next(1, &pNetCon, &Count); 1130 if (hr != S_OK) 1131 break; 1132 1133 TRACE("new connection\n"); 1134 pItem = static_cast<NOTIFICATION_ITEM*>(CoTaskMemAlloc(sizeof(NOTIFICATION_ITEM))); 1135 if (!pItem) 1136 break; 1137 1138 pContext = static_cast<LANSTATUSUI_CONTEXT*>(CoTaskMemAlloc(sizeof(LANSTATUSUI_CONTEXT))); 1139 if (!pContext) 1140 { 1141 CoTaskMemFree(pItem); 1142 break; 1143 } 1144 1145 ZeroMemory(pContext, sizeof(LANSTATUSUI_CONTEXT)); 1146 pContext->uID = Index; 1147 pContext->pNet = pNetCon; 1148 pContext->Status = -1; 1149 pContext->dwAdapterIndex = Index; 1150 pItem->uID = Index; 1151 pItem->pNext = NULL; 1152 pItem->pNet = pNetCon; 1153 pItem->pNet->AddRef(); 1154 hwndDlg = CreateDialogParamW(netshell_hInstance, MAKEINTRESOURCEW(IDD_STATUS), NULL, LANStatusDlg, (LPARAM)pContext); 1155 if (!hwndDlg) 1156 { 1157 ERR("CreateDialogParamW failed\n"); 1158 continue; 1159 } 1160 1161 ZeroMemory(&nid, sizeof(nid)); 1162 nid.cbSize = sizeof(nid); 1163 nid.uID = Index++; 1164 nid.uFlags = NIF_MESSAGE; 1165 nid.uVersion = NOTIFYICON_VERSION; 1166 nid.uCallbackMessage = WM_SHOWSTATUSDLG; 1167 nid.hWnd = hwndDlg; 1168 1169 hr = pNetCon->GetProperties(&pProps); 1170 if (SUCCEEDED(hr)) 1171 { 1172 CopyMemory(&pItem->guidItem, &pProps->guidId, sizeof(GUID)); 1173 if (!(pProps->dwCharacter & NCCF_SHOW_ICON)) 1174 { 1175 nid.dwState = NIS_HIDDEN; 1176 nid.dwStateMask = NIS_HIDDEN; 1177 nid.uFlags |= NIF_STATE; 1178 } 1179 if (pProps->Status == NCS_MEDIA_DISCONNECTED || pProps->Status == NCS_DISCONNECTED || pProps->Status == NCS_HARDWARE_DISABLED) 1180 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF)); 1181 else if (pProps->Status == NCS_CONNECTED) 1182 nid.hIcon = LoadIcon(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE)); 1183 1184 if (nid.hIcon) 1185 nid.uFlags |= NIF_ICON; 1186 1187 wcscpy(nid.szTip, pProps->pszwName); 1188 nid.uFlags |= NIF_TIP; 1189 } 1190 pContext->hwndStatusDlg = hwndDlg; 1191 pItem->hwndDlg = hwndDlg; 1192 1193 if (Shell_NotifyIconW(NIM_ADD, &nid)) 1194 { 1195 if (pLast) 1196 pLast->pNext = pItem; 1197 else 1198 m_pHead = pItem; 1199 1200 pLast = pItem; 1201 Index++; 1202 } 1203 else 1204 { 1205 ERR("Shell_NotifyIconW failed\n"); 1206 CoTaskMemFree(pItem); 1207 } 1208 1209 if (nid.uFlags & NIF_ICON) 1210 DestroyIcon(nid.hIcon); 1211 } 1212 1213 m_lpNetMan = pNetConMan; 1214 return S_OK; 1215} 1216 1217HRESULT 1218CLanStatus::ShowStatusDialogByCLSID(const GUID *pguidCmdGroup) 1219{ 1220 NOTIFICATION_ITEM *pItem; 1221 1222 pItem = m_pHead; 1223 while (pItem) 1224 { 1225 if (IsEqualGUID(pItem->guidItem, *pguidCmdGroup)) 1226 { 1227 SendMessageW(pItem->hwndDlg, WM_SHOWSTATUSDLG, 0, WM_LBUTTONUP); 1228 return S_OK; 1229 } 1230 pItem = pItem->pNext; 1231 } 1232 1233 ERR("not found\n"); 1234 return E_FAIL; 1235} 1236 1237HRESULT 1238WINAPI 1239CLanStatus::QueryStatus( 1240 const GUID *pguidCmdGroup, 1241 ULONG cCmds, 1242 OLECMD *prgCmds, 1243 OLECMDTEXT *pCmdText) 1244{ 1245 MessageBoxW(NULL, pCmdText->rgwz, L"IOleCommandTarget_fnQueryStatus", MB_OK); 1246 return E_NOTIMPL; 1247} 1248 1249HRESULT 1250WINAPI 1251CLanStatus::Exec( 1252 const GUID *pguidCmdGroup, 1253 DWORD nCmdID, 1254 DWORD nCmdexecopt, 1255 VARIANT *pvaIn, 1256 VARIANT *pvaOut) 1257{ 1258 if (pguidCmdGroup) 1259 { 1260 if (IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject)) 1261 { 1262 return InitializeNetTaskbarNotifications(); 1263 } 1264 else 1265 { 1266 /* invoke status dialog */ 1267 return ShowStatusDialogByCLSID(pguidCmdGroup); 1268 } 1269 } 1270 return S_OK; 1271}