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.

1805 lines
52 KiB

  1. // ****************************************************************************
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: C F P I D L . C P P
  7. //
  8. // Contents: Connections Folder structures and classes.
  9. //
  10. // Author: jeffspr 11 Nov 1997
  11. //
  12. // ****************************************************************************
  13. #include "pch.h"
  14. #pragma hdrstop
  15. #include "ncperms.h"
  16. #include "ncras.h"
  17. #include "initguid.h"
  18. #include "foldinc.h" // Standard shell\folder includes
  19. #include "ncnetcon.h"
  20. #include "ncmisc.h"
  21. extern CRITICAL_SECTION g_csPidl;
  22. // #define STRICTDEBUGGING
  23. BOOL fIsConnectedStatus(NETCON_STATUS ncs)
  24. {
  25. switch (ncs)
  26. {
  27. case NCS_CONNECTED:
  28. case NCS_AUTHENTICATING:
  29. case NCS_AUTHENTICATION_FAILED:
  30. case NCS_AUTHENTICATION_SUCCEEDED:
  31. case NCS_CREDENTIALS_REQUIRED:
  32. return TRUE;
  33. default:
  34. return FALSE;
  35. }
  36. }
  37. // ****************************************************************************
  38. //
  39. // Member: CConFoldEntry::CConFoldEntry
  40. //
  41. // Purpose: Constructor for CConFoldEntry
  42. //
  43. // Arguments:
  44. // (none)
  45. //
  46. // Returns:
  47. //
  48. // Author: jeffspr 11 Nov 1997
  49. // ****************************************************************************
  50. CConFoldEntry::CConFoldEntry()
  51. {
  52. m_bDirty = TRUE;
  53. TraceFileFunc(ttidConFoldEntry);
  54. // Need to clear out the pointers, otherwise clear() will AV
  55. m_pszName = NULL;
  56. m_pszDeviceName = NULL;
  57. m_pbPersistData = NULL;
  58. m_pszPhoneOrHostAddress = NULL;
  59. clear();
  60. }
  61. CConFoldEntry::CConFoldEntry(const CConFoldEntry& ConFoldEntry)
  62. {
  63. TraceFileFunc(ttidConFoldEntry);
  64. m_bDirty = TRUE;
  65. if (!ConFoldEntry.empty())
  66. {
  67. HRESULT hr = HrDupFolderEntry(ConFoldEntry);
  68. if (FAILED(hr))
  69. {
  70. clear();
  71. }
  72. }
  73. else
  74. {
  75. // Need to clear out the pointers, otherwise clear() will AV
  76. m_pszName = NULL;
  77. m_pszDeviceName = NULL;
  78. m_pbPersistData = NULL;
  79. m_pszPhoneOrHostAddress = NULL;
  80. clear();
  81. }
  82. }
  83. CConFoldEntry& CConFoldEntry::operator =(const CConFoldEntry& ConFoldEntry)
  84. {
  85. TraceFileFunc(ttidConFoldEntry);
  86. m_bDirty = TRUE;
  87. if (!ConFoldEntry.empty())
  88. {
  89. HRESULT hr = HrDupFolderEntry(ConFoldEntry);
  90. if (FAILED(hr))
  91. {
  92. clear();
  93. }
  94. }
  95. else
  96. {
  97. clear();
  98. }
  99. return *this;
  100. }
  101. // ****************************************************************************
  102. //
  103. // Member: CConFoldEntry::~CConFoldEntry
  104. //
  105. // Purpose: Destructor for CConFoldEntry
  106. //
  107. // Arguments:
  108. // (none)
  109. //
  110. // Returns:
  111. //
  112. // Author: jeffspr 11 Nov 1997
  113. // ****************************************************************************
  114. CConFoldEntry::~CConFoldEntry()
  115. {
  116. TraceFileFunc(ttidConFoldEntry);
  117. clear();
  118. }
  119. // ****************************************************************************
  120. //
  121. // Member: CConFoldEntry::SetDeviceName
  122. //
  123. // Purpose: Set the name of the device used by this connection
  124. //
  125. // Arguments:
  126. // pszDeviceName - New device name (NULL is valid)
  127. //
  128. // Returns:
  129. //
  130. // Author: scottbri 11 Nov 1999
  131. // ****************************************************************************
  132. HRESULT CConFoldEntry::SetDeviceName(LPCWSTR pszDeviceName)
  133. {
  134. HRESULT hr = S_OK;
  135. PWSTR pszOld = m_pszDeviceName;
  136. m_bDirty = TRUE;
  137. if (pszDeviceName)
  138. {
  139. // Only change the text is the text is actually different
  140. //
  141. if ((NULL == GetDeviceName()) ||
  142. wcscmp(pszDeviceName, GetDeviceName()))
  143. {
  144. hr = HrDupeShellString(pszDeviceName, &m_pszDeviceName);
  145. }
  146. else
  147. {
  148. // NOTE: In this one case, nothing change so there is
  149. // nothing to free so short circut the clean-up below
  150. //
  151. pszOld = NULL;
  152. hr = S_OK;
  153. }
  154. }
  155. else
  156. {
  157. hr = HrDupeShellString(L"", &m_pszDeviceName);
  158. }
  159. // Free the old string
  160. //
  161. if (SUCCEEDED(hr) && pszOld)
  162. {
  163. SHFree(pszOld);
  164. }
  165. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrSetDeviceName");
  166. return hr;
  167. }
  168. // ****************************************************************************
  169. //
  170. // Member: CConFoldEntry::SetPhoneOrHostAddress
  171. //
  172. // Purpose: Set the name of the device used by this connection
  173. //
  174. // Arguments:
  175. // pszDeviceName - New device name (NULL is valid)
  176. //
  177. // Returns:
  178. //
  179. // Author: scottbri 11 Nov 1999
  180. // ****************************************************************************
  181. HRESULT CConFoldEntry::SetPhoneOrHostAddress(LPCWSTR pszPhoneOrHostAddress)
  182. {
  183. HRESULT hr = S_OK;
  184. PWSTR pszOld = m_pszPhoneOrHostAddress;
  185. m_bDirty = TRUE;
  186. if (pszPhoneOrHostAddress)
  187. {
  188. // Only change the text is the text is actually different
  189. //
  190. if ((NULL == GetPhoneOrHostAddress()) ||
  191. wcscmp(pszPhoneOrHostAddress, GetPhoneOrHostAddress()))
  192. {
  193. hr = HrDupeShellString(pszPhoneOrHostAddress, &m_pszPhoneOrHostAddress);
  194. }
  195. else
  196. {
  197. // NOTE: In this one case, nothing change so there is
  198. // nothing to free so short circut the clean-up below
  199. //
  200. pszOld = NULL;
  201. hr = S_OK;
  202. }
  203. }
  204. else
  205. {
  206. hr = HrDupeShellString(L"", &m_pszPhoneOrHostAddress);
  207. }
  208. // Free the old string
  209. //
  210. if (SUCCEEDED(hr) && pszOld)
  211. {
  212. SHFree(pszOld);
  213. }
  214. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrSetDeviceName");
  215. return hr;
  216. }
  217. // ****************************************************************************
  218. //
  219. // Member: CConFoldEntry::SetName
  220. //
  221. // Purpose: Set the name of the connection
  222. //
  223. // Arguments:
  224. // pszName - New connection name (NULL is valid)
  225. //
  226. // Returns:
  227. //
  228. // Author: scottbri 11 Nov 1999
  229. // ****************************************************************************
  230. HRESULT CConFoldEntry::SetName(LPCWSTR pszName)
  231. {
  232. HRESULT hr = S_OK;
  233. PWSTR pszOld = m_pszName;
  234. m_bDirty = TRUE;
  235. if (pszName)
  236. {
  237. // Only change the text is the text is actually different
  238. //
  239. if ((NULL == GetName()) ||
  240. wcscmp(pszName, GetName()))
  241. {
  242. hr = HrDupeShellString(pszName, &m_pszName);
  243. }
  244. else
  245. {
  246. pszOld = NULL;
  247. hr = S_OK;
  248. }
  249. }
  250. else
  251. {
  252. PWSTR pszLoad = NULL;
  253. if (GetWizard() == WIZARD_MNC)
  254. {
  255. pszLoad = (PWSTR) SzLoadIds(IDS_CONFOLD_WIZARD_DISPLAY_NAME);
  256. }
  257. else if (GetWizard() == WIZARD_HNW)
  258. {
  259. pszLoad = (PWSTR) SzLoadIds(IDS_CONFOLD_HOMENET_WIZARD_DISPLAY_NAME);
  260. }
  261. //$$REVIEW: Change this to use c_szEmpty
  262. //
  263. hr = HrDupeShellString(pszLoad ? pszLoad : L"", &m_pszName);
  264. Assert(GetName());
  265. }
  266. // Free the old string
  267. //
  268. if (SUCCEEDED(hr) && pszOld)
  269. {
  270. SHFree(pszOld);
  271. }
  272. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrSetConnectionName");
  273. return hr;
  274. }
  275. // ****************************************************************************
  276. //
  277. // Member: CConFoldEntry::HrInitData
  278. //
  279. // Purpose: Initialize the CConFoldEntry data. Not all fields are
  280. // required at this time, though they will most likely be
  281. // required at some point during the life of the object.
  282. //
  283. // Arguments:
  284. // wizWizard [in] Wizard type?
  285. // ncm [in] Connection type
  286. // ncs [in] Connection status
  287. // pclsid [in] Pointer to CLSID of the connection
  288. // pguidId [in] Pointer to unique GUID for the connection
  289. // dwCharacteristics [in] Connection characteristics
  290. // pbPersistData [in] Persistant data for this connection
  291. // ulPersistSize [in] Size of the persist data blob
  292. // pszName [in] Name of the connection
  293. // pszDeviceName [in] Name of the connection's device
  294. //
  295. // Returns: S_OK or valid OLE return code.
  296. //
  297. // Author: jeffspr 11 Nov 1997
  298. // ****************************************************************************
  299. HRESULT CConFoldEntry::HrInitData(const WIZARD wizWizard,
  300. const NETCON_MEDIATYPE ncm,
  301. const NETCON_SUBMEDIATYPE ncsm,
  302. const NETCON_STATUS ncs,
  303. const CLSID * pclsid,
  304. LPCGUID pguidId,
  305. const DWORD dwCharacteristics,
  306. const BYTE * pbPersistData,
  307. const ULONG ulPersistSize,
  308. LPCWSTR pszName,
  309. LPCWSTR pszDeviceName,
  310. LPCWSTR pszPhoneOrHostAddress)
  311. {
  312. TraceFileFunc(ttidConFoldEntry);
  313. HRESULT hr = S_OK;
  314. // Initialize the internal data
  315. //
  316. m_bDirty = TRUE;
  317. m_wizWizard = wizWizard;
  318. m_ncm = ncm;
  319. m_ncs = ncs;
  320. m_dwCharacteristics = dwCharacteristics;;
  321. BOOL fOldEapolStatus = ((ncsm == NCSM_CM) && (ncm == NCM_LAN)) // NCSM_CM used to be NCM_AUTHENTICATING
  322. || (ncsm > NCSM_CM); // E.g. NCM_AUTHENTICATION_SUCCEEDED etc.
  323. if (!fOldEapolStatus)
  324. {
  325. m_ncsm = ncsm;
  326. }
  327. else
  328. {
  329. // ISSUE: This is for the migration of EAPOL state out off our PIDL
  330. // This should be taken out after the no-prior-upgrades RC1 build is released.
  331. if (NCM_LAN == ncm)
  332. {
  333. m_ncsm = NCSM_LAN; // If all else file, we'll pretend to be a normal LAN card.
  334. CIntelliName inName(NULL, NULL);
  335. NETCON_MEDIATYPE ncmTmp;
  336. NETCON_SUBMEDIATYPE ncsmTmp;
  337. // Try get the status from the OID or Bindings
  338. HRESULT hrT = inName.HrGetPseudoMediaTypes(*pguidId, &ncmTmp, &ncsmTmp);
  339. if (SUCCEEDED(hrT))
  340. {
  341. m_ncsm = ncsmTmp;
  342. }
  343. else
  344. {
  345. // Ok. That didn't work. Try the connections list next.
  346. if (g_ccl.IsInitialized())
  347. {
  348. ConnListEntry cle;
  349. hrT = g_ccl.HrFindConnectionByGuid(pguidId, cle);
  350. if (S_OK == hrT)
  351. {
  352. m_ncsm = cle.ccfe.GetNetConSubMediaType();
  353. }
  354. }
  355. }
  356. }
  357. else
  358. {
  359. m_ncsm = NCSM_NONE;
  360. }
  361. }
  362. if (pclsid)
  363. {
  364. m_clsid = *pclsid;
  365. }
  366. else
  367. {
  368. AssertSz(wizWizard != WIZARD_NOT_WIZARD, "If you're not a wizard, you must give me a CLSID for the class!");
  369. }
  370. if (pguidId)
  371. {
  372. m_guidId = *pguidId;
  373. }
  374. AssertSz(pguidId, "You must give me a GUID for the object!");
  375. // Copy the persist buffer
  376. //
  377. if (pbPersistData)
  378. {
  379. LPBYTE bufTemp = (BYTE *) SHAlloc(ulPersistSize);
  380. if (!bufTemp)
  381. {
  382. SetPersistData(NULL, 0);
  383. hr = E_OUTOFMEMORY;
  384. goto Exit;
  385. }
  386. CopyMemory(bufTemp, pbPersistData, ulPersistSize);
  387. SetPersistData(bufTemp, ulPersistSize);
  388. }
  389. else
  390. {
  391. AssertSz(wizWizard != WIZARD_NOT_WIZARD, "If you're not a wizard, you must give me a pbPersistData for the object!");
  392. SetPersistData(NULL, 0);
  393. }
  394. // Copy the device name
  395. //
  396. hr = SetDeviceName(pszDeviceName);
  397. if (SUCCEEDED(hr))
  398. {
  399. // Copy the name
  400. //
  401. hr = SetName(pszName);
  402. if (SUCCEEDED(hr))
  403. {
  404. hr = SetPhoneOrHostAddress(pszPhoneOrHostAddress);
  405. }
  406. }
  407. Exit:
  408. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrInitData");
  409. return hr;
  410. }
  411. // ****************************************************************************
  412. //
  413. // Member: CConFoldEntry::UpdateData
  414. //
  415. // Purpose: Modify the values in a CConFoldEntry
  416. //
  417. // Arguments:
  418. // DWORD dwChangeFlags
  419. // NETCON_MEDIATYPE MediaType
  420. // NETCON_STATUS Status
  421. // DWORD dwCharacteristics
  422. // PWSTR pszName
  423. // PWSTR pszDeviceName
  424. //
  425. // Returns: HRESULT
  426. //
  427. // Author: scottbri 10 Nov 1998
  428. // ****************************************************************************
  429. HRESULT CConFoldEntry::UpdateData( const DWORD dwChangeFlags,
  430. const NETCON_MEDIATYPE MediaType,
  431. const NETCON_SUBMEDIATYPE SubMediaType,
  432. const NETCON_STATUS Status,
  433. const DWORD dwCharacteristics,
  434. PCWSTR pszName,
  435. PCWSTR pszDeviceName,
  436. PCWSTR pszPhoneOrHostAddress)
  437. {
  438. TraceFileFunc(ttidConFoldEntry);
  439. HRESULT hr = S_OK;
  440. HRESULT hrTmp;
  441. m_bDirty = TRUE;
  442. if (dwChangeFlags & CCFE_CHANGE_MEDIATYPE)
  443. {
  444. SetNetConMediaType(MediaType);
  445. }
  446. if (dwChangeFlags & CCFE_CHANGE_SUBMEDIATYPE)
  447. {
  448. SetNetConSubMediaType(SubMediaType);
  449. }
  450. if (dwChangeFlags & CCFE_CHANGE_STATUS)
  451. {
  452. SetNetConStatus(Status);
  453. }
  454. if (dwChangeFlags & CCFE_CHANGE_CHARACTERISTICS)
  455. {
  456. SetCharacteristics(dwCharacteristics);
  457. }
  458. if (dwChangeFlags & CCFE_CHANGE_NAME)
  459. {
  460. hrTmp = SetName(pszName);
  461. if (FAILED(hrTmp))
  462. {
  463. hr = hrTmp;
  464. }
  465. }
  466. if (dwChangeFlags & CCFE_CHANGE_DEVICENAME)
  467. {
  468. hrTmp = SetDeviceName(pszDeviceName);
  469. if (FAILED(hrTmp))
  470. {
  471. hr = hrTmp;
  472. }
  473. }
  474. if (dwChangeFlags & CCFE_CHANGE_PHONEORHOSTADDRESS)
  475. {
  476. hrTmp = SetPhoneOrHostAddress(pszPhoneOrHostAddress);
  477. if (FAILED(hrTmp))
  478. {
  479. hr = hrTmp;
  480. }
  481. }
  482. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::UpdateData");
  483. return hr;
  484. }
  485. // ****************************************************************************
  486. //
  487. // Member: CConFoldEntry::HrDupFolderEntry
  488. //
  489. // Purpose: Duplicate a connection folder entry.
  490. //
  491. // Arguments:
  492. // pccfe The source folder entry to dup from
  493. //
  494. // Returns:
  495. //
  496. // Author: tongl 9/3/98
  497. // ****************************************************************************
  498. HRESULT CConFoldEntry::HrDupFolderEntry(const CConFoldEntry& ccfe)
  499. {
  500. TraceFileFunc(ttidConFoldEntry);
  501. m_bDirty = TRUE;
  502. Assert(!ccfe.empty());
  503. clear();
  504. return HrInitData( ccfe.GetWizard(),
  505. ccfe.GetNetConMediaType(),
  506. ccfe.GetNetConSubMediaType(),
  507. ccfe.GetNetConStatus(),
  508. &(ccfe.GetCLSID()),
  509. &(ccfe.GetGuidID()),
  510. ccfe.GetCharacteristics(),
  511. ccfe.GetPersistData(),
  512. ccfe.GetPersistSize(),
  513. ccfe.GetName(),
  514. ccfe.GetDeviceName(),
  515. ccfe.GetPhoneOrHostAddress());
  516. }
  517. // ****************************************************************************
  518. //
  519. // Member: CConFoldEntry::FShouldHaveTrayIconDisplayed
  520. //
  521. // Purpose: Return TRUE if this entry should have a tray icon displayed.
  522. //
  523. // Arguments:
  524. // (none)
  525. //
  526. // Returns: TRUE or FALSE.
  527. //
  528. // Author: shaunco 2 Nov 1998
  529. // ****************************************************************************
  530. BOOL CConFoldEntry::FShouldHaveTrayIconDisplayed() const
  531. {
  532. // If we're either MEDIA_DISCONNECTED (lan) or
  533. // we're connected and have the correct bits turned on
  534. // then we should display the icon
  535. //
  536. return ( !IsConnected() ||
  537. (fIsConnectedStatus(GetNetConStatus()) &&
  538. (GetCharacteristics() & NCCF_SHOW_ICON) &&
  539. !GetWizard() && FHasPermission(NCPERM_Statistics)));
  540. }
  541. // ****************************************************************************
  542. // Function:
  543. //
  544. // Purpose: Translate from a pidl to a CConFoldEntry class object
  545. //
  546. // Arguments:
  547. // pidl [in] PIDL from which to create
  548. // ppccfe [out] Resultant CConFoldEntry object pointer
  549. //
  550. // Returns:
  551. //
  552. // Author: jeffspr 11 Nov 1997
  553. // ****************************************************************************
  554. // ****************************************************************************
  555. //
  556. // Function: HrCreateConFoldPidlInternal
  557. //
  558. // Purpose: Utility function for creating new Connections Folder PIDLs.
  559. // This function is primarily called from HrCreateConFoldPidl,
  560. // but can also be called directly by those that have already
  561. // loaded the properties and persist data.
  562. //
  563. // Arguments:
  564. // pProps [in] From GetProperties
  565. // pbBuf [in] The persist buffer
  566. // ulBufSize [in] Size of the persist buffer
  567. // ppidl [out] Return pointer for the resultant pidl
  568. //
  569. // Returns:
  570. //
  571. // Author: jeffspr 27 Aug 1998
  572. // ****************************************************************************
  573. HRESULT HrCreateConFoldPidlInternal(IN const NETCON_PROPERTIES * pProps,
  574. IN const BYTE * pbBuf,
  575. IN ULONG ulBufSize,
  576. IN LPCWSTR szPhoneOrHostAddress,
  577. OUT PCONFOLDPIDL & pidl)
  578. {
  579. HRESULT hr = S_OK;
  580. CONFOLDENTRY ccfe;
  581. // Trace the useful info
  582. //
  583. TraceTag(ttidShellFolder, "Enum: %S, Ncm: %d, Ncs: %d, Char: 0x%08x "
  584. "(Show: %d, Del: %d, All: %d), Dev: %S",
  585. (pProps->pszwName) ? pProps->pszwName : L"null",
  586. pProps->MediaType, pProps->Status, pProps->dwCharacter,
  587. ((pProps->dwCharacter & NCCF_SHOW_ICON) > 0),
  588. ((pProps->dwCharacter & NCCF_ALLOW_REMOVAL) > 0),
  589. ((pProps->dwCharacter & NCCF_ALL_USERS) > 0),
  590. (pProps->pszwDeviceName) ? pProps->pszwDeviceName : L"null");
  591. // Init the CConFoldEntry from the data that we've retrieved.
  592. //
  593. hr = ccfe.HrInitData(WIZARD_NOT_WIZARD,
  594. pProps->MediaType,
  595. NCSM_NONE,
  596. pProps->Status,
  597. &pProps->clsidThisObject,
  598. &pProps->guidId,
  599. pProps->dwCharacter,
  600. pbBuf,
  601. ulBufSize,
  602. pProps->pszwName,
  603. pProps->pszwDeviceName,
  604. szPhoneOrHostAddress);
  605. if (FAILED(hr))
  606. {
  607. TraceHr(ttidShellFolder, FAL, hr, FALSE, "ccfe.HrInitData failed for "
  608. "non-wizard");
  609. goto Exit;
  610. }
  611. // Translate into the actual pidl
  612. //
  613. hr = ccfe.ConvertToPidl(pidl);
  614. if (FAILED(hr))
  615. {
  616. TraceHr(ttidShellFolder, FAL, hr, FALSE, "ConvertToPidl failed for non-wizard");
  617. }
  618. Exit:
  619. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateConFoldPidlInternal");
  620. return hr;
  621. }
  622. // ****************************************************************************
  623. //
  624. // Function: HrCreateConFoldPidl
  625. //
  626. // Purpose: Utility function for creating new Connections Folder PIDLs.
  627. //
  628. // Arguments:
  629. // wizWizard [in] Is this PIDL for a wizard?
  630. // pNetCon [in] INetConnection interface from the enumerator
  631. // pPersist [in] IPersist interface QI'd from the pNetCon
  632. // ppidl [out] Return pointer for the new pidl
  633. //
  634. // Returns: S_OK or valid OLE return code.
  635. //
  636. // Author: jeffspr 6 Oct 1997
  637. //
  638. // Notes: If the connection that you're adding is a real connection object
  639. // (not the wizard) and you already have loaded the persist data and
  640. // properties, you should call HrCreateConFoldPidlInternal directly
  641. // ****************************************************************************
  642. HRESULT HrCreateConFoldPidl(IN const WIZARD wizWizard,
  643. IN INetConnection * pNetCon,
  644. OUT PCONFOLDPIDL & ppidl)
  645. {
  646. HRESULT hr = S_OK;
  647. LPBYTE pbBuf = NULL;
  648. ULONG ulBufSize = 0;
  649. NETCON_PROPERTIES * pProps = NULL;
  650. CConFoldEntry ccfe;
  651. if (wizWizard == WIZARD_NOT_WIZARD)
  652. {
  653. Assert(pNetCon);
  654. hr = pNetCon->GetProperties (&pProps);
  655. if (FAILED(hr))
  656. {
  657. TraceHr(ttidShellFolder, FAL, hr, FALSE, "pNetCon->GetProperties failed in "
  658. "CConnectionFolderEnum::HrCreateConFoldPidl");
  659. goto Exit;
  660. }
  661. Assert (pProps);
  662. // Get the persist data from the connection
  663. //
  664. hr = HrGetConnectionPersistData(pNetCon, &pbBuf, &ulBufSize, NULL);
  665. if (FAILED(hr))
  666. {
  667. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrGetConnectionPersistData failed in "
  668. "CConnectionFolderEnum::HrCreateConFoldPidl");
  669. goto Exit;
  670. }
  671. WCHAR szPhoneOrHostAddress[MAX_PATH];
  672. wcscpy(szPhoneOrHostAddress, L" ");
  673. if ( (NCM_TUNNEL == pProps->MediaType) || (NCM_PHONE == pProps->MediaType) )
  674. {
  675. HRESULT hrTmp;
  676. RASCON_INFO RasConInfo;
  677. if (SUCCEEDED(hr))
  678. {
  679. hrTmp = HrRciGetRasConnectionInfo(pNetCon, &RasConInfo);
  680. if (SUCCEEDED(hrTmp))
  681. {
  682. GetPrivateProfileString(RasConInfo.pszwEntryName, L"PhoneNumber",
  683. L" ", szPhoneOrHostAddress, MAX_PATH,
  684. RasConInfo.pszwPbkFile);
  685. RciFree(&RasConInfo);
  686. }
  687. }
  688. }
  689. // Call the pre-read-data version of this function to actually pack the
  690. // ccfe and insert.
  691. //
  692. hr = HrCreateConFoldPidlInternal(pProps, pbBuf, ulBufSize, szPhoneOrHostAddress, ppidl);
  693. if (FAILED(hr))
  694. {
  695. goto Exit;
  696. }
  697. }
  698. else
  699. {
  700. GUID guidWiz;
  701. if (wizWizard == WIZARD_MNC)
  702. {
  703. guidWiz = GUID_MNC_WIZARD;
  704. }
  705. else
  706. {
  707. guidWiz = GUID_HNW_WIZARD;
  708. Assert(wizWizard == WIZARD_HNW);
  709. }
  710. // Pack the CConFoldEntry data from the retrieved info
  711. //
  712. hr = ccfe.HrInitData(wizWizard, NCM_NONE, NCSM_NONE, NCS_DISCONNECTED,
  713. NULL, &guidWiz, 0, NULL, 0, NULL, NULL, NULL);
  714. if (FAILED(hr))
  715. {
  716. TraceHr(ttidShellFolder, FAL, hr, FALSE, "ccfe.HrInitData failed for "
  717. "Wizard");
  718. goto Exit;
  719. }
  720. // Translate into an actual pidl
  721. //
  722. hr = ccfe.ConvertToPidl(ppidl);
  723. if (FAILED(hr))
  724. {
  725. TraceHr(ttidShellFolder, FAL, hr, FALSE, "ConvertToPidl failed for wizard");
  726. }
  727. }
  728. Exit:
  729. MemFree(pbBuf);
  730. FreeNetconProperties(pProps);
  731. TraceHr(ttidError, FAL, hr, FALSE, "HrCreateConFoldPidl");
  732. return hr;
  733. }
  734. // ****************************************************************************
  735. //
  736. // Function: HrCreateConFoldPidl
  737. //
  738. // Purpose: Utility function for creating new Connections Folder PIDLs.
  739. //
  740. // Arguments:
  741. // wizWizard [in] Is this PIDL for a wizard?
  742. // PropsEx [in] PropsEx structure
  743. // ppidl [out] Return pointer for the new pidl
  744. //
  745. // Returns: S_OK or valid OLE return code.
  746. //
  747. // Author: deonb 26 Mar 2001
  748. //
  749. // Notes:
  750. // ****************************************************************************
  751. HRESULT HrCreateConFoldPidl(IN const NETCON_PROPERTIES_EX& PropsEx,
  752. OUT PCONFOLDPIDL & ppidl)
  753. {
  754. HRESULT hr = S_OK;
  755. NETCON_PROPERTIES * pProps = NULL;
  756. CConFoldEntry ccfe;
  757. // Trace the useful info
  758. //
  759. TraceTag(ttidShellFolder, "Enum: %S, Ncm: %d, Ncs: %d, Char: 0x%08x "
  760. "(Show: %d, Del: %d, All: %d), Dev: %S",
  761. (PropsEx.bstrName) ? PropsEx.bstrName : L"null",
  762. PropsEx.ncMediaType,
  763. PropsEx.ncStatus,
  764. PropsEx.dwCharacter,
  765. ((PropsEx.dwCharacter & NCCF_SHOW_ICON) > 0),
  766. ((PropsEx.dwCharacter & NCCF_ALLOW_REMOVAL) > 0),
  767. ((PropsEx.dwCharacter & NCCF_ALL_USERS) > 0),
  768. (PropsEx.bstrDeviceName) ? PropsEx.bstrDeviceName : L"null");
  769. // Init the CConFoldEntry from the data that we've retrieved.
  770. //
  771. hr = ccfe.HrInitData(WIZARD_NOT_WIZARD,
  772. PropsEx.ncMediaType,
  773. PropsEx.ncSubMediaType,
  774. PropsEx.ncStatus,
  775. &PropsEx.clsidThisObject,
  776. &PropsEx.guidId,
  777. PropsEx.dwCharacter,
  778. reinterpret_cast<const BYTE*>(PropsEx.bstrPersistData),
  779. SysStringByteLen(PropsEx.bstrPersistData),
  780. PropsEx.bstrName,
  781. PropsEx.bstrDeviceName,
  782. PropsEx.bstrPhoneOrHostAddress);
  783. if (SUCCEEDED(hr))
  784. {
  785. // Translate into the actual pidl
  786. //
  787. hr = ccfe.ConvertToPidl(ppidl);
  788. }
  789. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrCreateConFoldPidl");
  790. return hr;
  791. }
  792. // ****************************************************************************
  793. //
  794. // Function: ConvertToPidlInCache
  795. //
  796. // Purpose: Determine whether a particular PIDL is in a format we support.
  797. // If so but it is not in the CONFOLDPIDL format, then find a match
  798. // in our cache and allocate a new pisl
  799. //
  800. // Arguments:
  801. // pidl [] PIDL to test
  802. // ppcfpRet PIDL converted to PCONFOLDPIDL, if required and it
  803. // matches an existing connection in the cache
  804. //
  805. // Returns: NONE
  806. //
  807. // Author: tongl, 4 April, 1999
  808. // ****************************************************************************
  809. // ****************************************************************************
  810. //
  811. // Function: HrNetConFromPidl
  812. //
  813. // Purpose: Translate from a packed PIDL to a INetConnection pointer.
  814. // Do this by converting to a ConFoldEntry and getting the
  815. // pointer from there
  816. //
  817. // Arguments:
  818. // pidl [in] Pidl that contains the connection persist data
  819. // ppNetCon [out] INetConnection * return
  820. //
  821. // Returns:
  822. //
  823. // Author: jeffspr 11 Nov 1997
  824. // ****************************************************************************
  825. HRESULT HrNetConFromPidl( const PCONFOLDPIDL & pidl,
  826. INetConnection ** ppNetCon)
  827. {
  828. HRESULT hr = S_OK;
  829. CONFOLDENTRY pccfe;
  830. Assert(ppNetCon);
  831. hr = pidl.ConvertToConFoldEntry(pccfe);
  832. if (SUCCEEDED(hr))
  833. {
  834. Assert(!pccfe.empty());
  835. hr = pccfe.HrGetNetCon(IID_INetConnection,
  836. reinterpret_cast<VOID**>(ppNetCon));
  837. }
  838. // Free the CConFoldEntry class, if successfully created
  839. //
  840. TraceHr(ttidError, FAL, hr, FALSE, "HrNetConFromPidl");
  841. return hr;
  842. }
  843. // ****************************************************************************
  844. //
  845. // Member: CConFoldEntry::HrGetNetCon
  846. //
  847. // Purpose: Get the INetConnection pointer from the persisted data
  848. //
  849. // Arguments:
  850. // ppNetCon [] Return pointer for the INetConnection
  851. //
  852. // Returns:
  853. //
  854. // Author: jeffspr 11 Nov 1997
  855. // ****************************************************************************
  856. HRESULT CConFoldEntry::HrGetNetCon( IN REFIID riid,
  857. IN VOID** ppv) const
  858. {
  859. HRESULT hr = HrGetConnectionFromPersistData( GetCLSID(),
  860. GetPersistData(),
  861. GetPersistSize(),
  862. riid,
  863. ppv);
  864. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::HrGetNetCon");
  865. return hr;
  866. }
  867. // ****************************************************************************
  868. HRESULT PConfoldPidlVecFromItemIdListArray(LPCITEMIDLIST * apidl, DWORD dwPidlCount, PCONFOLDPIDLVEC& vecConfoldPidl)
  869. {
  870. HRESULT hr = S_OK;
  871. if (NULL == apidl)
  872. {
  873. return S_FALSE;
  874. }
  875. LPCITEMIDLIST *tmpIdList = apidl;
  876. for (DWORD i = 0; i < dwPidlCount; i++)
  877. {
  878. PCONFOLDPIDL newPidl;
  879. hr = newPidl.InitializeFromItemIDList(*tmpIdList);
  880. if (SUCCEEDED(hr))
  881. {
  882. vecConfoldPidl.push_back(newPidl);
  883. }
  884. else
  885. {
  886. break;
  887. }
  888. tmpIdList++;
  889. }
  890. return hr;
  891. }
  892. #ifdef DBG_VALIDATE_PIDLS
  893. inline BOOL IsValidPIDL(LPCITEMIDLIST pidl)
  894. {
  895. CExceptionSafeLock esLock(&g_csPidl);
  896. if (NULL == pidl)
  897. {
  898. return TRUE;
  899. }
  900. if (IsBadReadPtr(pidl, sizeof(USHORT)))
  901. {
  902. AssertSz(FALSE, "invalid read pointer");
  903. return FALSE;
  904. }
  905. else
  906. {
  907. if (IsBadReadPtr(pidl, pidl->mkid.cb) )
  908. {
  909. AssertSz(FALSE, "invalid read buffer");
  910. return FALSE;
  911. }
  912. else
  913. {
  914. if (0 == _ILNext(pidl)->mkid.cb || IsValidPIDL(_ILNext(pidl)) )
  915. {
  916. return TRUE;
  917. }
  918. else
  919. {
  920. // Don't need to assert since called IsValidPidl would have asserted already
  921. return FALSE;
  922. }
  923. }
  924. }
  925. return FALSE;
  926. }
  927. #endif
  928. BOOL ConFoldPidl_v1::IsPidlOfThisType() const
  929. {
  930. if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_V1 )
  931. {
  932. #if defined( DBG ) && defined ( STRICTDEBUGGING )
  933. DWORD dwDataOffset = bData - reinterpret_cast<const BYTE *>(this); // Get bData offset;
  934. DWORD dwPidlSize;
  935. dwPidlSize = dwDataOffset;
  936. dwPidlSize += ulPersistBufSize;
  937. dwPidlSize += ulStrNameSize;
  938. dwPidlSize += ulStrDeviceNameSize;
  939. dwPidlSize += sizeof(USHORT); // Terminating
  940. AssertSz(dwPidlSize <= iCB, "Self-inconsistend PIDL"); // Sometimes V1 PIDLs are shorter - hence not == a check.
  941. AssertSz(ulPersistBufPos + ulPersistBufSize < iCB, "Self-inconsistend PIDL");
  942. AssertSz(ulStrDeviceNamePos + ulStrDeviceNameSize < iCB, "Self-inconsistend PIDL");
  943. AssertSz(ulStrNamePos + ulStrNameSize < iCB, "Self-inconsistend PIDL");
  944. AssertSz(ulStrNamePos == 0, "Name doesn't start at 0");
  945. AssertSz(ulStrDeviceNamePos == ulStrNameSize, "Device name misaligned");
  946. AssertSz(ulPersistBufPos == ulStrDeviceNamePos + ulStrDeviceNameSize, "Persisted buffer misaligned");
  947. AssertSz(dwDataOffset + ulPersistBufPos + ulPersistBufSize <= iCB, "Persisted buffer larger than PIDL");
  948. #endif
  949. return TRUE;
  950. }
  951. else
  952. {
  953. return FALSE;
  954. }
  955. }
  956. BOOL ConFoldPidl_v2::IsPidlOfThisType() const
  957. {
  958. if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_V2 )
  959. {
  960. #if defined( DBG ) && defined ( STRICTDEBUGGING )
  961. DWORD dwDataOffset = bData - reinterpret_cast<const BYTE *>(this); // Get bData offset;
  962. DWORD dwPidlSize;
  963. dwPidlSize = dwDataOffset;
  964. dwPidlSize += ulPersistBufSize;
  965. dwPidlSize += ulStrNameSize;
  966. dwPidlSize += ulStrDeviceNameSize;
  967. dwPidlSize += ulStrPhoneOrHostAddressSize;
  968. dwPidlSize += sizeof(USHORT); // Terminating 0
  969. AssertSz(dwPidlSize <= iCB, "Self-inconsistend PIDL"); // Sometimes V1 PIDLs are shorter - hence not == a check.
  970. AssertSz(ulPersistBufPos + ulPersistBufSize < iCB, "Self-inconsistend PIDL");
  971. AssertSz(ulStrDeviceNamePos + ulStrDeviceNameSize < iCB, "Self-inconsistend PIDL");
  972. AssertSz(ulStrNamePos + ulStrNameSize < iCB, "Self-inconsistend PIDL");
  973. AssertSz(ulStrPhoneOrHostAddressPos + ulStrPhoneOrHostAddressSize < iCB, "Self-inconsistend PIDL");
  974. AssertSz(ulStrNamePos == 0, "Name doesn't start at 0");
  975. AssertSz(ulStrDeviceNamePos == ulStrNameSize, "Device name misaligned");
  976. AssertSz(ulPersistBufPos == ulStrDeviceNamePos + ulStrDeviceNameSize, "Persisted buffer misaligned");
  977. AssertSz(ulStrPhoneOrHostAddressPos == ulPersistBufPos + ulPersistBufSize, "Phone/Host address misaligned");
  978. AssertSz(dwDataOffset + ulPersistBufPos + ulPersistBufSize <= iCB, "Buffer larger than PIDL");
  979. #endif
  980. return TRUE;
  981. }
  982. else
  983. {
  984. return FALSE;
  985. }
  986. }
  987. BOOL ConFoldPidlFolder::IsPidlOfThisType() const
  988. {
  989. // We can't tell if it's a PIDL_TYPE_FOLDER - this is shell internal
  990. if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_UNKNOWN )
  991. {
  992. #ifdef DBG
  993. if ( (dwLength != 0x14) || (dwId != 0x1f) )
  994. {
  995. return FALSE;
  996. }
  997. #endif
  998. return TRUE;
  999. }
  1000. else
  1001. {
  1002. return FALSE;
  1003. }
  1004. }
  1005. BOOL ConFoldPidl98::IsPidlOfThisType(BOOL * pfIsWizard) const
  1006. {
  1007. if ( GetPidlType(reinterpret_cast<LPCITEMIDLIST>(this)) == PIDL_TYPE_98 )
  1008. {
  1009. return TRUE;
  1010. }
  1011. else
  1012. {
  1013. return FALSE;
  1014. }
  1015. }
  1016. const DWORD CConFoldEntry::GetCharacteristics() const
  1017. {
  1018. return m_dwCharacteristics;
  1019. }
  1020. HRESULT CConFoldEntry::SetCharacteristics(const DWORD dwCharacteristics)
  1021. {
  1022. m_bDirty = TRUE;
  1023. m_dwCharacteristics = dwCharacteristics;
  1024. return S_OK;
  1025. }
  1026. const GUID CConFoldEntry::GetGuidID() const
  1027. {
  1028. return m_guidId;
  1029. }
  1030. HRESULT CConFoldEntry::SetGuidID(const GUID guidId)
  1031. {
  1032. m_bDirty = TRUE;
  1033. m_guidId = guidId;
  1034. return S_OK;
  1035. }
  1036. const CLSID CConFoldEntry::GetCLSID() const
  1037. {
  1038. return m_clsid;
  1039. }
  1040. HRESULT CConFoldEntry::SetCLSID(const CLSID clsid)
  1041. {
  1042. m_bDirty = TRUE;
  1043. m_clsid = clsid;
  1044. return S_OK;
  1045. }
  1046. PCWSTR CConFoldEntry::GetName() const
  1047. {
  1048. return m_pszName;
  1049. }
  1050. HRESULT CConFoldEntry::SetPName(IN TAKEOWNERSHIP SHALLOCATED PWSTR pszName)
  1051. {
  1052. m_bDirty = TRUE;
  1053. m_pszName = pszName;
  1054. return S_OK;
  1055. }
  1056. PCWSTR CConFoldEntry::GetDeviceName() const
  1057. {
  1058. return m_pszDeviceName;
  1059. }
  1060. HRESULT CConFoldEntry::SetPDeviceName(IN TAKEOWNERSHIP SHALLOCATED PWSTR pszDeviceName)
  1061. {
  1062. m_bDirty = TRUE;
  1063. m_pszDeviceName = pszDeviceName;
  1064. return S_OK;
  1065. }
  1066. PCWSTR CConFoldEntry::GetPhoneOrHostAddress() const
  1067. {
  1068. return m_pszPhoneOrHostAddress;
  1069. }
  1070. HRESULT CConFoldEntry::SetPPhoneOrHostAddress(IN TAKEOWNERSHIP SHALLOCATED PWSTR pszPhoneOrHostAddress)
  1071. {
  1072. m_bDirty = TRUE;
  1073. m_pszPhoneOrHostAddress = pszPhoneOrHostAddress;
  1074. return S_OK;
  1075. }
  1076. const NETCON_STATUS CConFoldEntry::GetNetConStatus() const
  1077. {
  1078. return m_ncs;
  1079. }
  1080. const BOOL CConFoldEntry::IsConnected() const
  1081. {
  1082. return (m_ncs != NCS_MEDIA_DISCONNECTED) && (m_ncs != NCS_INVALID_ADDRESS);
  1083. }
  1084. HRESULT CConFoldEntry::SetNetConStatus(const NETCON_STATUS ncs)
  1085. {
  1086. m_bDirty = TRUE;
  1087. m_ncs = ncs;
  1088. return S_OK;
  1089. }
  1090. const NETCON_MEDIATYPE CConFoldEntry::GetNetConMediaType() const
  1091. {
  1092. return m_ncm;
  1093. }
  1094. HRESULT CConFoldEntry::SetNetConMediaType(const NETCON_MEDIATYPE ncm)
  1095. {
  1096. m_bDirty = TRUE;
  1097. m_ncm = ncm;
  1098. return S_OK;
  1099. }
  1100. const NETCON_SUBMEDIATYPE CConFoldEntry::GetNetConSubMediaType() const
  1101. {
  1102. return m_ncsm;
  1103. }
  1104. HRESULT CConFoldEntry::SetNetConSubMediaType(const NETCON_SUBMEDIATYPE ncsm)
  1105. {
  1106. m_bDirty = TRUE;
  1107. m_ncsm = ncsm;
  1108. return S_OK;
  1109. }
  1110. const WIZARD CConFoldEntry::GetWizard() const
  1111. {
  1112. return m_wizWizard;
  1113. }
  1114. HRESULT CConFoldEntry::SetWizard(const WIZARD wizWizard)
  1115. {
  1116. m_bDirty = TRUE;
  1117. m_wizWizard = wizWizard;
  1118. return S_OK;
  1119. }
  1120. const BYTE * CConFoldEntry::GetPersistData() const
  1121. {
  1122. return m_pbPersistData;
  1123. }
  1124. const ULONG CConFoldEntry::GetPersistSize() const
  1125. {
  1126. return m_ulPersistSize;
  1127. }
  1128. HRESULT CConFoldEntry::SetPersistData(BYTE * pbPersistData, const ULONG ulPersistSize)
  1129. {
  1130. m_bDirty = TRUE;
  1131. m_pbPersistData = pbPersistData;
  1132. m_ulPersistSize = ulPersistSize;
  1133. return S_OK;
  1134. }
  1135. BOOL CConFoldEntry::empty() const
  1136. {
  1137. if (GetWizard())
  1138. {
  1139. return FALSE;
  1140. }
  1141. else
  1142. {
  1143. if (IsEqualGUID(GetCLSID(), GUID_NULL) )
  1144. {
  1145. return TRUE;
  1146. }
  1147. else
  1148. {
  1149. return FALSE;
  1150. }
  1151. }
  1152. }
  1153. void CConFoldEntry::clear()
  1154. {
  1155. TraceFileFunc(ttidConFoldEntry);
  1156. m_bDirty = TRUE;
  1157. if (GetName())
  1158. {
  1159. SHFree(m_pszName);
  1160. m_pszName = NULL;
  1161. }
  1162. if (GetDeviceName())
  1163. {
  1164. SHFree(m_pszDeviceName);
  1165. m_pszDeviceName = NULL;
  1166. }
  1167. if (GetPhoneOrHostAddress())
  1168. {
  1169. SHFree(m_pszPhoneOrHostAddress);
  1170. m_pszPhoneOrHostAddress = NULL;
  1171. }
  1172. if (GetPersistData())
  1173. {
  1174. SHFree(m_pbPersistData);
  1175. m_pbPersistData = NULL;
  1176. m_ulPersistSize = 0;
  1177. }
  1178. m_wizWizard = WIZARD_NOT_WIZARD;
  1179. m_ncm = NCM_NONE;
  1180. m_ncsm= NCSM_NONE;
  1181. m_ncs = NCS_DISCONNECTED;
  1182. m_dwCharacteristics = 0;
  1183. m_clsid = GUID_NULL;
  1184. m_guidId = GUID_NULL;
  1185. }
  1186. LPITEMIDLIST CConFoldEntry::TearOffItemIdList() const
  1187. {
  1188. PCONFOLDPIDL pidl;
  1189. m_bDirty = TRUE;
  1190. ConvertToPidl(pidl);
  1191. return pidl.TearOffItemIdList();
  1192. }
  1193. HRESULT CConFoldEntry::InitializeFromItemIdList(LPCITEMIDLIST lpItemIdList)
  1194. {
  1195. PCONFOLDPIDL pidl;
  1196. HRESULT hr = S_OK;
  1197. m_bDirty = TRUE;
  1198. hr = pidl.InitializeFromItemIDList(lpItemIdList);
  1199. if (FAILED(hr))
  1200. {
  1201. return hr;
  1202. }
  1203. hr = pidl.ConvertToConFoldEntry(*this);
  1204. return hr;
  1205. }
  1206. HRESULT CConFoldEntry::ConvertToPidl( OUT CPConFoldPidl<ConFoldPidl_v1>& pidl) const
  1207. {
  1208. TraceFileFunc(ttidConFoldEntry);
  1209. HRESULT hr = S_OK;
  1210. DWORD dwNameSize = 0;
  1211. DWORD dwDeviceNameSize = 0;
  1212. DWORD dwPidlSize = sizeof(ConFoldPidl_v1); // Initialize the PIDL byte count with the base size
  1213. Assert(!empty());
  1214. Assert(GetName());
  1215. Assert(GetDeviceName());
  1216. NETCFG_TRY
  1217. if (m_bDirty)
  1218. {
  1219. // Get the size of the name, and tack on a trailing NULL (since we now
  1220. // have something else in the buffer behind it.
  1221. //
  1222. dwNameSize = lstrlenW(GetName()) + 1;
  1223. dwDeviceNameSize = lstrlenW(GetDeviceName()) + 1;
  1224. // Add the size of the string to the PIDL struct size. We don't need to include
  1225. // an extra byte for the string's terminating NULL because we've already
  1226. // included a WCHAR[1] in the struct.
  1227. //
  1228. dwPidlSize += ((dwNameSize) * sizeof(WCHAR));
  1229. dwPidlSize += ((dwDeviceNameSize) * sizeof(WCHAR));
  1230. // Tack of the length of the persist buffer
  1231. //
  1232. dwPidlSize += GetPersistSize();
  1233. // Allocate the PIDL.
  1234. //
  1235. hr = pidl.ILCreate(dwPidlSize + sizeof(USHORT)); // Terminating 0 for the PIDL
  1236. if (SUCCEEDED(hr))
  1237. {
  1238. PWSTR pszName = NULL;
  1239. PWSTR pszDeviceName = NULL;
  1240. PWSTR pszPhoneOrHostAddress = NULL;
  1241. // Fill in the pidl info.
  1242. //
  1243. pidl->wizWizard = GetWizard();
  1244. pidl->iCB = dwPidlSize;
  1245. // pidl->dwVersion = CONNECTIONS_FOLDER_IDL_VERSION_V1;
  1246. pidl->ncm = GetNetConMediaType();
  1247. pidl->ncs = GetNetConStatus();
  1248. pidl->uLeadId = CONFOLDPIDL_LEADID;
  1249. pidl->uTrailId = CONFOLDPIDL_TRAILID;
  1250. pidl->clsid = GetCLSID();
  1251. pidl->guidId = GetGuidID();
  1252. pidl->dwCharacteristics = GetCharacteristics();
  1253. // Fill in the name
  1254. //
  1255. pidl->ulStrNamePos = 0; // offset into the PIDL's pbBuf
  1256. pidl->ulStrNameSize = dwNameSize * sizeof(WCHAR); // in bytes
  1257. pszName = pidl->PszGetNamePointer();
  1258. lstrcpyW(pszName, GetName());
  1259. pszName[dwNameSize] = 0;
  1260. // Fill in the device name, and set the offset info
  1261. //
  1262. pidl->ulStrDeviceNamePos = pidl->ulStrNamePos + pidl->ulStrNameSize;
  1263. pidl->ulStrDeviceNameSize = dwDeviceNameSize * sizeof(WCHAR); // in bytes
  1264. pszDeviceName = pidl->PszGetDeviceNamePointer();
  1265. lstrcpyW(pszDeviceName, GetDeviceName());
  1266. pszDeviceName[dwDeviceNameSize] = 0;
  1267. // Set the offset into the PIDL's pbBuf
  1268. //
  1269. pidl->ulPersistBufPos = pidl->ulStrDeviceNamePos + pidl->ulStrDeviceNameSize;
  1270. // Fill in the persist buffer, if present (it won't be on a wizard)
  1271. //
  1272. if (GetPersistData())
  1273. {
  1274. pidl->ulPersistBufSize = GetPersistSize();
  1275. CopyMemory(pidl->bData + pidl->ulPersistBufPos, GetPersistData(), GetPersistSize());
  1276. }
  1277. else
  1278. {
  1279. // Since we're the wizard, there shouldn't be a buffer, so the size
  1280. // should always be passed in as 0.
  1281. //
  1282. Assert(GetPersistSize() == 0);
  1283. pidl->ulPersistBufSize = 0;
  1284. }
  1285. // Don't forget to terminate the list!
  1286. //
  1287. LPITEMIDLIST pidlTerminate;
  1288. pidlTerminate = ILNext( pidl.GetItemIdList() );
  1289. pidlTerminate->mkid.cb = 0;
  1290. }
  1291. else
  1292. {
  1293. AssertSz(FALSE, "CConFoldEntry::ConvertToPidl is hosed");
  1294. hr = E_OUTOFMEMORY;
  1295. }
  1296. #ifdef DBG_VALIDATE_PIDLS
  1297. Assert(IsValidPIDL( pidl.GetItemIdList() ));
  1298. #endif
  1299. Assert( pidl->IsPidlOfThisType() ) ;
  1300. if (SUCCEEDED(hr))
  1301. {
  1302. m_bDirty = FALSE;
  1303. m_CachedV1Pidl = pidl;
  1304. }
  1305. }
  1306. else
  1307. {
  1308. TraceTag(ttidShellFolder, "Using internally cached PIDL");
  1309. pidl = m_CachedV1Pidl;
  1310. }
  1311. NETCFG_CATCH(hr)
  1312. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::ConvertToPidl");
  1313. return hr;
  1314. }
  1315. HRESULT CConFoldEntry::ConvertToPidl( OUT CPConFoldPidl<ConFoldPidl_v2>& pidl) const
  1316. {
  1317. TraceFileFunc(ttidConFoldEntry);
  1318. HRESULT hr = S_OK;
  1319. DWORD dwNameSize = 0;
  1320. DWORD dwDeviceNameSize = 0;
  1321. DWORD dwPhoneOrHostAddressSize = 0;
  1322. DWORD dwPidlSize = sizeof(ConFoldPidl_v2); // Initialize the PIDL byte count with the base size
  1323. Assert(!empty());
  1324. Assert(GetName());
  1325. Assert(GetDeviceName());
  1326. Assert(GetPhoneOrHostAddress());
  1327. NETCFG_TRY
  1328. if (m_bDirty)
  1329. {
  1330. // Get the size of the name, and tack on a trailing NULL (since we now
  1331. // have something else in the buffer behind it.
  1332. //
  1333. dwNameSize = lstrlenW(GetName()) + 1;
  1334. dwDeviceNameSize = lstrlenW(GetDeviceName()) + 1;
  1335. dwPhoneOrHostAddressSize = lstrlenW(GetPhoneOrHostAddress()) + 1;
  1336. // Add the size of the string to the PIDL struct size. We don't need to include
  1337. // an extra byte for the string's terminating NULL because we've already
  1338. // included a WCHAR[1] in the struct.
  1339. //
  1340. dwPidlSize += ((dwNameSize) * sizeof(WCHAR));
  1341. dwPidlSize += ((dwDeviceNameSize) * sizeof(WCHAR));
  1342. dwPidlSize += ((dwPhoneOrHostAddressSize) * sizeof(WCHAR));
  1343. // Tack of the length of the persist buffer
  1344. //
  1345. dwPidlSize += GetPersistSize();
  1346. // Allocate the PIDL.
  1347. //
  1348. hr = pidl.ILCreate(dwPidlSize + sizeof(USHORT)); // Terminating 0 for the PIDL
  1349. if (SUCCEEDED(hr))
  1350. {
  1351. PWSTR pszName = NULL;
  1352. PWSTR pszDeviceName = NULL;
  1353. PWSTR pszPhoneOrHostAddress = NULL;
  1354. // Fill in the pidl info.
  1355. //
  1356. pidl->wizWizard = GetWizard();
  1357. pidl->iCB = dwPidlSize;
  1358. // pidl->dwVersion = CONNECTIONS_FOLDER_IDL_VERSION_V1;
  1359. pidl->ncm = GetNetConMediaType();
  1360. pidl->ncs = GetNetConStatus();
  1361. pidl->ncsm = GetNetConSubMediaType();
  1362. pidl->uLeadId = CONFOLDPIDL_LEADID;
  1363. pidl->uTrailId = CONFOLDPIDL_TRAILID;
  1364. pidl->clsid = GetCLSID();
  1365. pidl->guidId = GetGuidID();
  1366. pidl->dwCharacteristics = GetCharacteristics();
  1367. // Fill in the name
  1368. //
  1369. pidl->ulStrNamePos = 0; // offset into the PIDL's pbBuf
  1370. pidl->ulStrNameSize = dwNameSize * sizeof(WCHAR); // in bytes
  1371. pszName = pidl->PszGetNamePointer();
  1372. lstrcpyW(pszName, GetName());
  1373. pszName[dwNameSize] = 0;
  1374. // Fill in the device name, and set the offset info
  1375. //
  1376. pidl->ulStrDeviceNamePos = pidl->ulStrNamePos + pidl->ulStrNameSize;
  1377. pidl->ulStrDeviceNameSize = dwDeviceNameSize * sizeof(WCHAR); // in bytes
  1378. pszDeviceName = pidl->PszGetDeviceNamePointer();
  1379. lstrcpyW(pszDeviceName, GetDeviceName());
  1380. pszDeviceName[dwDeviceNameSize] = 0;
  1381. // Set the offset into the PIDL's pbBuf
  1382. //
  1383. pidl->ulPersistBufPos = pidl->ulStrDeviceNamePos + pidl->ulStrDeviceNameSize;
  1384. // Fill in the persist buffer, if present (it won't be on a wizard)
  1385. //
  1386. if (GetPersistData())
  1387. {
  1388. pidl->ulPersistBufSize = GetPersistSize();
  1389. CopyMemory(pidl->bData + pidl->ulPersistBufPos, GetPersistData(), GetPersistSize());
  1390. }
  1391. else
  1392. {
  1393. // Since we're the wizard, there shouldn't be a buffer, so the size
  1394. // should always be passed in as 0.
  1395. //
  1396. Assert(GetPersistSize() == 0);
  1397. pidl->ulPersistBufSize = 0;
  1398. }
  1399. // Fill in the Phone Number & Host Address name, and set the offset info
  1400. //
  1401. pidl->ulStrPhoneOrHostAddressPos = pidl->ulPersistBufPos + pidl->ulPersistBufSize; // offset
  1402. pidl->ulStrPhoneOrHostAddressSize = dwPhoneOrHostAddressSize * sizeof(WCHAR); // in bytes
  1403. pszPhoneOrHostAddress = pidl->PszGetPhoneOrHostAddressPointer();
  1404. lstrcpyW(pszPhoneOrHostAddress, GetPhoneOrHostAddress());
  1405. pszPhoneOrHostAddress[dwPhoneOrHostAddressSize] = 0;
  1406. Assert( !lstrcmpW(pidl->PszGetNamePointer(), GetName()) );
  1407. Assert( !lstrcmpW(pidl->PszGetPhoneOrHostAddressPointer(), GetPhoneOrHostAddress()) );
  1408. Assert( !lstrcmpW(pidl->PszGetDeviceNamePointer(), GetDeviceName()) );
  1409. Assert( !memcmp(pidl->PbGetPersistBufPointer(), GetPersistData(), GetPersistSize()) );
  1410. // Don't forget to terminate the list!
  1411. //
  1412. LPITEMIDLIST pidlTerminate;
  1413. pidlTerminate = ILNext( pidl.GetItemIdList() );
  1414. pidlTerminate->mkid.cb = 0;
  1415. }
  1416. else
  1417. {
  1418. AssertSz(FALSE, "CConFoldEntry::ConvertToPidl is hosed");
  1419. hr = E_OUTOFMEMORY;
  1420. }
  1421. #ifdef DBG_VALIDATE_PIDLS
  1422. Assert(IsValidPIDL( pidl.GetItemIdList() ));
  1423. #endif
  1424. Assert( pidl->IsPidlOfThisType() ) ;
  1425. if (SUCCEEDED(hr))
  1426. {
  1427. m_bDirty = FALSE;
  1428. m_CachedV2Pidl = pidl;
  1429. }
  1430. }
  1431. else
  1432. {
  1433. TraceTag(ttidShellFolder, "Using internally cached PIDL");
  1434. pidl = m_CachedV2Pidl;
  1435. }
  1436. NETCFG_CATCH(hr)
  1437. TraceHr(ttidError, FAL, hr, FALSE, "CConFoldEntry::ConvertToPidl");
  1438. return hr;
  1439. }
  1440. CONFOLDPIDLTYPE GetPidlType(LPCITEMIDLIST pidl)
  1441. {
  1442. CONFOLDPIDLTYPE bRet = PIDL_TYPE_UNKNOWN;
  1443. if (!pidl)
  1444. {
  1445. return bRet;
  1446. }
  1447. // V1 check
  1448. if (pidl->mkid.cb >= CBCONFOLDPIDLV1_MIN)
  1449. {
  1450. const UNALIGNED ConFoldPidl_v1* pcfp = reinterpret_cast<const ConFoldPidl_v1*>(pidl);
  1451. if ( (pcfp->iCB >= CBCONFOLDPIDLV1_MIN) && (pcfp->iCB <= CBCONFOLDPIDLV1_MAX))
  1452. {
  1453. if (pcfp->uLeadId == CONFOLDPIDL_LEADID &&
  1454. pcfp->uTrailId == CONFOLDPIDL_TRAILID)
  1455. {
  1456. if (pcfp->dwVersion == ConFoldPidl_v1::CONNECTIONS_FOLDER_IDL_VERSION)
  1457. {
  1458. bRet = PIDL_TYPE_V1;
  1459. return bRet;
  1460. }
  1461. }
  1462. }
  1463. }
  1464. // V2 check
  1465. if (pidl->mkid.cb >= CBCONFOLDPIDLV2_MIN)
  1466. {
  1467. const UNALIGNED ConFoldPidl_v2* pcfp = reinterpret_cast<const ConFoldPidl_v2 *>(pidl);
  1468. if ( (pcfp->iCB >= CBCONFOLDPIDLV2_MIN) && (pcfp->iCB <= CBCONFOLDPIDLV2_MAX))
  1469. {
  1470. if (pcfp->uLeadId == CONFOLDPIDL_LEADID &&
  1471. pcfp->uTrailId == CONFOLDPIDL_TRAILID)
  1472. {
  1473. if (pcfp->dwVersion == ConFoldPidl_v2::CONNECTIONS_FOLDER_IDL_VERSION)
  1474. {
  1475. bRet = PIDL_TYPE_V2;
  1476. return bRet;
  1477. }
  1478. }
  1479. }
  1480. }
  1481. // 98 Check
  1482. if (pidl->mkid.cb >= CBCONFOLDPIDL98_MIN)
  1483. {
  1484. const UNALIGNED ConFoldPidl98* pcfp = reinterpret_cast<const ConFoldPidl98 *>(pidl);
  1485. if ((pcfp->cbSize >= CBCONFOLDPIDL98_MIN) && (pcfp->cbSize <= CBCONFOLDPIDL98_MAX))
  1486. {
  1487. if ((SOF_REMOTE == pcfp->uFlags) || (SOF_NEWREMOTE == pcfp->uFlags) ||
  1488. (SOF_MEMBER == pcfp->uFlags))
  1489. {
  1490. if (pcfp->nIconIndex >= 0)
  1491. {
  1492. bRet = PIDL_TYPE_98;
  1493. return bRet;
  1494. }
  1495. }
  1496. }
  1497. }
  1498. return bRet;
  1499. }
  1500. HRESULT ConFoldPidl_v1::ConvertToConFoldEntry(OUT CConFoldEntry& ccfe) const
  1501. {
  1502. HRESULT hr = S_OK;
  1503. Assert(this);
  1504. if (!this)
  1505. {
  1506. return E_UNEXPECTED;
  1507. }
  1508. #if ( defined (MMMDBG) && defined ( _X86_ ) )
  1509. if ( (g_ccl.m_csMain.OwningThread == (HANDLE)GetCurrentThreadId()) && (g_ccl.m_csMain.LockCount != -1) )
  1510. {
  1511. AssertSz(NULL, ".ConvertToConFoldEntry is called while the thread is owning g_ccl's Critical section. \r\n"
  1512. "This may deadlock since .ConvertToConFoldEntry needs to marshall COM calls to other threads \r\n\r\n"
  1513. "To Fix: Make a copy of ccfe from the pidl and Release the lock before calling .ConvertToConFoldEntry.");
  1514. }
  1515. #endif
  1516. // hr = ConvertToPidlInCache(*this, pcfp); // NOT REQUIRED. WE KNOW THIS IS A V1 PIDL!
  1517. // Initialize the data from the pidl
  1518. hr = ccfe.HrInitData(wizWizard,
  1519. ncm,
  1520. NCSM_NONE,
  1521. ncs,
  1522. &clsid,
  1523. &guidId,
  1524. dwCharacteristics,
  1525. PbGetPersistBufPointer(),
  1526. ulPersistBufSize,
  1527. PszGetNamePointer(),
  1528. PszGetDeviceNamePointer(),
  1529. NULL /*PszGetPhoneOrHostAddressPointer()*/);
  1530. if (FAILED(hr))
  1531. {
  1532. TraceHr(ttidShellFolder, FAL, hr, FALSE, "Failed in call to pcfe->HrInitData in ConvertToConFoldEntry");
  1533. }
  1534. TraceHr(ttidError, FAL, hr, FALSE, "ConvertToConFoldEntry");
  1535. return hr;
  1536. }
  1537. HRESULT ConFoldPidl_v2::ConvertToConFoldEntry(OUT CConFoldEntry& ccfe) const
  1538. {
  1539. HRESULT hr = S_OK;
  1540. Assert(this);
  1541. if (!this)
  1542. {
  1543. return E_UNEXPECTED;
  1544. }
  1545. #if ( defined (MMMDBG) && defined ( _X86_ ) )
  1546. if ( (g_ccl.m_csMain.OwningThread == (HANDLE)GetCurrentThreadId()) && (g_ccl.m_csMain.LockCount != -1) )
  1547. {
  1548. AssertSz(NULL, ".ConvertToConFoldEntry is called while the thread is owning g_ccl's Critical section. \r\n"
  1549. "This may deadlock since .ConvertToConFoldEntry needs to marshall COM calls to other threads \r\n\r\n"
  1550. "To Fix: Make a copy of ccfe from the pidl and Release the lock before calling .ConvertToConFoldEntry.");
  1551. }
  1552. #endif
  1553. // hr = ConvertToPidlInCache(*this, pcfp); // NOT REQUIRED. WE KNOW THIS IS A V2 PIDL!
  1554. // Initialize the data from the pidl
  1555. hr = ccfe.HrInitData(wizWizard,
  1556. ncm,
  1557. ncsm,
  1558. ncs,
  1559. &clsid,
  1560. &guidId,
  1561. dwCharacteristics,
  1562. PbGetPersistBufPointer(),
  1563. ulPersistBufSize,
  1564. PszGetNamePointer(),
  1565. PszGetDeviceNamePointer(),
  1566. PszGetPhoneOrHostAddressPointer());
  1567. if (FAILED(hr))
  1568. {
  1569. TraceHr(ttidShellFolder, FAL, hr, FALSE, "Failed in call to pcfe->HrInitData in ConvertToConFoldEntry");
  1570. }
  1571. TraceHr(ttidError, FAL, hr, FALSE, "ConvertToConFoldEntry");
  1572. return hr;
  1573. }