Leaked source code of windows server 2003
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.

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