Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1305 lines
41 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: I S H E L L F 2 . C P P
  7. //
  8. // Contents: Provide IShellFolder2 interface for CConnectionsFolderDetails
  9. // interface. Supercedes IShellDetails. This does not describe
  10. // IShellFolder members of IShellFolder2 - those are provided in ishellf.cpp
  11. // This object is created by the ishellv code, primarily to support the
  12. // WebView data pane in the folder
  13. //
  14. // Notes:
  15. //
  16. // Author: deonb 18 May 20000
  17. //
  18. //----------------------------------------------------------------------------
  19. #include "pch.h"
  20. #pragma hdrstop
  21. #include "foldinc.h" // Standard shell\folder includes
  22. #include "cfutils.h" // Connections folder utilities
  23. #include "raserror.h"
  24. #include "naming.h"
  25. //---[ externs ]--------------------------------------------------------------
  26. extern COLS c_rgCols[];
  27. inline HRESULT HrCopyToSTRRET(
  28. STRRET * pstr,
  29. PCWSTR pszIn)
  30. {
  31. HRESULT hr = S_OK;
  32. UINT uiByteLen = (lstrlen(pszIn) + 1) * sizeof(WCHAR);
  33. Assert(pstr);
  34. if (!pstr)
  35. {
  36. hr = E_INVALIDARG;
  37. }
  38. else
  39. {
  40. pstr->uType = STRRET_WSTR;
  41. pstr->pOleStr = (PWSTR) SHAlloc(uiByteLen);
  42. if (pstr->pOleStr == NULL)
  43. {
  44. hr = E_OUTOFMEMORY;
  45. }
  46. else
  47. {
  48. CopyMemory(pstr->pOleStr, pszIn, uiByteLen);
  49. }
  50. }
  51. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrCopyToSTRRET");
  52. return hr;
  53. }
  54. const WCHAR c_szDevice[] = L"\\DEVICE\\";
  55. const WCHAR c_szLocalSubnet[] = L"255.255.255.255";
  56. const WCHAR c_crlf[] = L"\r\n";
  57. HRESULT HrGetAutoNetSetting(PWSTR pszGuid, DHCP_ADDRESS_TYPE * pAddrType);
  58. HRESULT HrGetAutoNetSetting(REFGUID pGuidId, DHCP_ADDRESS_TYPE * pAddrType);
  59. //+---------------------------------------------------------------------------
  60. //
  61. // Member: GetAutoNetSettingsForAdapter
  62. //
  63. // Purpose: Get the AutoNet settings for an adapter and return inside a
  64. // formatted string
  65. //
  66. // Arguments:
  67. // cfe [in] The connectoid
  68. // uiFormatString [in] ResourceID of the FormatMessage (not sprintf) compatible
  69. // Format string
  70. // szString [out] Output string
  71. //
  72. // Returns:
  73. //
  74. // Author: deonb 2 April 2001
  75. //
  76. // Notes:
  77. //
  78. HRESULT GetAutoNetSettingsForAdapter(IN const CConFoldEntry& cfe, IN UINT uiFormatString, OUT tstring& szString)
  79. {
  80. HRESULT hr = S_OK;
  81. LPCWSTR szTmpString = NULL;
  82. if (IsMediaRASType(cfe.GetNetConMediaType()))
  83. {
  84. szTmpString = SzLoadIds(IDS_DHCP_ISP);
  85. }
  86. else
  87. {
  88. DHCP_ADDRESS_TYPE DhcpAddress;
  89. hr = HrGetAutoNetSetting(cfe.GetGuidID(), &DhcpAddress);
  90. if (SUCCEEDED(hr))
  91. {
  92. switch (DhcpAddress)
  93. {
  94. case UNKNOWN_ADDR:
  95. hr = E_FAIL;
  96. break;
  97. case NORMAL_ADDR:
  98. szTmpString = SzLoadIds(IDS_DHCP);
  99. break;
  100. case AUTONET_ADDR:
  101. szTmpString = SzLoadIds(IDS_AUTONET);
  102. break;
  103. case ALTERNATE_ADDR:
  104. szTmpString = SzLoadIds(IDS_ALTERNATE_ADDR);
  105. break;
  106. case STATIC_ADDR:
  107. szTmpString = SzLoadIds(IDS_STATIC_CFG);
  108. break;
  109. default:
  110. hr = E_FAIL;
  111. AssertSz(NULL, "Invalid DHCP Address type");
  112. }
  113. }
  114. }
  115. if (szTmpString)
  116. {
  117. WCHAR szFormatBuf[1024];
  118. if (DwFormatString(SzLoadIds(uiFormatString), szFormatBuf, 1024, szTmpString))
  119. {
  120. szString = szFormatBuf;
  121. }
  122. else
  123. {
  124. hr = HrFromLastWin32Error();
  125. }
  126. }
  127. TraceHr(ttidShellFolder, FAL, hr, FALSE, "GetAutoNetSettingsForAdapter");
  128. return hr;
  129. }
  130. //+---------------------------------------------------------------------------
  131. //
  132. // Member: GetPrimaryIPAddressForAdapter
  133. //
  134. // Purpose: Get the primary IP Address for an adapter and return inside a
  135. // formatted string
  136. //
  137. // Arguments:
  138. // cfe [in] The connectoid
  139. // uiFormatString [in] ResourceID of the FormatMessage (not sprintf) compatible
  140. // Format string
  141. // szString [out] Output string
  142. //
  143. // Returns:
  144. //
  145. // Author: deonb 2 April 2001
  146. //
  147. // Notes:
  148. //
  149. HRESULT GetPrimaryIPAddressForAdapter(IN const CConFoldEntry& cfe, IN UINT uiFormatString, OUT tstring& szString)
  150. {
  151. HRESULT hr = S_OK;
  152. if (IsMediaRASType(cfe.GetNetConMediaType()))
  153. {
  154. DWORD cb = sizeof(RASCONN);
  155. DWORD cConnections;
  156. DWORD dwErr;
  157. LPRASCONN pRasConn = reinterpret_cast<LPRASCONN>(new BYTE[cb]);
  158. if (!pRasConn)
  159. {
  160. return E_OUTOFMEMORY;
  161. }
  162. pRasConn->dwSize = sizeof(RASCONN);
  163. do
  164. {
  165. dwErr = RasEnumConnections(pRasConn, &cb, &cConnections);
  166. if (ERROR_BUFFER_TOO_SMALL == dwErr)
  167. {
  168. delete[] pRasConn;
  169. pRasConn = reinterpret_cast<LPRASCONN>(new BYTE[cb]);
  170. if (!pRasConn)
  171. {
  172. return E_OUTOFMEMORY;
  173. }
  174. }
  175. } while (ERROR_BUFFER_TOO_SMALL == dwErr);
  176. if (!dwErr)
  177. {
  178. Assert( (cb % sizeof(RASCONN)) == 0);
  179. DWORD dwItems = cb / sizeof(RASCONN);
  180. for (DWORD x = 0; x < dwItems; x++)
  181. {
  182. if (pRasConn[x].guidEntry == cfe.GetGuidID())
  183. {
  184. RASPPPIP rasPPPIP;
  185. rasPPPIP.dwSize = sizeof(RASPPPIP);
  186. DWORD dwSize = rasPPPIP.dwSize;
  187. dwErr = RasGetProjectionInfo(pRasConn[x].hrasconn, RASP_PppIp, &rasPPPIP, &dwSize);
  188. if (!dwErr)
  189. {
  190. WCHAR szFormatBuf[MAX_PATH];
  191. if (DwFormatString(
  192. SzLoadIds(uiFormatString),
  193. szFormatBuf,
  194. MAX_PATH,
  195. rasPPPIP.szIpAddress,
  196. c_szLocalSubnet
  197. ) )
  198. {
  199. szString = szFormatBuf;
  200. }
  201. else
  202. {
  203. hr = HrFromLastWin32Error();
  204. }
  205. }
  206. else
  207. {
  208. Assert(dwErr != ERROR_BUFFER_TOO_SMALL);
  209. hr = HrFromLastWin32Error();
  210. }
  211. }
  212. }
  213. }
  214. else
  215. {
  216. hr = HrFromLastWin32Error();
  217. }
  218. }
  219. else
  220. {
  221. PIP_ADAPTER_INFO pAdapterInfo = NULL;
  222. DWORD dwOutBufLen = 0;
  223. DWORD dwRet = ERROR_SUCCESS;
  224. dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen);
  225. if (dwRet == ERROR_BUFFER_OVERFLOW)
  226. {
  227. pAdapterInfo = (PIP_ADAPTER_INFO) CoTaskMemAlloc(dwOutBufLen);
  228. if (NULL == pAdapterInfo)
  229. {
  230. hr = E_OUTOFMEMORY;
  231. }
  232. }
  233. else if (ERROR_SUCCESS == dwRet)
  234. {
  235. hr = E_FAIL;
  236. }
  237. else
  238. {
  239. hr = HRESULT_FROM_WIN32(dwRet);
  240. }
  241. if (SUCCEEDED(hr))
  242. {
  243. dwRet = GetAdaptersInfo(pAdapterInfo, &dwOutBufLen);
  244. if (ERROR_SUCCESS != dwRet)
  245. {
  246. CoTaskMemFree(pAdapterInfo);
  247. hr = HRESULT_FROM_WIN32(dwRet);
  248. }
  249. if (SUCCEEDED(hr))
  250. {
  251. WCHAR wszGuid[c_cchGuidWithTerm];
  252. ::StringFromGUID2(cfe.GetGuidID(), wszGuid, c_cchGuidWithTerm);
  253. BOOL fFound = FALSE;
  254. PIP_ADAPTER_INFO pAdapterInfoEnum = pAdapterInfo;
  255. while (pAdapterInfoEnum)
  256. {
  257. USES_CONVERSION;
  258. if (lstrcmp(wszGuid, A2W(pAdapterInfoEnum->AdapterName)) == 0)
  259. {
  260. LPCWSTR strIPAddress = A2W(pAdapterInfoEnum->IpAddressList.IpAddress.String);
  261. LPCWSTR strSubnetMask = A2W(pAdapterInfoEnum->IpAddressList.IpMask.String);
  262. LPCWSTR strGateway = A2W(pAdapterInfoEnum->GatewayList.IpAddress.String);
  263. WCHAR szFormatBuf[MAX_PATH];
  264. LPCWSTR szMode = NULL;
  265. if (strIPAddress && strSubnetMask && strGateway)
  266. {
  267. LPCWSTR szArgs[] = {strIPAddress, strSubnetMask};
  268. if (DwFormatString(
  269. SzLoadIds(uiFormatString), // lpSource
  270. szFormatBuf, // Buffer
  271. MAX_PATH, // Len
  272. strIPAddress,
  273. strSubnetMask
  274. ) )
  275. {
  276. szString = szFormatBuf;
  277. }
  278. else
  279. {
  280. hr = HrFromLastWin32Error();
  281. }
  282. }
  283. break;
  284. }
  285. pAdapterInfoEnum = pAdapterInfoEnum->Next;
  286. }
  287. CoTaskMemFree(pAdapterInfo);
  288. }
  289. }
  290. }
  291. TraceHr(ttidShellFolder, FAL, hr, FALSE, "GetPrimaryIPAddressForAdapter");
  292. return hr;
  293. }
  294. //+---------------------------------------------------------------------------
  295. //
  296. // Member: GetWirelessModeForAdapter
  297. //
  298. // Purpose: Get the Wireless mode for an adapter and return inside a
  299. // formatted string
  300. //
  301. // Arguments:
  302. // cfe [in] The connectoid
  303. // uiFormatString [in] ResourceID of the FormatMessage (not sprintf) compatible
  304. // Format string
  305. // szString [out] Output string
  306. //
  307. // Returns:
  308. //
  309. // Author: deonb 2 April 2001
  310. //
  311. // Notes:
  312. //
  313. HRESULT GetWirelessModeForAdapter(IN const CConFoldEntry& cfe, IN UINT uiFormatString, OUT tstring& szString)
  314. {
  315. HRESULT hr = S_OK;
  316. DWORD dwInfraStructureMode = 0;
  317. DWORD dwInfraStructureModeSize = sizeof(DWORD);
  318. hr = HrQueryNDISAdapterOID(cfe.GetGuidID(),
  319. OID_802_11_INFRASTRUCTURE_MODE,
  320. &dwInfraStructureModeSize,
  321. &dwInfraStructureMode);
  322. if (SUCCEEDED(hr))
  323. {
  324. WCHAR szTmpBuf[MAX_PATH];
  325. LPCWSTR szMode = NULL;
  326. switch (dwInfraStructureMode)
  327. {
  328. case Ndis802_11IBSS:
  329. szMode = SzLoadIds(IDS_TOOLTIP_ADHOC);
  330. break;
  331. case Ndis802_11Infrastructure:
  332. szMode = SzLoadIds(IDS_TOOLTIP_INFRASTRUCTURE);
  333. break;
  334. }
  335. if (szMode)
  336. {
  337. if (DwFormatString(
  338. SzLoadIds(uiFormatString),
  339. szTmpBuf, // Buffer
  340. MAX_PATH, // Len
  341. szMode
  342. ))
  343. {
  344. szString = szTmpBuf;
  345. }
  346. else
  347. {
  348. hr = HrFromLastWin32Error();
  349. }
  350. }
  351. }
  352. TraceHr(ttidShellFolder, FAL, hr, FALSE, "GetWirelessModeForAdapter");
  353. return hr;
  354. }
  355. //+---------------------------------------------------------------------------
  356. //
  357. // Member: GetWirelessSSIDForAdapter
  358. //
  359. // Purpose: Get the Wireless SSID for an adapter and return inside a
  360. // formatted string
  361. //
  362. // Arguments:
  363. // cfe [in] The connectoid
  364. // uiFormatString [in] ResourceID of the FormatMessage (not sprintf) compatible
  365. // Format string
  366. // szString [out] Output string
  367. //
  368. // Returns:
  369. //
  370. // Author: deonb 4 April 2001
  371. //
  372. // Notes:
  373. //
  374. HRESULT GetWirelessSSIDForAdapter(IN const CConFoldEntry& cfe, IN UINT uiFormatString, OUT tstring& szString)
  375. {
  376. HRESULT hr = S_OK;
  377. NDIS_802_11_SSID ndisSSID;
  378. DWORD dwndisSSIDSize = sizeof(NDIS_802_11_SSID);
  379. hr = HrQueryNDISAdapterOID(cfe.GetGuidID(),
  380. OID_802_11_SSID,
  381. &dwndisSSIDSize,
  382. &ndisSSID);
  383. if (SUCCEEDED(hr))
  384. {
  385. if (ndisSSID.SsidLength > 1)
  386. {
  387. WCHAR szuSSID[sizeof(ndisSSID.Ssid)+1];
  388. DWORD dwLen = ndisSSID.SsidLength;
  389. if (dwLen > sizeof(ndisSSID.Ssid))
  390. {
  391. dwLen = sizeof(ndisSSID.Ssid);
  392. AssertSz(FALSE, "Unexpected SSID encountered");
  393. }
  394. ndisSSID.Ssid[dwLen] = 0;
  395. mbstowcs(szuSSID, reinterpret_cast<LPSTR>(ndisSSID.Ssid), celems(szuSSID));
  396. WCHAR szTmpBuf[MAX_PATH];
  397. if (DwFormatString(
  398. SzLoadIds(uiFormatString),
  399. szTmpBuf, // Buffer
  400. MAX_PATH, // Len
  401. szuSSID
  402. ))
  403. {
  404. szString = szTmpBuf;
  405. }
  406. else
  407. {
  408. hr = HrFromLastWin32Error();
  409. }
  410. }
  411. else
  412. {
  413. hr = E_FAIL;
  414. }
  415. }
  416. TraceHr(ttidShellFolder, FAL, hr, FALSE, "GetWirelessModeForAdapter");
  417. return hr;
  418. }
  419. //+---------------------------------------------------------------------------
  420. //
  421. // Member: GetWirelessEncryptionForAdapter
  422. //
  423. // Purpose: Get the Wireless Encryption for an adapter and return inside a
  424. // formatted string
  425. //
  426. // Arguments:
  427. // cfe [in] The connectoid
  428. // uiFormatString [in] ResourceID of the FormatMessage (not sprintf) compatible
  429. // Format string
  430. // szString [out] Output string
  431. //
  432. // Returns:
  433. //
  434. // Author: deonb 4 April 2001
  435. //
  436. // Notes:
  437. //
  438. HRESULT GetWirelessEncryptionForAdapter(IN const CConFoldEntry& cfe, IN UINT uiFormatString, OUT tstring& szString)
  439. {
  440. HRESULT hr = S_OK;
  441. DWORD dwEncryption = 0;
  442. DWORD dwEncryptionSize = sizeof(DWORD);
  443. hr = HrQueryNDISAdapterOID(cfe.GetGuidID(),
  444. OID_802_11_WEP_STATUS,
  445. &dwEncryptionSize,
  446. &dwEncryption);
  447. if (SUCCEEDED(hr))
  448. {
  449. WCHAR szTmpBuf[MAX_PATH];
  450. LPCWSTR szMode = NULL;
  451. if (Ndis802_11WEPEnabled == dwEncryption)
  452. {
  453. szMode = SzLoadIds(IDS_CONFOLD_STATUS_ENABLED);
  454. }
  455. else
  456. {
  457. szMode = SzLoadIds(IDS_CONFOLD_STATUS_DISABLED);
  458. }
  459. if (szMode)
  460. {
  461. if (DwFormatString(
  462. SzLoadIds(uiFormatString),
  463. szTmpBuf, // Buffer
  464. MAX_PATH, // Len
  465. szMode
  466. ))
  467. {
  468. szString = szTmpBuf;
  469. }
  470. else
  471. {
  472. hr = HrFromLastWin32Error();
  473. }
  474. }
  475. }
  476. TraceHr(ttidShellFolder, FAL, hr, FALSE, "GetWirelessEncryptionForAdapter");
  477. return hr;
  478. }
  479. //+---------------------------------------------------------------------------
  480. //
  481. // Member: GetWirelessSignalStrengthForAdapter
  482. //
  483. // Purpose: Get the Wireless Signal Strength for an adapter and return inside a
  484. // formatted string
  485. //
  486. // Arguments:
  487. // cfe [in] The connectoid
  488. // uiFormatString [in] ResourceID of the FormatMessage (not sprintf) compatible
  489. // Format string
  490. // szString [out] Output string
  491. //
  492. // Returns:
  493. //
  494. // Author: deonb 4 April 2001
  495. //
  496. // Notes:
  497. //
  498. HRESULT GetWirelessSignalStrengthForAdapter(IN const CConFoldEntry& cfe, IN UINT uiFormatString, OUT tstring& szString)
  499. {
  500. HRESULT hr = S_OK;
  501. DWORD pdwEnumValue;
  502. LONG lSignalStrength = 0;
  503. DWORD dwSignalStrengthSize = sizeof(DWORD);
  504. hr = HrQueryNDISAdapterOID(cfe.GetGuidID(),
  505. OID_802_11_RSSI,
  506. &dwSignalStrengthSize,
  507. &lSignalStrength);
  508. if (SUCCEEDED(hr))
  509. {
  510. WCHAR szTmpBuf[MAX_PATH];
  511. if (DwFormatString(
  512. SzLoadIds(uiFormatString),
  513. szTmpBuf, // Buffer
  514. MAX_PATH, // Len
  515. PszGetRSSIString(lSignalStrength)))
  516. {
  517. szString = szTmpBuf;
  518. }
  519. else
  520. {
  521. hr = HrFromLastWin32Error();
  522. }
  523. }
  524. TraceHr(ttidShellFolder, FAL, hr, FALSE, "GetWirelessSignalStrengthForAdapter");
  525. return hr;
  526. }
  527. //+---------------------------------------------------------------------------
  528. //
  529. // Member: CConnectionFolderDetails::GetDetailsOf
  530. //
  531. // Purpose: Returns the column information, either for the columns
  532. // themselves, or for the actual details of the view items.
  533. //
  534. // Arguments:
  535. // pidl [in] The pidl for the object being requested
  536. // iColumn [in] The details column needed
  537. // lpDetails [in] Buffer that receives the detail data
  538. //
  539. // Returns:
  540. //
  541. // Author: jeffspr 16 Mar 1998
  542. //
  543. // Notes:
  544. //
  545. HRESULT CConnectionFolder::GetDetailsOf(
  546. LPCITEMIDLIST pidl,
  547. UINT iColumn,
  548. LPSHELLDETAILS lpDetails)
  549. {
  550. TraceFileFunc(ttidShellFolder);
  551. HRESULT hr = S_OK;
  552. PCWSTR pszString = NULL;
  553. WCHAR szStatus[CONFOLD_MAX_STATUS_LENGTH];
  554. tstring szTmpString;
  555. // If the column requested is beyond our set of columns,
  556. // return failure.
  557. //
  558. if (((INT)iColumn < 0) || ((INT)iColumn >= ICOL_MAX))
  559. {
  560. hr = E_FAIL;
  561. }
  562. else
  563. {
  564. // If NULL, caller wants strings for the column headers
  565. //
  566. CONFOLDENTRY cfe; // Need this scope as we assign pszString from it.
  567. if (NULL == pidl)
  568. {
  569. if (c_rgCols[iColumn].iStringRes)
  570. {
  571. pszString = SzLoadIds(c_rgCols[iColumn].iStringRes);
  572. }
  573. lpDetails->fmt = c_rgCols[iColumn].iFormat;
  574. lpDetails->cxChar = c_rgCols[iColumn].iColumnSize;
  575. }
  576. else
  577. {
  578. INT iStringRes = 0;
  579. PCONFOLDPIDL pcfp;
  580. hr = pcfp.InitializeFromItemIDList(pidl);
  581. if (FAILED(hr))
  582. {
  583. return hr;
  584. }
  585. hr = pcfp.ConvertToConFoldEntry(cfe);
  586. if (SUCCEEDED(hr))
  587. {
  588. Assert(!cfe.empty());
  589. lpDetails->fmt = c_rgCols[iColumn].iColumnSize;
  590. lpDetails->cxChar = c_rgCols[iColumn].iColumnSize;
  591. if (!cfe.GetWizard())
  592. {
  593. // Retrieve the appropriate column
  594. //
  595. switch(iColumn)
  596. {
  597. case ICOL_NAME: // 0
  598. pszString = cfe.GetName();
  599. break;
  600. case ICOL_TYPE: // 1
  601. MapNCMToResourceId(cfe.GetNetConMediaType(), cfe.GetCharacteristics(), &iStringRes);
  602. pszString = SzLoadIds(iStringRes);
  603. break;
  604. case ICOL_STATUS: // 2
  605. MapNCSToComplexStatus(cfe.GetNetConStatus(), cfe.GetNetConMediaType(), cfe.GetNetConSubMediaType(), cfe.GetCharacteristics(), szStatus, CONFOLD_MAX_STATUS_LENGTH, cfe.GetGuidID());
  606. pszString = szStatus;
  607. break;
  608. case ICOL_DEVICE_NAME: // 3
  609. pszString = cfe.GetDeviceName();
  610. break;
  611. case ICOL_PHONEORHOSTADDRESS: // 4
  612. case ICOL_PHONENUMBER: // 7
  613. case ICOL_HOSTADDRESS: // 8
  614. pszString = cfe.GetPhoneOrHostAddress();
  615. break;
  616. case ICOL_OWNER: // 5
  617. if (cfe.GetCharacteristics() & NCCF_ALL_USERS)
  618. {
  619. pszString = SzLoadIds(IDS_CONFOLD_DETAILS_OWNER_SYSTEM);
  620. }
  621. else
  622. {
  623. pszString = PszGetOwnerStringFromCharacteristics(pszGetUserName(), cfe.GetCharacteristics() );
  624. }
  625. break;
  626. case ICOL_ADDRESS: //6
  627. {
  628. if (!fIsConnectedStatus(cfe.GetNetConStatus()))
  629. {
  630. hr = E_FAIL;
  631. }
  632. else
  633. {
  634. BOOL bSomeDetail = FALSE;
  635. tstring szAutonet;
  636. tstring szIp;
  637. hr = GetPrimaryIPAddressForAdapter(cfe, IDS_DETAILS_IP_ADDRESS, szIp);
  638. if (SUCCEEDED(hr))
  639. {
  640. szTmpString += szIp;
  641. bSomeDetail = TRUE;
  642. }
  643. hr = GetAutoNetSettingsForAdapter(cfe, IDS_DETAILS_ADDRESS_TYPE, szAutonet);
  644. if (SUCCEEDED(hr))
  645. {
  646. if (bSomeDetail)
  647. {
  648. szTmpString += c_crlf;
  649. }
  650. szTmpString += szAutonet;
  651. bSomeDetail = TRUE;
  652. }
  653. if (bSomeDetail)
  654. {
  655. hr = S_OK;
  656. pszString = szTmpString.c_str();
  657. }
  658. }
  659. }
  660. break;
  661. case ICOL_WIRELESS_MODE:
  662. {
  663. if ( (NCS_DISCONNECTED != cfe.GetNetConStatus()) &&
  664. (NCS_HARDWARE_DISABLED != cfe.GetNetConStatus()) &&
  665. (NCS_HARDWARE_MALFUNCTION!= cfe.GetNetConStatus()) &&
  666. (NCS_HARDWARE_NOT_PRESENT!= cfe.GetNetConStatus()) &&
  667. (NCS_MEDIA_DISCONNECTED != cfe.GetNetConStatus()) &&
  668. (cfe.GetNetConMediaType() == NCM_LAN) &&
  669. (cfe.GetNetConSubMediaType() == NCSM_WIRELESS) )
  670. {
  671. BOOL bSomeDetail = FALSE;
  672. tstring szString;
  673. hr = GetWirelessModeForAdapter(cfe, IDS_DETAILS_802_11_MODE, szString);
  674. if (SUCCEEDED(hr))
  675. {
  676. szTmpString += szString;
  677. bSomeDetail = TRUE;
  678. }
  679. hr = GetWirelessSSIDForAdapter(cfe, IDS_DETAILS_802_11_SSID_TYPE, szString);
  680. if (SUCCEEDED(hr))
  681. {
  682. if (bSomeDetail)
  683. {
  684. szTmpString += c_crlf;
  685. }
  686. szTmpString += szString;
  687. bSomeDetail = TRUE;
  688. }
  689. hr = GetWirelessEncryptionForAdapter(cfe, IDS_DETAILS_802_11_ENCRYPTION_TYPE, szString);
  690. if (SUCCEEDED(hr))
  691. {
  692. if (bSomeDetail)
  693. {
  694. szTmpString += c_crlf;
  695. }
  696. szTmpString += szString;
  697. bSomeDetail = TRUE;
  698. }
  699. hr = GetWirelessSignalStrengthForAdapter(cfe, IDS_DETAILS_802_11_SIGNAL_STRENGTH, szString);
  700. if (SUCCEEDED(hr))
  701. {
  702. if (bSomeDetail)
  703. {
  704. szTmpString += c_crlf;
  705. }
  706. szTmpString += szString;
  707. bSomeDetail = TRUE;
  708. }
  709. if (bSomeDetail)
  710. {
  711. hr = S_OK;
  712. pszString = szTmpString.c_str();
  713. }
  714. }
  715. else
  716. {
  717. hr = E_FAIL;
  718. }
  719. }
  720. break;
  721. default:
  722. AssertSz(FALSE, "CConnectionFolder::GetDetailsOf - Invalid ICOL from the Shell");
  723. pszString = NULL;
  724. hr = E_FAIL;
  725. break;
  726. }
  727. }
  728. else
  729. {
  730. // If we're the wizard, and they want the name, then load
  731. // the friendly rendition for webview's sake
  732. //
  733. switch(iColumn)
  734. {
  735. case ICOL_NAME: // 0
  736. pszString = SzLoadIds(IDS_CONFOLD_WIZARD_DISPLAY_NAME);
  737. break;
  738. case ICOL_TYPE: // 1
  739. pszString = SzLoadIds(IDS_CONFOLD_WIZARD_TYPE);
  740. break;
  741. }
  742. }
  743. }
  744. }
  745. if (SUCCEEDED(hr))
  746. {
  747. // Copy the string to the return buffer type. If there was no string loaded,
  748. // then just copy a null string a return it. This will happen for each
  749. // wizard item, since we provide no text.
  750. //
  751. hr = HrCopyToSTRRET(&(lpDetails->str), pszString ? pszString : L" \0");
  752. }
  753. }
  754. return hr;
  755. }
  756. //+---------------------------------------------------------------------------
  757. //
  758. // Member: CConnectionFolderDetails::EnumSearches
  759. //
  760. // Purpose: Requests a pointer to an interface that allows a client to
  761. // enumerate the available search objects.
  762. //
  763. // Arguments:
  764. // IEnumExtraSearch [in] Address of a pointer to an enumerator object's
  765. // IEnumExtraSearch interface.
  766. //
  767. // Returns:
  768. //
  769. // Author: deonb 17 May 2000
  770. //
  771. // Notes:
  772. //
  773. STDMETHODIMP CConnectionFolder::EnumSearches (
  774. IEnumExtraSearch **ppEnum)
  775. {
  776. TraceFileFunc(ttidShellFolder);
  777. return E_NOTIMPL;
  778. }
  779. //+---------------------------------------------------------------------------
  780. //
  781. // Member: CConnectionFolderDetails::GetDefaultColumn
  782. //
  783. // Purpose: Gets the default sorting and display columns.
  784. //
  785. // Arguments:
  786. // dwReserved [in] Reserved. Set to zero.
  787. // pSort [out] Pointer to a value that receives the index of the default sorted column.
  788. // pDisplay [out] Pointer to a value that receives the index of the default display column.
  789. //
  790. // Returns:
  791. //
  792. // Author: deonb 17 May 2000
  793. //
  794. // Notes:
  795. //
  796. STDMETHODIMP CConnectionFolder::GetDefaultColumn (
  797. DWORD dwReserved,
  798. ULONG *pSort,
  799. ULONG *pDisplay )
  800. {
  801. TraceFileFunc(ttidShellFolder);
  802. return E_NOTIMPL;
  803. }
  804. //+---------------------------------------------------------------------------
  805. //
  806. // Member: CConnectionFolderDetails::GetDefaultColumnState
  807. //
  808. // Purpose: Retrieves the default state for a specified column.
  809. //
  810. // Arguments:
  811. // iColumn [in] Integer that specifies the column number.
  812. // pcsFlags [out] Pointer to flags that indicate the default column state.
  813. //
  814. // Returns:
  815. //
  816. // Author: deonb 17 May 2000
  817. //
  818. // Notes:
  819. //
  820. STDMETHODIMP CConnectionFolder::GetDefaultColumnState (
  821. UINT iColumn,
  822. DWORD *pcsFlags )
  823. {
  824. TraceFileFunc(ttidShellFolder);
  825. HRESULT hr;
  826. if ( (static_cast<INT>(iColumn) >= ICOL_NAME) && (static_cast<INT>(iColumn) < ICOL_MAX) )
  827. {
  828. *pcsFlags = c_rgCols[iColumn].csFlags;
  829. hr = S_OK;
  830. }
  831. else
  832. {
  833. hr = E_FAIL;
  834. }
  835. return hr;
  836. }
  837. //+---------------------------------------------------------------------------
  838. //
  839. // Member: CConnectionFolderDetails::GetDefaultSearchGUID
  840. //
  841. // Purpose: Returns the globally unique identifier (GUID) of the default
  842. // search object for the folder.
  843. //
  844. // Arguments:
  845. // lpGUID [out] GUID of the default search object.
  846. //
  847. // Returns:
  848. //
  849. // Author: deonb 17 May 2000
  850. //
  851. // Notes:
  852. //
  853. STDMETHODIMP CConnectionFolder::GetDefaultSearchGUID (
  854. LPGUID lpGUID )
  855. {
  856. TraceFileFunc(ttidShellFolder);
  857. return E_NOTIMPL;
  858. }
  859. #define DEFINE_SCID(name, fmtid, pid) const SHCOLUMNID name = { fmtid, pid }
  860. //+---------------------------------------------------------------------------
  861. //
  862. // Member: CConnectionFolderDetails::GetDetailsEx
  863. //
  864. // Purpose: Retrieves detailed information, identified by a property set ID
  865. // (FMTID) and property ID (PID), on an item in a shell folder.
  866. //
  867. // Arguments:
  868. // pidl [in] PIDL of the item, relative to the parent folder. This method accepts
  869. // only single-level PIDLs. The structure must contain exactly one
  870. // SHITEMID structure followed by a terminating zero.
  871. // pscid [in] Pointer to an SHCOLUMNID structure that identifies the column.
  872. // pv [out] Pointer to a VARIANT with the requested information.
  873. // The value will be fully typed.
  874. // Returns:
  875. //
  876. // Author: deonb 17 May 2000
  877. //
  878. // Notes:
  879. //
  880. #define STR_FMTID_DUIWebViewProp TEXT("{4BF1583F-916B-4719-AC31-8896A4BD8D8B}")
  881. #define PSCID_DUIWebViewProp {0x4bf1583f, 0x916b, 0x4719, 0xac, 0x31, 0x88, 0x96, 0xa4, 0xbd, 0x8d, 0x8b}
  882. DEFINE_SCID(SCID_WebViewDisplayProperties, PSGUID_WEBVIEW, PID_DISPLAY_PROPERTIES);
  883. #ifdef __cplusplus
  884. #define IsEqualSCID(a, b) (((a).pid == (b).pid) && IsEqualIID((a).fmtid, (b).fmtid) )
  885. #else
  886. #define IsEqualSCID(a, b) (((a).pid == (b).pid) && IsEqualIID(&((a).fmtid),&((b).fmtid)))
  887. #endif
  888. const TCHAR szDUI_LAN_Props[] =
  889. TEXT("prop:")
  890. TEXT("Name;") // ICOL_NAME (0)
  891. STR_FMTID_DUIWebViewProp TEXT("1") // ICOL_TYPE (1)
  892. TEXT(";")
  893. STR_FMTID_DUIWebViewProp TEXT("2") // ICOL_STATUS (2)
  894. TEXT(";")
  895. STR_FMTID_DUIWebViewProp TEXT("3") // ICOL_DEVICE_NAME (3)
  896. TEXT(";")
  897. STR_FMTID_DUIWebViewProp TEXT("6") // ICOL_ADDRESS (6)
  898. TEXT(";")
  899. ;
  900. const TCHAR szDUI_WIRELESS_LAN_Props[] =
  901. TEXT("prop:")
  902. TEXT("Name;") // ICOL_NAME (0)
  903. STR_FMTID_DUIWebViewProp TEXT("2") // ICOL_STATUS (2)
  904. TEXT(";")
  905. STR_FMTID_DUIWebViewProp TEXT("6") // ICOL_ADDRESS (6)
  906. TEXT(";")
  907. STR_FMTID_DUIWebViewProp TEXT("9") // ICOL_WIRELESS_MODE (9)
  908. TEXT(";")
  909. ;
  910. const TCHAR szDUI_PHONEISDN_Props[] =
  911. TEXT("prop:")
  912. TEXT("Name;") // ICOL_NAME (0)
  913. STR_FMTID_DUIWebViewProp TEXT("1") // ICOL_TYPE (1)
  914. TEXT(";")
  915. STR_FMTID_DUIWebViewProp TEXT("2") // ICOL_STATUS (2)
  916. TEXT(";")
  917. STR_FMTID_DUIWebViewProp TEXT("3") // ICOL_DEVICE_NAME (3)
  918. TEXT(";")
  919. STR_FMTID_DUIWebViewProp TEXT("7") // ICOL_PHONENUMBER (7)
  920. TEXT(";")
  921. STR_FMTID_DUIWebViewProp TEXT("6") // ICOL_ADDRESS (6)
  922. TEXT(";")
  923. ;
  924. const TCHAR szDUI_RASOTHER_Props[] =
  925. TEXT("prop:")
  926. TEXT("Name;") // ICOL_NAME (0)
  927. STR_FMTID_DUIWebViewProp TEXT("1") // ICOL_TYPE (1)
  928. TEXT(";")
  929. STR_FMTID_DUIWebViewProp TEXT("2") // ICOL_STATUS (2)
  930. TEXT(";")
  931. STR_FMTID_DUIWebViewProp TEXT("3") // ICOL_DEVICE_NAME (3)
  932. TEXT(";")
  933. STR_FMTID_DUIWebViewProp TEXT("8") // ICOL_HOSTADDRESS (8)
  934. TEXT(";")
  935. STR_FMTID_DUIWebViewProp TEXT("6") // ICOL_ADDRESS (6)
  936. TEXT(";")
  937. ;
  938. STDMETHODIMP CConnectionFolder::GetDetailsEx (
  939. LPCITEMIDLIST pidl,
  940. const SHCOLUMNID *pscid,
  941. VARIANT *pv )
  942. {
  943. TraceFileFunc(ttidShellFolder);
  944. HRESULT hr = S_OK;
  945. if ( (!pidl) || (!pscid) || (!pv) )
  946. {
  947. return E_INVALIDARG;
  948. }
  949. VariantInit(pv);
  950. if (IsEqualSCID(*pscid, SCID_WebViewDisplayProperties))
  951. {
  952. VariantInit(pv);
  953. pv->vt = VT_BSTR;
  954. PCONFOLDPIDL pcfp;
  955. hr = pcfp.InitializeFromItemIDList(pidl);
  956. if (FAILED(hr))
  957. {
  958. return hr;
  959. }
  960. switch (pcfp->ncm)
  961. {
  962. case NCM_LAN:
  963. if ( pcfp->ncsm == NCSM_WIRELESS )
  964. {
  965. pv->bstrVal = SysAllocString(szDUI_WIRELESS_LAN_Props);
  966. }
  967. else
  968. {
  969. pv->bstrVal = SysAllocString(szDUI_LAN_Props);
  970. }
  971. break;
  972. case NCM_BRIDGE:
  973. pv->bstrVal = SysAllocString(szDUI_LAN_Props);
  974. break;
  975. case NCM_NONE:
  976. case NCM_DIRECT:
  977. case NCM_PPPOE:
  978. case NCM_SHAREDACCESSHOST_LAN:
  979. case NCM_SHAREDACCESSHOST_RAS:
  980. case NCM_TUNNEL:
  981. pv->bstrVal = SysAllocString(szDUI_RASOTHER_Props);
  982. break;
  983. case NCM_PHONE:
  984. case NCM_ISDN:
  985. pv->bstrVal = SysAllocString(szDUI_PHONEISDN_Props);
  986. break;
  987. default:
  988. AssertSz(NULL, "Unexpected NetCon Media Type");
  989. hr = E_FAIL;
  990. }
  991. }
  992. else if (IsEqualIID(pscid->fmtid, FMTID_DUIWebViewProp) && pscid->pid < ICOL_MAX)
  993. {
  994. // this is a webview property -- get the value from GetDetailsOf(...)
  995. SHELLDETAILS sd = {0};
  996. hr = GetDetailsOf(pidl, pscid->pid, &sd);
  997. if (SUCCEEDED(hr))
  998. {
  999. WCHAR szTemp[INFOTIPSIZE];
  1000. hr = StrRetToBufW(&sd.str, pidl, szTemp, INFOTIPSIZE);
  1001. if (SUCCEEDED(hr))
  1002. {
  1003. pv->vt = VT_BSTR;
  1004. pv->bstrVal = SysAllocString(szTemp);
  1005. }
  1006. }
  1007. }
  1008. else
  1009. if (IsEqualGUID(pscid->fmtid, GUID_NETSHELL_PROPS))
  1010. {
  1011. CComBSTR bstrDisplayString;
  1012. PCONFOLDPIDL pcfp;
  1013. hr = pcfp.InitializeFromItemIDList(pidl);
  1014. if FAILED(hr)
  1015. {
  1016. return hr;
  1017. }
  1018. CONFOLDENTRY cfe;
  1019. hr = pcfp.ConvertToConFoldEntry(cfe);
  1020. if (SUCCEEDED(hr))
  1021. {
  1022. Assert(!cfe.empty());
  1023. INT iStringRes;
  1024. if (!cfe.GetWizard())
  1025. {
  1026. switch (pscid->pid)
  1027. {
  1028. case ICOL_NAME:
  1029. WCHAR szDisplayName[2];
  1030. szDisplayName[0] = towupper(*cfe.GetName());
  1031. szDisplayName[1] = NULL;
  1032. bstrDisplayString = szDisplayName;
  1033. break;
  1034. case ICOL_DEVICE_NAME:
  1035. bstrDisplayString = cfe.GetDeviceName();
  1036. if (bstrDisplayString.Length() == 0) // e.g. Incoming Connections
  1037. {
  1038. bstrDisplayString = cfe.GetName();
  1039. }
  1040. break;
  1041. case ICOL_PHONEORHOSTADDRESS:
  1042. AssertSz(FALSE, "Can't group by this column - IDefCategoryProvider should have prevented this.");
  1043. bstrDisplayString = cfe.GetPhoneOrHostAddress();
  1044. break;
  1045. case ICOL_TYPE:
  1046. MapNCMToResourceId(pcfp->ncm, pcfp->dwCharacteristics, &iStringRes);
  1047. bstrDisplayString = SzLoadIds(iStringRes);
  1048. break;
  1049. case ICOL_NETCONMEDIATYPE:
  1050. pv->vt = VT_I4;
  1051. pv->lVal = pcfp->ncm;
  1052. return S_OK;
  1053. case ICOL_NETCONSUBMEDIATYPE:
  1054. pv->vt = VT_I4;
  1055. pv->lVal = pcfp->ncsm;
  1056. return S_OK;
  1057. case ICOL_NETCONSTATUS:
  1058. pv->vt = VT_I4;
  1059. pv->lVal = pcfp->ncs;
  1060. return S_OK;
  1061. case ICOL_NETCONCHARACTERISTICS:
  1062. pv->vt = VT_I4;
  1063. pv->lVal = pcfp->dwCharacteristics;
  1064. return S_OK;
  1065. case ICOL_STATUS:
  1066. WCHAR szStatus[CONFOLD_MAX_STATUS_LENGTH];
  1067. MapNCSToComplexStatus(pcfp->ncs, pcfp->ncm, pcfp->ncsm, pcfp->dwCharacteristics, szStatus, CONFOLD_MAX_STATUS_LENGTH, pcfp->guidId);
  1068. bstrDisplayString = szStatus;
  1069. break;
  1070. case ICOL_OWNER:
  1071. if (cfe.GetCharacteristics() & NCCF_ALL_USERS)
  1072. {
  1073. bstrDisplayString = SzLoadIds(IDS_CONFOLD_DETAILS_OWNER_SYSTEM);
  1074. }
  1075. else
  1076. {
  1077. bstrDisplayString = PszGetOwnerStringFromCharacteristics(pszGetUserName(), cfe.GetCharacteristics() );
  1078. }
  1079. break;
  1080. default:
  1081. hr = E_FAIL;
  1082. break;
  1083. }
  1084. }
  1085. else // if !(pccfe.GetWizard())
  1086. {
  1087. switch (pscid->pid)
  1088. {
  1089. case ICOL_NAME: // 0
  1090. WCHAR szDisplayName[2];
  1091. szDisplayName[0] = towupper(*cfe.GetName());
  1092. szDisplayName[1] = NULL;
  1093. bstrDisplayString = szDisplayName;
  1094. break;
  1095. case ICOL_TYPE: // 1
  1096. default:
  1097. bstrDisplayString = SzLoadIds(IDS_CONFOLD_WIZARD_TYPE);
  1098. break;
  1099. }
  1100. }
  1101. }
  1102. if (SUCCEEDED(hr))
  1103. {
  1104. if (bstrDisplayString.Length() == 0)
  1105. {
  1106. hr = E_FAIL;
  1107. }
  1108. else
  1109. {
  1110. pv->vt = VT_BSTR;
  1111. pv->bstrVal = bstrDisplayString.Detach();
  1112. }
  1113. }
  1114. }
  1115. else
  1116. {
  1117. hr = E_FAIL;
  1118. }
  1119. return hr;
  1120. }
  1121. //+---------------------------------------------------------------------------
  1122. //
  1123. // Member: CConnectionFolderDetails::MapNameToSCID
  1124. //
  1125. // Purpose: Converts a column name to the appropriate property set ID (FMTID)
  1126. // and property ID (PID).
  1127. //
  1128. // Arguments:
  1129. // iColumn [in] Zero-based index of the desired information field. It is
  1130. // identical to the column number of the information as it is
  1131. // displayed in a Microsoft� Windows� Explorer Details view.
  1132. // pscid [out] Pointer to an SHCOLUMNID structure containing the FMTID and PID.
  1133. // Returns:
  1134. //
  1135. // Author: deonb 17 May 2000
  1136. //
  1137. // Notes:
  1138. //
  1139. STDMETHODIMP CConnectionFolder::MapColumnToSCID (
  1140. UINT iColumn,
  1141. SHCOLUMNID *pscid )
  1142. {
  1143. TraceFileFunc(ttidShellFolder);
  1144. HRESULT hr = S_OK;
  1145. if (!pscid)
  1146. {
  1147. return E_INVALIDARG;
  1148. }
  1149. if ( (static_cast<INT>(iColumn) >= ICOL_NAME) && (static_cast<INT>(iColumn) < ICOL_MAX) )
  1150. {
  1151. pscid->fmtid = GUID_NETSHELL_PROPS;
  1152. pscid->pid = iColumn;
  1153. }
  1154. else
  1155. {
  1156. hr = E_INVALIDARG;
  1157. }
  1158. return hr;
  1159. }