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.

493 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: I E N U M I D L . C P P
  7. //
  8. // Contents: IEnumIDList implementation for CConnectionFolderEnum
  9. //
  10. // Notes:
  11. //
  12. // Author: jeffspr 22 Sep 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "foldinc.h" // Standard shell\folder includes
  18. #include "ncnetcon.h"
  19. #include "webview.h"
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Member: CConnectionFolderEnum::CConnectionFolderEnum
  23. //
  24. // Purpose: Constructor for the enumerator
  25. //
  26. // Arguments:
  27. // (none)
  28. //
  29. // Returns:
  30. //
  31. // Author: jeffspr 18 Mar 1998
  32. //
  33. // Notes:
  34. //
  35. CConnectionFolderEnum::CConnectionFolderEnum() throw()
  36. {
  37. TraceFileFunc(ttidShellFolderIface);
  38. m_iterPidlCurrent = m_apidl.end();
  39. m_pidlFolder.Clear();
  40. m_dwFlags = 0;
  41. m_fTray = FALSE;
  42. m_dwEnumerationType = CFCOPT_ENUMALL; // all connection types
  43. }
  44. //+---------------------------------------------------------------------------
  45. //
  46. // Function: CConnectionFolderEnum
  47. //
  48. // Purpose: Destructor for the enumerator. Standard cleanup.
  49. //
  50. // Arguments:
  51. // (none)
  52. //
  53. // Returns:
  54. //
  55. // Author: jeffspr 18 Mar 1998
  56. //
  57. // Notes:
  58. //
  59. CConnectionFolderEnum::~CConnectionFolderEnum() throw()
  60. {
  61. TraceFileFunc(ttidShellFolderIface);
  62. m_pidlFolder.Clear();
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // Function: CConnectionFolderEnum::PidlInitialize
  67. //
  68. // Purpose: Initialization for the enumerator object
  69. //
  70. // Arguments:
  71. // fTray [in] Are we owned by the tray
  72. // pidlFolder [in] Pidl for the folder itself
  73. // dwEnumerationType [in] Enumeration type (inbound/outbound/all)
  74. //
  75. // Returns:
  76. //
  77. // Author: jeffspr 18 Mar 1998
  78. //
  79. // Notes:
  80. //
  81. VOID CConnectionFolderEnum::PidlInitialize(
  82. IN BOOL fTray,
  83. OUT const PCONFOLDPIDLFOLDER& pidlFolder,
  84. OUT DWORD dwEnumerationType)
  85. {
  86. TraceFileFunc(ttidShellFolderIface);
  87. NETCFG_TRY
  88. m_fTray = fTray;
  89. m_pidlFolder = pidlFolder;
  90. m_dwEnumerationType = dwEnumerationType;
  91. NETCFG_CATCH_AND_RETHROW
  92. }
  93. //+---------------------------------------------------------------------------
  94. //
  95. // Member: CConnectionFolderEnum::CreateInstance
  96. //
  97. // Purpose: Create an instance of the CConnectionFolderEnum object, and
  98. // returns the requested interface
  99. //
  100. // Arguments:
  101. // riid [in] Interface requested
  102. // ppv [out] Pointer to receive the requested interface
  103. //
  104. // Returns: Standard OLE HRESULT
  105. //
  106. // Author: jeffspr 5 Nov 1997
  107. //
  108. // Notes:
  109. //
  110. HRESULT CConnectionFolderEnum::CreateInstance(
  111. IN REFIID riid,
  112. OUT void** ppv)
  113. {
  114. TraceFileFunc(ttidShellFolderIface);
  115. HRESULT hr = E_OUTOFMEMORY;
  116. CConnectionFolderEnum * pObj = NULL;
  117. pObj = new CComObject <CConnectionFolderEnum>;
  118. if (pObj)
  119. {
  120. // Do the standard CComCreator::CreateInstance stuff.
  121. //
  122. pObj->SetVoid (NULL);
  123. pObj->InternalFinalConstructAddRef ();
  124. hr = pObj->FinalConstruct ();
  125. pObj->InternalFinalConstructRelease ();
  126. if (SUCCEEDED(hr))
  127. {
  128. hr = pObj->QueryInterface (riid, ppv);
  129. }
  130. if (FAILED(hr))
  131. {
  132. delete pObj;
  133. }
  134. }
  135. TraceHr(ttidError, FAL, hr, FALSE, "CConnectionFolderEnum::CreateInstance");
  136. return hr;
  137. }
  138. //+---------------------------------------------------------------------------
  139. //
  140. // Member: CConnectionFolderEnum::Next
  141. //
  142. // Purpose: Retrieves the specified number of item identifiers in the
  143. // enumeration sequence and advances the current position
  144. // by the number of items retrieved.
  145. //
  146. // Arguments:
  147. // celt [] Max number requested
  148. // rgelt [] Array to fill
  149. // pceltFetched [] Return count for # filled.
  150. //
  151. // Returns: S_OK if successful, S_FALSE if there are no more items
  152. // in the enumeration sequence, or an OLE-defined error value
  153. // otherwise.
  154. //
  155. // Author: jeffspr 5 Nov 1997
  156. //
  157. // Notes:
  158. //
  159. STDMETHODIMP CConnectionFolderEnum::Next(
  160. IN ULONG celt,
  161. OUT LPITEMIDLIST * rgelt,
  162. OUT ULONG * pceltFetched)
  163. {
  164. TraceFileFunc(ttidShellFolderIface);
  165. HRESULT hr = S_OK;
  166. Assert(celt >= 1);
  167. Assert(rgelt);
  168. Assert(pceltFetched || (celt == 1));
  169. // If the caller asks for the fetch count, zero it out for now.
  170. //
  171. if (pceltFetched)
  172. {
  173. *pceltFetched = 0;
  174. }
  175. // Init the output list pointer
  176. //
  177. *rgelt = NULL;
  178. // If there's not currently a list, build one.
  179. //
  180. if (m_apidl.empty())
  181. {
  182. hr = Reset();
  183. // This will have returned either S_FALSE (no wizard? weird!), an
  184. // error (meaning creating the wizard failed), or S_OK, meaning
  185. // that (at least) the wizard creation succeeded. Enum of the connections
  186. // failing will get filtered by Reset().
  187. }
  188. if (SUCCEEDED(hr))
  189. {
  190. // If there are NOW items in the list
  191. //
  192. if (!m_apidl.empty() )
  193. {
  194. BOOL fMatchFound = FALSE;
  195. // Check that we've set the current pointer to at least the root
  196. //
  197. // Normalize the return code
  198. hr = S_OK;
  199. while ((S_OK == hr) && !fMatchFound)
  200. {
  201. // If there are no remaining entries, return S_FALSE.
  202. //
  203. if ( m_iterPidlCurrent == m_apidl.end() )
  204. {
  205. hr = S_FALSE;
  206. }
  207. else
  208. {
  209. const PCONFOLDPIDL& pcfp = *m_iterPidlCurrent;
  210. // Else, Return the first entry, then increment the current
  211. // pointer
  212. //
  213. Assert(!pcfp.empty());
  214. // Check to see if we want to return this type, based on
  215. // the enumeration type & connection type. The wizard
  216. // should always be included.
  217. //
  218. if ( WIZARD_NOT_WIZARD != pcfp->wizWizard )
  219. {
  220. if (HrIsWebViewEnabled() == S_OK)
  221. {
  222. m_iterPidlCurrent++; // skip over this item
  223. continue;
  224. }
  225. else
  226. {
  227. fMatchFound = TRUE;
  228. }
  229. }
  230. else
  231. {
  232. switch(m_dwEnumerationType)
  233. {
  234. case CFCOPT_ENUMALL:
  235. fMatchFound = TRUE;
  236. break;
  237. case CFCOPT_ENUMINCOMING:
  238. fMatchFound = (pcfp->dwCharacteristics & NCCF_INCOMING_ONLY);
  239. break;
  240. case CFCOPT_ENUMOUTGOING:
  241. fMatchFound = !(pcfp->dwCharacteristics & NCCF_INCOMING_ONLY);
  242. break;
  243. }
  244. }
  245. // If we've found one that needn't be filtered out,
  246. // then fill in the return param, etc.
  247. //
  248. if (fMatchFound)
  249. {
  250. // Copy the pidl for return
  251. //
  252. rgelt[0] = m_iterPidlCurrent->TearOffItemIdList();
  253. if (!rgelt[0])
  254. {
  255. hr = E_OUTOFMEMORY;
  256. }
  257. else
  258. {
  259. // If they requested a return count, fill it in.
  260. //
  261. if (pceltFetched)
  262. {
  263. *pceltFetched = 1;
  264. }
  265. // ISSUE:
  266. // IsValidPIDL is debug code. However, we're doing this in release mode until we
  267. // find the bug from NTRAID#NTBUG9-125787-2000/07/26-deonb.
  268. #ifdef DBG_VALIDATE_PIDLS
  269. if (!IsValidPIDL(rgelt[0]))
  270. {
  271. return E_ABORT;
  272. }
  273. #endif
  274. }
  275. }
  276. // Move the pointer to the next pidl in the list.
  277. //
  278. m_iterPidlCurrent++;
  279. }
  280. }
  281. }
  282. else
  283. {
  284. // There are no items in the list, return S_FALSE
  285. //
  286. hr = S_FALSE;
  287. }
  288. }
  289. #ifdef DBG
  290. if (pceltFetched)
  291. {
  292. TraceTag(ttidShellFolderIface, "IEnumIDList::Next generated PIDL: 0x%08x", rgelt[0]);
  293. }
  294. #endif
  295. TraceHr(ttidError, FAL, hr, (S_FALSE == hr), "CConnectionFolderEnum::Next");
  296. return hr;
  297. }
  298. //+---------------------------------------------------------------------------
  299. //
  300. // Member: CConnectionFolderEnum::Skip
  301. //
  302. // Purpose: Skips over the specified number of elements in the
  303. // enumeration sequence.
  304. //
  305. // Arguments:
  306. // celt [in] Number of item identifiers to skip.
  307. //
  308. // Returns: Returns S_OK if successful, or an OLE-defined error
  309. // value otherwise.
  310. //
  311. // Author: jeffspr 5 Nov 1997
  312. //
  313. // Notes:
  314. //
  315. STDMETHODIMP CConnectionFolderEnum::Skip(
  316. IN ULONG celt)
  317. {
  318. TraceFileFunc(ttidShellFolderIface);
  319. HRESULT hr = S_OK;
  320. NYI("CConnectionFolderEnum::Skip");
  321. // Currently, do nothing
  322. //
  323. TraceHr(ttidError, FAL, hr, FALSE, "CConnectionFolderEnum::Skip");
  324. return S_OK;
  325. }
  326. //+---------------------------------------------------------------------------
  327. //
  328. // Member: CConnectionFolderEnum::Reset
  329. //
  330. // Purpose: Returns to the beginning of the enumeration sequence. For us,
  331. // this means do all of the actual enumeration
  332. //
  333. // Arguments:
  334. // (none)
  335. //
  336. // Returns: Returns S_OK if successful, or an OLE-defined error
  337. // value otherwise.
  338. //
  339. // Author: jeffspr 5 Nov 1997
  340. //
  341. // Notes:
  342. //
  343. STDMETHODIMP CConnectionFolderEnum::Reset()
  344. {
  345. TraceFileFunc(ttidShellFolderIface);
  346. HRESULT hr = S_OK;
  347. // If there's already a list, free it and rebuild.
  348. //
  349. if (!m_apidl.empty())
  350. {
  351. m_apidl.clear();
  352. m_iterPidlCurrent = m_apidl.end();
  353. }
  354. hr = HrRetrieveConManEntries();
  355. if (SUCCEEDED(hr))
  356. {
  357. // Normalize the return code. HrRetrieveConManEntries... may have returned
  358. // S_FALSE, meaning that there we no connections (fine).
  359. //
  360. hr = S_OK;
  361. m_iterPidlCurrent = m_apidl.begin();
  362. }
  363. else
  364. {
  365. // Actually, we're still going to return noerror here after tracing the problem,
  366. // as we don't want to keep the enumerator from returning an error
  367. // if the wizard is present (no connections, but hey, better than nothing).
  368. //
  369. TraceHr(ttidError, FAL, hr, FALSE,
  370. "CConnectionsFolderEnum failed in call to HrRetrieveConManEntries");
  371. hr = S_FALSE;
  372. }
  373. TraceHr(ttidError, FAL, hr, FALSE, "CConnectionFolderEnum::Reset");
  374. return hr;
  375. }
  376. //+---------------------------------------------------------------------------
  377. //
  378. // Member: CConnectionFolderEnum::Clone
  379. //
  380. // Purpose: Creates a new item enumeration object with the same contents
  381. // and state as the current one.
  382. //
  383. // Arguments:
  384. // ppenum [out] Return a clone of the current internal PIDL
  385. //
  386. // Returns: Returns S_OK if successful, or an OLE-defined error
  387. // value otherwise.
  388. //
  389. // Author: jeffspr 5 Nov 1997
  390. //
  391. // Notes:
  392. //
  393. STDMETHODIMP CConnectionFolderEnum::Clone(
  394. OUT IEnumIDList ** ppenum)
  395. {
  396. TraceFileFunc(ttidShellFolderIface);
  397. NYI("CConnectionFolderEnum::Clone");
  398. *ppenum = NULL;
  399. return E_NOTIMPL;
  400. }
  401. //+---------------------------------------------------------------------------
  402. //
  403. // Member: CConnectionFolderEnum::HrRetrieveConManEntries
  404. //
  405. // Purpose: Enumerate all connections from the ConnectionManagers, and
  406. // add them to our IDL.
  407. //
  408. // Arguments:
  409. // (none)
  410. //
  411. // Returns:
  412. //
  413. // Author: jeffspr 8 Oct 1997
  414. //
  415. // Notes:
  416. //
  417. HRESULT CConnectionFolderEnum::HrRetrieveConManEntries()
  418. {
  419. TraceFileFunc(ttidShellFolderIface);
  420. HRESULT hr = S_OK;
  421. NETCFG_TRY
  422. PCONFOLDPIDLVEC apidlNew;
  423. hr = g_ccl.HrRetrieveConManEntries(apidlNew);
  424. if (SUCCEEDED(hr))
  425. {
  426. m_apidl.clear();
  427. m_apidl = apidlNew;
  428. }
  429. TraceHr(ttidError, FAL, hr, FALSE, "CConnectionFolder::HrRetrieveConManEntries");
  430. NETCFG_CATCH(hr)
  431. return hr;
  432. }