1 /* 2 * PROJECT: ReactOS Shell 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: CNetworkConnections Shell Folder 5 * COPYRIGHT: Copyright 2008 Johannes Anderwald <johannes.anderwald@reactos.org> 6 */ 7 8 #include "precomp.h" 9 #include <shellfolderutils.h> 10 11 #define MAX_PROPERTY_SHEET_PAGE (10) 12 13 /*********************************************************************** 14 * IShellFolder implementation 15 */ 16 17 static const shvheader NetConnectSFHeader[] = { 18 {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20}, 19 {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 8}, 20 {IDS_SHV_COLUMN_STATE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, 21 {IDS_SHV_COLUMN_DEVNAME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12}, 22 {IDS_SHV_COLUMN_PHONE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10}, 23 {IDS_SHV_COLUMN_OWNER, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5} 24 }; 25 26 #define NETCONNECTSHELLVIEWCOLUMNS 6 27 28 #define COLUMN_NAME 0 29 #define COLUMN_TYPE 1 30 #define COLUMN_STATUS 2 31 #define COLUMN_DEVNAME 3 32 #define COLUMN_PHONE 4 33 #define COLUMN_OWNER 5 34 35 HRESULT 36 ShowNetConnectionStatus( 37 IOleCommandTarget *lpOleCmd, 38 PCUITEMID_CHILD pidl, 39 HWND hwnd); 40 41 CNetworkConnections::CNetworkConnections() : 42 m_pidlRoot(NULL) 43 { 44 HRESULT hr; 45 hr = CoCreateInstance(CLSID_ConnectionTray, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IOleCommandTarget, &m_lpOleCmd)); 46 if (FAILED_UNEXPECTEDLY(hr)) 47 m_lpOleCmd = NULL; 48 } 49 50 CNetworkConnections::~CNetworkConnections() 51 { 52 if (m_pidlRoot) 53 SHFree(m_pidlRoot); 54 } 55 56 /************************************************************************** 57 * ISF_NetConnect_fnParseDisplayName 58 */ 59 HRESULT WINAPI CNetworkConnections::ParseDisplayName ( 60 HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName, 61 DWORD * pchEaten, PIDLIST_RELATIVE * ppidl, DWORD * pdwAttributes) 62 { 63 HRESULT hr = E_UNEXPECTED; 64 65 *ppidl = 0; 66 if (pchEaten) 67 *pchEaten = 0; /* strange but like the original */ 68 69 return hr; 70 } 71 72 /************************************************************************** 73 * ISF_NetConnect_fnEnumObjects 74 */ 75 HRESULT WINAPI CNetworkConnections::EnumObjects( 76 HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList) 77 { 78 return CEnumIDList_CreateInstance(hwndOwner, dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList)); 79 } 80 81 /************************************************************************** 82 * ISF_NetConnect_fnBindToObject 83 */ 84 HRESULT WINAPI CNetworkConnections::BindToObject ( 85 PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut) 86 { 87 return E_NOTIMPL; 88 } 89 90 /************************************************************************** 91 * ISF_NetConnect_fnBindToStorage 92 */ 93 HRESULT WINAPI CNetworkConnections::BindToStorage( 94 PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut) 95 { 96 *ppvOut = NULL; 97 return E_NOTIMPL; 98 } 99 100 /************************************************************************** 101 * ISF_NetConnect_fnCompareIDs 102 */ 103 HRESULT WINAPI CNetworkConnections::CompareIDs( 104 LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2) 105 { 106 const UINT colcount = NETCONNECTSHELLVIEWCOLUMNS; 107 108 if (ILGetNext(pidl1) || ILGetNext(pidl2)) 109 return E_NOTIMPL; // FIXME: Can the connection folder have subfolders? 110 111 if (lParam & SHCIDS_CANONICALONLY) 112 { 113 PNETCONIDSTRUCT p1 = ILGetConnData(pidl1); 114 PNETCONIDSTRUCT p2 = ILGetConnData(pidl2); 115 if (p1 && p2) 116 { 117 int res = memcmp(&p1->guidId, &p2->guidId, sizeof(GUID)); 118 return MAKE_COMPARE_HRESULT(res); 119 } 120 } 121 IShellFolder2 *psf = static_cast<IShellFolder2*>(this); 122 return ShellFolderImpl_CompareItemIDs<colcount, -1>(psf, lParam, (PCUITEMID_CHILD)pidl1, (PCUITEMID_CHILD)pidl2); 123 } 124 125 /************************************************************************** 126 * ISF_NetConnect_fnCreateViewObject 127 */ 128 HRESULT WINAPI CNetworkConnections::CreateViewObject( 129 HWND hwndOwner, REFIID riid, LPVOID * ppvOut) 130 { 131 HRESULT hr = E_NOINTERFACE; 132 133 if (!ppvOut) 134 return hr; 135 136 *ppvOut = NULL; 137 138 if (IsEqualIID(riid, IID_IShellView)) 139 { 140 CSFV cvf = {sizeof(cvf), this}; 141 CComPtr<IShellView> pShellView; 142 hr = SHCreateShellFolderViewEx(&cvf, &pShellView); 143 if (FAILED_UNEXPECTEDLY(hr)) 144 return hr; 145 146 return pShellView->QueryInterface(riid, ppvOut); 147 } 148 149 return hr; 150 } 151 152 /************************************************************************** 153 * ISF_NetConnect_fnGetAttributesOf 154 */ 155 HRESULT WINAPI CNetworkConnections::GetAttributesOf( 156 UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut) 157 { 158 //IGenericSFImpl *This = (IGenericSFImpl *)iface; 159 // FIXME: Why are these reporting SFGAO_FILESYSTEM and SFGAO_FILESYSANCESTOR? 160 HRESULT hr = S_OK; 161 static const DWORD dwNetConnectAttributes = SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | 162 SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE; 163 164 static const DWORD dwNetConnectItemAttributes = SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR | 165 SFGAO_FILESYSANCESTOR | SFGAO_CANRENAME; 166 167 if (!rgfInOut) 168 return E_INVALIDARG; 169 170 if (cidl && !apidl) 171 return E_INVALIDARG; 172 173 if (*rgfInOut == 0) 174 *rgfInOut = ~0; 175 176 if (cidl > 1) 177 *rgfInOut &= ~SFGAO_HASPROPSHEET; 178 179 if (cidl == 0) 180 { 181 *rgfInOut = dwNetConnectAttributes; 182 } 183 else 184 { 185 *rgfInOut = dwNetConnectItemAttributes; 186 187 while (cidl > 0 && *apidl) 188 { 189 PNETCONIDSTRUCT pdata = ILGetConnData(*apidl); 190 if (!pdata) 191 continue; 192 193 if (!(pdata->dwCharacter & NCCF_ALLOW_RENAME)) 194 *rgfInOut &= ~SFGAO_CANRENAME; 195 196 apidl++; 197 cidl--; 198 } 199 } 200 201 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */ 202 *rgfInOut &= ~SFGAO_VALIDATE; 203 204 return hr; 205 } 206 207 /************************************************************************** 208 * ISF_NetConnect_fnGetUIObjectOf 209 * 210 * PARAMETERS 211 * hwndOwner [in] Parent window for any output 212 * cidl [in] array size 213 * apidl [in] simple pidl array 214 * riid [in] Requested Interface 215 * prgfInOut [ ] reserved 216 * ppvObject [out] Resulting Interface 217 * 218 */ 219 220 HRESULT WINAPI CNetworkConnections::GetUIObjectOf( 221 HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, 222 UINT * prgfInOut, LPVOID * ppvOut) 223 { 224 IUnknown *pObj = NULL; 225 HRESULT hr = E_INVALIDARG; 226 227 if (!ppvOut) 228 return hr; 229 230 *ppvOut = NULL; 231 232 if ((IsEqualIID(riid, IID_IContextMenu) || IsEqualIID (riid, IID_IContextMenu2) || IsEqualIID(riid, IID_IContextMenu3) || 233 IsEqualIID(riid, IID_IQueryInfo) || IsEqualIID(riid, IID_IExtractIconW)) && cidl >= 1) 234 { 235 return ShellObjectCreatorInit<CNetConUiObject>(apidl[0], m_lpOleCmd, riid, ppvOut); 236 } 237 else 238 hr = E_NOINTERFACE; 239 240 *ppvOut = pObj; 241 return hr; 242 } 243 244 /************************************************************************** 245 * ISF_NetConnect_fnGetDisplayNameOf 246 * 247 */ 248 HRESULT WINAPI CNetworkConnections::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet) 249 { 250 if (!strRet) 251 return E_INVALIDARG; 252 253 if (!pidl) 254 return SHSetStrRet(strRet, netshell_hInstance, IDS_NETWORKCONNECTION); 255 256 PWCHAR pwchName = ILGetConnName(pidl); 257 if (!pwchName) 258 { 259 ERR("Got invalid pidl\n"); 260 return E_INVALIDARG; 261 } 262 263 return SHSetStrRet(strRet, pwchName); 264 } 265 266 /************************************************************************** 267 * ISF_NetConnect_fnSetNameOf 268 * Changes the name of a file object or subfolder, possibly changing its item 269 * identifier in the process. 270 * 271 * PARAMETERS 272 * hwndOwner [in] Owner window for output 273 * pidl [in] simple pidl of item to change 274 * lpszName [in] the items new display name 275 * dwFlags [in] SHGNO formatting flags 276 * ppidlOut [out] simple pidl returned 277 */ 278 HRESULT WINAPI CNetworkConnections::SetNameOf ( 279 HWND hwndOwner, PCUITEMID_CHILD pidl, /*simple pidl */ 280 LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD * pPidlOut) 281 { 282 HRESULT hr; 283 CComPtr<INetConnection> pCon; 284 285 hr = ILGetConnection(pidl, &pCon); 286 if (FAILED_UNEXPECTEDLY(hr)) 287 return hr; 288 289 hr = pCon->Rename(lpName); 290 if (FAILED_UNEXPECTEDLY(hr)) 291 return hr; 292 293 if (pPidlOut) 294 { 295 *pPidlOut = ILCreateNetConnectItem(pCon); 296 if (*pPidlOut == NULL) 297 return E_FAIL; 298 } 299 300 return S_OK; 301 } 302 303 HRESULT WINAPI CNetworkConnections::GetDefaultSearchGUID(GUID * pguid) 304 { 305 return E_NOTIMPL; 306 } 307 308 HRESULT WINAPI CNetworkConnections::EnumSearches(IEnumExtraSearch ** ppenum) 309 { 310 return E_NOTIMPL; 311 } 312 313 HRESULT WINAPI CNetworkConnections::GetDefaultColumn(DWORD dwRes, ULONG * pSort, ULONG * pDisplay) 314 { 315 if (pSort) 316 *pSort = 0; 317 if (pDisplay) 318 *pDisplay = 0; 319 320 return S_OK; 321 } 322 323 HRESULT WINAPI CNetworkConnections::GetDefaultColumnState(UINT iColumn, DWORD * pcsFlags) 324 { 325 if (!pcsFlags || iColumn >= NETCONNECTSHELLVIEWCOLUMNS) 326 return E_INVALIDARG; 327 *pcsFlags = NetConnectSFHeader[iColumn].pcsFlags; 328 return S_OK; 329 } 330 331 HRESULT WINAPI CNetworkConnections::GetDetailsEx( 332 PCUITEMID_CHILD pidl, const SHCOLUMNID * pscid, VARIANT * pv) 333 { 334 return E_NOTIMPL; 335 } 336 337 HRESULT WINAPI CNetworkConnections::GetDetailsOf( 338 PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS * psd) 339 { 340 if (iColumn >= NETCONNECTSHELLVIEWCOLUMNS) 341 return E_FAIL; 342 343 psd->fmt = NetConnectSFHeader[iColumn].fmt; 344 psd->cxChar = NetConnectSFHeader[iColumn].cxChar; 345 if (pidl == NULL) 346 return SHSetStrRet(&psd->str, netshell_hInstance, NetConnectSFHeader[iColumn].colnameid); 347 348 PNETCONIDSTRUCT pdata = ILGetConnData(pidl); 349 if (!pdata) 350 return E_FAIL; 351 352 switch (iColumn) 353 { 354 case COLUMN_NAME: 355 return SHSetStrRet(&psd->str, ILGetConnName(pidl)); 356 case COLUMN_TYPE: 357 if (pdata->MediaType == NCM_LAN || pdata->MediaType == NCM_SHAREDACCESSHOST_RAS) 358 { 359 return SHSetStrRet(&psd->str, netshell_hInstance, IDS_TYPE_ETHERNET); 360 } 361 else 362 { 363 return SHSetStrRet(&psd->str, ""); 364 } 365 break; 366 case COLUMN_STATUS: 367 switch(pdata->Status) 368 { 369 case NCS_HARDWARE_DISABLED: 370 return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_NON_OPERATIONAL); 371 case NCS_DISCONNECTED: 372 return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_UNREACHABLE); 373 case NCS_MEDIA_DISCONNECTED: 374 return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_DISCONNECTED); 375 case NCS_CONNECTING: 376 return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_CONNECTING); 377 case NCS_CONNECTED: 378 return SHSetStrRet(&psd->str, netshell_hInstance, IDS_STATUS_CONNECTED); 379 default: 380 return SHSetStrRet(&psd->str, ""); 381 } 382 break; 383 case COLUMN_DEVNAME: 384 return SHSetStrRet(&psd->str, ILGetDeviceName(pidl)); 385 case COLUMN_PHONE: 386 case COLUMN_OWNER: 387 return SHSetStrRet(&psd->str, ""); 388 } 389 390 return E_FAIL; 391 } 392 393 HRESULT WINAPI CNetworkConnections::MapColumnToSCID(UINT column, SHCOLUMNID *pscid) 394 { 395 return E_NOTIMPL; 396 } 397 398 //IObjectWithSite 399 //IInternetSecurityManager 400 401 /************************************************************************** 402 * IContextMenu2 Implementation 403 */ 404 405 CNetConUiObject::CNetConUiObject() 406 : m_pidl(NULL) 407 { 408 } 409 410 CNetConUiObject::~CNetConUiObject() 411 { 412 } 413 414 HRESULT WINAPI CNetConUiObject::Initialize(PCUITEMID_CHILD pidl, IOleCommandTarget *lpOleCmd) 415 { 416 m_pidl = pidl; 417 m_lpOleCmd = lpOleCmd; 418 return S_OK; 419 } 420 421 void WINAPI _InsertMenuItemW ( 422 HMENU hmenu, 423 UINT indexMenu, 424 BOOL fByPosition, 425 UINT wID, 426 UINT fType, 427 LPCWSTR dwTypeData, 428 UINT fState) 429 { 430 MENUITEMINFOW mii; 431 WCHAR szText[100]; 432 433 ZeroMemory(&mii, sizeof(mii)); 434 mii.cbSize = sizeof(mii); 435 if (fType == MFT_SEPARATOR) 436 { 437 mii.fMask = MIIM_ID | MIIM_TYPE; 438 } 439 else if (fType == MFT_STRING) 440 { 441 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; 442 if ((ULONG_PTR)HIWORD((ULONG_PTR)dwTypeData) == 0) 443 { 444 if (LoadStringW(netshell_hInstance, LOWORD((ULONG_PTR)dwTypeData), szText, sizeof(szText)/sizeof(WCHAR))) 445 { 446 szText[(sizeof(szText)/sizeof(WCHAR))-1] = 0; 447 mii.dwTypeData = szText; 448 } 449 else 450 { 451 return; 452 } 453 } 454 else 455 { 456 mii.dwTypeData = (LPWSTR) dwTypeData; 457 } 458 mii.fState = fState; 459 } 460 461 mii.wID = wID; 462 mii.fType = fType; 463 InsertMenuItemW( hmenu, indexMenu, fByPosition, &mii); 464 } 465 466 /************************************************************************** 467 * ISF_NetConnect_IContextMenu_QueryContextMenu() 468 */ 469 HRESULT WINAPI CNetConUiObject::QueryContextMenu( 470 HMENU hMenu, 471 UINT indexMenu, 472 UINT idCmdFirst, 473 UINT idCmdLast, 474 UINT uFlags) 475 { 476 PNETCONIDSTRUCT pdata = ILGetConnData(m_pidl); 477 if (!pdata) 478 { 479 ERR("Got invalid pidl\n"); 480 return E_FAIL; 481 } 482 483 if (pdata->Status == NCS_HARDWARE_DISABLED || pdata->Status == NCS_MEDIA_DISCONNECTED || pdata->Status == NCS_DISCONNECTED) 484 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_ACTIVATE), MFS_DEFAULT); 485 else 486 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 1, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DEACTIVATE), MFS_ENABLED); 487 488 if (pdata->Status == NCS_HARDWARE_DISABLED || pdata->Status == NCS_MEDIA_DISCONNECTED || pdata->Status == NCS_DISCONNECTED) 489 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_GRAYED); 490 else if (pdata->Status == NCS_CONNECTED) 491 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_DEFAULT); 492 else 493 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 2, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_ENABLED); 494 495 if (pdata->Status == NCS_HARDWARE_DISABLED || pdata->Status == NCS_MEDIA_DISCONNECTED) 496 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 3, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_GRAYED); 497 else 498 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 3, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_ENABLED); 499 500 _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); 501 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 4, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_CREATELINK), MFS_ENABLED); 502 503 if (pdata->dwCharacter & NCCF_ALLOW_REMOVAL) 504 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 5, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_ENABLED); 505 else 506 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 5, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_GRAYED); 507 508 if (pdata->dwCharacter & NCCF_ALLOW_RENAME) 509 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 6, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_ENABLED); 510 else 511 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 6, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_GRAYED); 512 513 _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED); 514 if (pdata->Status == NCS_CONNECTED) 515 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 7, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_ENABLED); 516 else 517 _InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + 7, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_DEFAULT); 518 519 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 9); 520 } 521 522 BOOL 523 CALLBACK 524 PropSheetExCallback(HPROPSHEETPAGE hPage, LPARAM lParam) 525 { 526 PROPSHEETHEADERW *pinfo = (PROPSHEETHEADERW *)lParam; 527 528 if (pinfo->nPages < MAX_PROPERTY_SHEET_PAGE) 529 { 530 pinfo->phpage[pinfo->nPages++] = hPage; 531 return TRUE; 532 } 533 return FALSE; 534 } 535 536 HRESULT 537 ShowNetConnectionStatus( 538 IOleCommandTarget *lpOleCmd, 539 PCUITEMID_CHILD pidl, 540 HWND hwnd) 541 { 542 if (!lpOleCmd) 543 return E_FAIL; 544 545 PNETCONIDSTRUCT pdata = ILGetConnData(pidl); 546 if (!pdata) 547 { 548 ERR("Got invalid pidl\n"); 549 return E_FAIL; 550 } 551 552 return lpOleCmd->Exec(&pdata->guidId, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL); 553 } 554 555 static int CALLBACK 556 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 557 { 558 // NOTE: This callback is needed to set large icon correctly. 559 HICON hIcon; 560 switch (uMsg) 561 { 562 case PSCB_INITIALIZED: 563 { 564 hIcon = LoadIconW(netshell_hInstance, MAKEINTRESOURCEW(IDI_SHELL_NETWORK_FOLDER)); 565 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 566 break; 567 } 568 } 569 return 0; 570 } 571 572 HRESULT 573 ShowNetConnectionProperties( 574 INetConnection *pNetConnect, 575 HWND hwnd) 576 { 577 HRESULT hr; 578 CLSID ClassID; 579 PROPSHEETHEADERW pinfo; 580 HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE]; 581 CComPtr<INetConnectionPropertyUi> pNCP; 582 NETCON_PROPERTIES * pProperties; 583 584 if (pNetConnect->GetProperties(&pProperties) != S_OK) 585 return E_FAIL; 586 587 hr = pNetConnect->GetUiObjectClassId(&ClassID); 588 if (FAILED(hr)) 589 { 590 NcFreeNetconProperties(pProperties); 591 return hr; 592 } 593 594 hr = CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER, IID_INetConnectionPropertyUi, (LPVOID*)&pNCP); 595 if (FAILED(hr)) 596 { 597 NcFreeNetconProperties(pProperties); 598 return hr; 599 } 600 601 hr = pNCP->SetConnection(pNetConnect); 602 if (SUCCEEDED(hr)) 603 { 604 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW)); 605 ZeroMemory(hppages, sizeof(hppages)); 606 pinfo.dwSize = sizeof(PROPSHEETHEADERW); 607 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW | 608 PSH_USEICONID | PSH_USECALLBACK; 609 pinfo.hInstance = netshell_hInstance; 610 pinfo.pszIcon = MAKEINTRESOURCEW(IDI_SHELL_NETWORK_FOLDER); 611 pinfo.phpage = hppages; 612 pinfo.hwndParent = hwnd; 613 pinfo.pfnCallback = PropSheetProc; 614 615 pinfo.pszCaption = pProperties->pszwName; 616 hr = pNCP->AddPages(hwnd, PropSheetExCallback, (LPARAM)&pinfo); 617 if (SUCCEEDED(hr)) 618 { 619 if (PropertySheetW(&pinfo) < 0) 620 hr = E_FAIL; 621 } 622 } 623 NcFreeNetconProperties(pProperties); 624 return hr; 625 } 626 627 628 /************************************************************************** 629 * ISF_NetConnect_IContextMenu_InvokeCommand() 630 */ 631 HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) 632 { 633 UINT CmdId = LOWORD(lpcmi->lpVerb) + IDS_NET_ACTIVATE; 634 635 /* We should get this when F2 is pressed in explorer */ 636 if (!IS_INTRESOURCE(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "rename")) 637 { 638 CmdId = IDS_NET_RENAME; 639 } 640 else if (!IS_INTRESOURCE(lpcmi->lpVerb) && !strcmp(lpcmi->lpVerb, "properties")) 641 { 642 CmdId = IDS_NET_PROPERTIES; 643 } 644 else if (!IS_INTRESOURCE(lpcmi->lpVerb) || LOWORD(lpcmi->lpVerb) > 7) 645 { 646 FIXME("Got invalid command\n"); 647 return E_NOTIMPL; 648 } 649 650 switch(CmdId) 651 { 652 case IDS_NET_RENAME: 653 { 654 HRESULT hr; 655 CComPtr<IShellView> psv; 656 hr = IUnknown_QueryService(m_pUnknown, SID_IFolderView, IID_PPV_ARG(IShellView, &psv)); 657 if (SUCCEEDED(hr)) 658 { 659 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT; 660 psv->SelectItem(m_pidl, selFlags); 661 } 662 663 return S_OK; 664 } 665 case IDS_NET_STATUS: 666 { 667 return ShowNetConnectionStatus(m_lpOleCmd, m_pidl, lpcmi->hwnd); 668 } 669 case IDS_NET_REPAIR: 670 case IDS_NET_CREATELINK: 671 case IDS_NET_DELETE: 672 FIXME("Command %u is not implemented\n", CmdId); 673 return E_NOTIMPL; 674 } 675 676 HRESULT hr; 677 CComPtr<INetConnection> pCon; 678 679 hr = ILGetConnection(m_pidl, &pCon); 680 if (FAILED_UNEXPECTEDLY(hr)) 681 return hr; 682 683 switch(CmdId) 684 { 685 case IDS_NET_ACTIVATE: 686 return pCon->Connect(); 687 case IDS_NET_DEACTIVATE: 688 return pCon->Disconnect(); 689 case IDS_NET_PROPERTIES: 690 return ShowNetConnectionProperties(pCon, lpcmi->hwnd); 691 } 692 693 return E_NOTIMPL; 694 } 695 696 /************************************************************************** 697 * ISF_NetConnect_IContextMenu_GetCommandString() 698 * 699 */ 700 HRESULT WINAPI CNetConUiObject::GetCommandString( 701 UINT_PTR idCommand, 702 UINT uFlags, 703 UINT* lpReserved, 704 LPSTR lpszName, 705 UINT uMaxNameLen) 706 { 707 return E_FAIL; 708 } 709 710 /************************************************************************** 711 * ISF_NetConnect_IContextMenu_HandleMenuMsg() 712 */ 713 HRESULT WINAPI CNetConUiObject::HandleMenuMsg( 714 UINT uMsg, 715 WPARAM wParam, 716 LPARAM lParam) 717 { 718 return E_NOTIMPL; 719 } 720 721 HRESULT WINAPI CNetConUiObject::HandleMenuMsg2( 722 UINT uMsg, 723 WPARAM wParam, 724 LPARAM lParam, 725 LRESULT *plResult) 726 { 727 return E_NOTIMPL; 728 } 729 730 HRESULT WINAPI CNetConUiObject::GetSite(REFIID riid, PVOID *ppvSite) 731 { 732 if (!m_pUnknown) 733 { 734 *ppvSite = NULL; 735 return E_FAIL; 736 } 737 738 return m_pUnknown->QueryInterface(riid, ppvSite); 739 } 740 741 HRESULT WINAPI CNetConUiObject::SetSite(IUnknown *pUnkSite) 742 { 743 m_pUnknown = pUnkSite; 744 return S_OK; 745 } 746 747 /************************************************************************ 748 * ISF_NetConnect_IExtractIcon_GetIconLocation 749 */ 750 HRESULT WINAPI CNetConUiObject::GetIconLocation( 751 UINT uFlags, 752 LPWSTR szIconFile, 753 UINT cchMax, 754 int *piIndex, 755 UINT *pwFlags) 756 { 757 *pwFlags = 0; 758 if (!GetModuleFileNameW(netshell_hInstance, szIconFile, cchMax)) 759 { 760 ERR("GetModuleFileNameW failed\n"); 761 return E_FAIL; 762 } 763 764 PNETCONIDSTRUCT pdata = ILGetConnData(m_pidl); 765 if (!pdata) 766 { 767 ERR("Got invalid pidl\n"); 768 return E_FAIL; 769 } 770 771 if (pdata->Status == NCS_CONNECTED || pdata->Status == NCS_CONNECTING) 772 *piIndex = -IDI_NET_IDLE; 773 else 774 *piIndex = -IDI_NET_OFF; 775 776 return S_OK; 777 } 778 779 /************************************************************************ 780 * ISF_NetConnect_IExtractIcon_Extract 781 */ 782 HRESULT WINAPI CNetConUiObject::Extract( 783 LPCWSTR pszFile, 784 UINT nIconIndex, 785 HICON *phiconLarge, 786 HICON *phiconSmall, 787 UINT nIconSize) 788 { 789 return SHDefExtractIconW(pszFile, nIconIndex, 0, phiconLarge, phiconSmall, nIconSize); 790 } 791 792 /************************************************************************ 793 * ISF_NetConnect_PersistFolder2_GetClassID 794 */ 795 HRESULT WINAPI CNetworkConnections::GetClassID(CLSID *lpClassId) 796 { 797 if (!lpClassId) 798 return E_POINTER; 799 800 *lpClassId = CLSID_ConnectionFolder; 801 802 return S_OK; 803 } 804 805 /************************************************************************ 806 * ISF_NetConnect_PersistFolder2_Initialize 807 * 808 * NOTES: it makes no sense to change the pidl 809 */ 810 HRESULT WINAPI CNetworkConnections::Initialize(PCIDLIST_ABSOLUTE pidl) 811 { 812 if (m_pidlRoot) 813 SHFree(m_pidlRoot); 814 m_pidlRoot = ILClone(pidl); 815 816 return S_OK; 817 } 818 819 /************************************************************************** 820 * ISF_NetConnect_PersistFolder2_GetCurFolder 821 */ 822 HRESULT WINAPI CNetworkConnections::GetCurFolder(PIDLIST_ABSOLUTE *pidl) 823 { 824 if (!pidl) 825 return E_POINTER; 826 827 *pidl = ILClone(m_pidlRoot); 828 829 return S_OK; 830 } 831 832 /************************************************************************ 833 * ISF_NetConnect_ShellExecuteHookW_Execute 834 */ 835 HRESULT WINAPI CNetworkConnections::Execute(LPSHELLEXECUTEINFOW pei) 836 { 837 PCUITEMID_CHILD pidl = ILFindLastID((ITEMIDLIST*)pei->lpIDList); 838 PNETCONIDSTRUCT pdata = ILGetConnData(pidl); 839 if (!pdata) 840 { 841 ERR("Got invalid pidl\n"); 842 return E_FAIL; 843 } 844 845 if (pdata->Status == NCS_CONNECTED) 846 { 847 return ShowNetConnectionStatus(m_lpOleCmd, pidl, pei->hwnd); 848 } 849 850 return S_OK; 851 } 852 853 HRESULT WINAPI CNetworkConnections::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID) 854 { 855 FIXME("CNetworkConnections::Initialize()\n"); 856 return E_NOTIMPL; 857 } 858 859 HRESULT WINAPI CNetworkConnections::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) 860 { 861 FIXME("CNetworkConnections::Exec()\n"); 862 return E_NOTIMPL; 863 } 864 865 HRESULT WINAPI CNetworkConnections::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) 866 { 867 FIXME("CNetworkConnections::QueryStatus()\n"); 868 return E_NOTIMPL; 869 } 870 871 HRESULT WINAPI CNetworkConnections::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) 872 { 873 FIXME("CNetworkConnections::MessageSFVCB()\n"); 874 return E_NOTIMPL; 875 } 876 877 HRESULT WINAPI CNetConUiObject::GetInfoFlags(DWORD *pdwFlags) 878 { 879 *pdwFlags = 0; 880 881 return S_OK; 882 } 883 884 /************************************************************************ 885 * ISF_NetConnect_PersistFolder2_Initialize 886 * 887 * NOTES: it makes no sense to change the pidl 888 */ 889 HRESULT WINAPI CNetConUiObject::GetInfoTip(DWORD dwFlags, WCHAR **ppwszTip) 890 { 891 *ppwszTip = NULL; 892 return S_OK; 893 } 894