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.

479 lines
12 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: expiter.cxx
  7. //
  8. // Contents: CExposedIterator implementation
  9. //
  10. // History: 12-Mar-92 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <exphead.cxx>
  14. #pragma hdrstop
  15. #include <expiter.hxx>
  16. #include <sstream.hxx>
  17. #include <ptrcache.hxx>
  18. #include <expparam.hxx>
  19. //+--------------------------------------------------------------
  20. //
  21. // Member: CExposedIterator::CExposedIterator, public
  22. //
  23. // Synopsis: Constructor
  24. //
  25. // Arguments: [ppdf] - Public docfile
  26. // [pdfnKey] - Initial key
  27. // [pdfb] - DocFile basis
  28. // [ppc] - Context
  29. //
  30. // History: 12-Mar-92 DrewB Created
  31. //
  32. //---------------------------------------------------------------
  33. CExposedIterator::CExposedIterator(CPubDocFile *ppdf,
  34. CDfName *pdfnKey,
  35. CDFBasis *pdfb,
  36. CPerContext *ppc)
  37. {
  38. olDebugOut((DEB_ITRACE, "In CExposedIterator::CExposedIterator("
  39. "%p, %d:%s, %p, %p)\n", ppdf, pdfnKey->GetLength(),
  40. pdfnKey->GetBuffer(), pdfb, ppc));
  41. _ppc = ppc;
  42. _ppdf = P_TO_BP(CBasedPubDocFilePtr, ppdf);
  43. _ppdf->vAddRef();
  44. _dfnKey.Set(pdfnKey);
  45. _pdfb = P_TO_BP(CBasedDFBasisPtr, pdfb);
  46. _pdfb->vAddRef();
  47. _cReferences = 1;
  48. _sig = CEXPOSEDITER_SIG;
  49. olDebugOut((DEB_ITRACE, "Out CExposedIterator::CExposedIterator\n"));
  50. }
  51. //+--------------------------------------------------------------
  52. //
  53. // Member: CExposedIterator::~CExposedIterator, public
  54. //
  55. // Synopsis: Destructor
  56. //
  57. // History: 22-Jan-92 DrewB Created
  58. //
  59. //---------------------------------------------------------------
  60. CExposedIterator::~CExposedIterator(void)
  61. {
  62. olDebugOut((DEB_ITRACE, "In CExposedIterator::~CExposedIterator\n"));
  63. _sig = CEXPOSEDITER_SIGDEL;
  64. //In order to call into the tree, we need to take the mutex.
  65. //The mutex may get deleted in _ppc->Release(), so we can't
  66. //release it here. The mutex actually gets released in
  67. //CPerContext::Release() or in the CPerContext destructor.
  68. SCODE sc;
  69. #if !defined(MULTIHEAP)
  70. // TakeSem and ReleaseSem are moved to the Release Method
  71. // so that the deallocation for this object is protected
  72. if (_ppc)
  73. {
  74. sc = TakeSem();
  75. SetWriteAccess();
  76. olAssert(SUCCEEDED(sc));
  77. }
  78. #ifdef ASYNC
  79. IDocfileAsyncConnectionPoint *pdacp = _cpoint.GetMarshalPoint();
  80. #endif
  81. #endif //MULTIHEAP
  82. olAssert(_cReferences == 0);
  83. if (_ppdf)
  84. _ppdf->CPubDocFile::vRelease();
  85. if (_pdfb)
  86. _pdfb->CDFBasis::vRelease();
  87. #if !defined(MULTIHEAP)
  88. if (_ppc)
  89. {
  90. if (_ppc->Release() > 0)
  91. ReleaseSem(sc);
  92. }
  93. #ifdef ASYNC
  94. //Mutex has been released, so we can release the connection point
  95. // without fear of deadlock.
  96. if (pdacp != NULL)
  97. pdacp->Release();
  98. #endif
  99. #endif // MULTIHEAP
  100. olDebugOut((DEB_ITRACE, "Out CExposedIterator::~CExposedIterator\n"));
  101. }
  102. //+--------------------------------------------------------------
  103. //
  104. // Member: CExposedIterator::Next, public
  105. //
  106. // Synopsis: Gets N entries from an iterator
  107. //
  108. // Arguments: [celt] - Count of elements
  109. // [rgelt] - Array for element return
  110. // [pceltFetched] - If non-NULL, contains the number of
  111. // elements fetched
  112. //
  113. // Returns: Appropriate status code
  114. //
  115. // Modifies: [rgelt]
  116. // [pceltFetched]
  117. //
  118. // History: 16-Mar-92 DrewB Created
  119. //
  120. //---------------------------------------------------------------
  121. _OLESTDMETHODIMP CExposedIterator::Next(ULONG celt,
  122. STATSTGW FAR *rgelt,
  123. ULONG *pceltFetched)
  124. {
  125. SAFE_SEM;
  126. SAFE_ACCESS;
  127. SCODE sc;
  128. STATSTGW *pelt = rgelt;
  129. ULONG celtDone;
  130. CDfName dfnInitial;
  131. CPtrCache pc;
  132. STATSTGW stat;
  133. olDebugOut((DEB_TRACE, "In CExposedIterator::Next(%lu, %p, %p)\n",
  134. celt, rgelt, pceltFetched));
  135. OL_VALIDATE(Next(celt, rgelt, pceltFetched));
  136. olChk(Validate());
  137. BEGIN_PENDING_LOOP;
  138. olChk(TakeSafeSem());
  139. SetReadAccess();
  140. olChk(_ppdf->CheckReverted());
  141. // Preserve initial key to reset on failure
  142. dfnInitial.Set(&_dfnKey);
  143. TRY
  144. {
  145. for (; pelt<rgelt+celt; pelt++)
  146. {
  147. sc = _ppdf->FindGreaterEntry(&_dfnKey, NULL, &stat, FALSE);
  148. if (FAILED(sc))
  149. {
  150. if (sc == STG_E_NOMOREFILES)
  151. sc = S_FALSE;
  152. break;
  153. }
  154. if (FAILED(sc = pc.Add(stat.pwcsName)))
  155. {
  156. TaskMemFree(stat.pwcsName);
  157. break;
  158. }
  159. _dfnKey.Set(stat.pwcsName);
  160. stat.grfMode = 0;
  161. stat.grfLocksSupported = 0;
  162. stat.STATSTG_dwStgFmt = 0;
  163. *pelt = stat;
  164. }
  165. }
  166. CATCH(CException, e)
  167. {
  168. sc = e.GetErrorCode();
  169. }
  170. END_CATCH
  171. END_PENDING_LOOP;
  172. // Can't move this down because dfnInitial isn't set for all EH_Err cases
  173. if (FAILED(sc))
  174. _dfnKey.Set(&dfnInitial);
  175. olDebugOut((DEB_TRACE, "Out CExposedIterator::Next => %lX\n", sc));
  176. EH_Err:
  177. celtDone = (ULONG)(pelt-rgelt);
  178. if (FAILED(sc))
  179. {
  180. void *pv;
  181. pc.StartEnum();
  182. while (pc.Next(&pv))
  183. TaskMemFree(pv);
  184. }
  185. else if (pceltFetched)
  186. // May fault but that's acceptable
  187. *pceltFetched = celtDone;
  188. return _OLERETURN(sc);
  189. }
  190. //+--------------------------------------------------------------
  191. //
  192. // Member: CExposedIterator::Skip, public
  193. //
  194. // Synopsis: Skips N entries from an iterator
  195. //
  196. // Arguments: [celt] - Count of elements
  197. //
  198. // Returns: Appropriate status code
  199. //
  200. // History: 16-Mar-92 DrewB Created
  201. //
  202. //---------------------------------------------------------------
  203. STDMETHODIMP CExposedIterator::Skip(ULONG celt)
  204. {
  205. SCODE sc;
  206. olDebugOut((DEB_TRACE, "In CExposedIterator::Skip(%lu)\n", celt));
  207. OL_VALIDATE(Skip(celt));
  208. if (SUCCEEDED(sc = Validate()))
  209. sc = hSkip(celt, FALSE);
  210. olDebugOut((DEB_TRACE, "Out CExposedIterator::Skip\n"));
  211. return ResultFromScode(sc);
  212. }
  213. //+--------------------------------------------------------------
  214. //
  215. // Member: CExposedIterator::Reset, public
  216. //
  217. // Synopsis: Rewinds the iterator
  218. //
  219. // Returns: Appropriate status code
  220. //
  221. // History: 22-Jan-92 DrewB Created
  222. //
  223. //---------------------------------------------------------------
  224. STDMETHODIMP CExposedIterator::Reset(void)
  225. {
  226. SCODE sc;
  227. olDebugOut((DEB_TRACE, "In CExposedIterator::Reset()\n"));
  228. OL_VALIDATE(Reset());
  229. if (SUCCEEDED(sc = Validate()))
  230. sc = hReset();
  231. olDebugOut((DEB_TRACE, "Out CExposedIterator::Reset\n"));
  232. return ResultFromScode(sc);
  233. }
  234. //+--------------------------------------------------------------
  235. //
  236. // Member: CExposedIterator::Clone, public
  237. //
  238. // Synopsis: Clones this iterator
  239. //
  240. // Arguments: [ppenm] - Clone return
  241. //
  242. // Returns: Appropriate status code
  243. //
  244. // Modifies: [ppenm]
  245. //
  246. // History: 26-Mar-92 DrewB Created
  247. //
  248. //---------------------------------------------------------------
  249. STDMETHODIMP CExposedIterator::Clone(IEnumSTATSTG **ppenm)
  250. {
  251. SCODE sc, scSem = STG_E_INUSE;
  252. SafeCExposedIterator piExp;
  253. #ifdef MULTIHEAP
  254. CSafeMultiHeap smh(_ppc);
  255. #endif
  256. olDebugOut((DEB_TRACE, "In CExposedIterator::Clone(%p)\n", ppenm));
  257. OL_VALIDATE(Clone(ppenm));
  258. olChk(Validate());
  259. olChk(scSem = TakeSem());
  260. if (!SUCCEEDED(sc = _ppdf->CheckReverted()))
  261. {
  262. ReleaseSem(scSem);
  263. olChk(sc);
  264. }
  265. SetReadAccess();
  266. piExp.Attach(new CExposedIterator(BP_TO_P(CPubDocFile *, _ppdf),
  267. &_dfnKey,
  268. BP_TO_P(CDFBasis *, _pdfb),
  269. _ppc));
  270. if ((CExposedIterator *)piExp == NULL)
  271. sc = STG_E_INSUFFICIENTMEMORY;
  272. ClearReadAccess();
  273. ReleaseSem(scSem);
  274. if (SUCCEEDED(sc))
  275. {
  276. _ppc->AddRef();
  277. TRANSFER_INTERFACE(piExp, IEnumSTATSTG, ppenm);
  278. }
  279. if (_cpoint.IsInitialized())
  280. {
  281. olChkTo(EH_init, piExp->InitClone(&_cpoint));
  282. }
  283. olDebugOut((DEB_TRACE, "Out CExposedIterator::Clone => %p\n",
  284. *ppenm));
  285. // Fall through
  286. EH_Err:
  287. return ResultFromScode(sc);
  288. EH_init:
  289. piExp->Release();
  290. goto EH_Err;
  291. }
  292. //+--------------------------------------------------------------
  293. //
  294. // Member: CExposedIterator::Release, public
  295. //
  296. // Synopsis: Releases resources for the iterator
  297. //
  298. // Returns: Appropriate status code
  299. //
  300. // History: 22-Jan-92 DrewB Created
  301. //
  302. //---------------------------------------------------------------
  303. STDMETHODIMP_(ULONG) CExposedIterator::Release(void)
  304. {
  305. LONG lRet;
  306. olDebugOut((DEB_TRACE, "In CExposedIterator::Release()\n"));
  307. #ifdef MULTIHEAP
  308. CSafeMultiHeap smh(_ppc);
  309. CPerContext *ppc = _ppc;
  310. SCODE sc = S_OK;
  311. #endif
  312. if (FAILED(Validate()))
  313. return 0;
  314. if ((lRet = hRelease()) == 0)
  315. #ifdef MULTIHEAP
  316. {
  317. if (_ppc)
  318. {
  319. sc = TakeSem();
  320. SetWriteAccess();
  321. olAssert(SUCCEEDED(sc));
  322. }
  323. #ifdef ASYNC
  324. IDocfileAsyncConnectionPoint *pdacp = _cpoint.GetMarshalPoint();
  325. #endif
  326. #endif //MULTIHEAP
  327. delete this;
  328. #ifdef MULTIHEAP
  329. if (ppc)
  330. {
  331. if (ppc->Release() == 0)
  332. g_smAllocator.Uninit();
  333. else
  334. if (SUCCEEDED(sc)) ppc->UntakeSem();
  335. }
  336. #ifdef ASYNC
  337. //Mutex has been released, so we can release the connection point
  338. // without fear of deadlock.
  339. if (pdacp != NULL)
  340. pdacp->Release();
  341. #endif
  342. }
  343. #endif
  344. olDebugOut((DEB_TRACE, "Out CExposedIterator::Release\n"));
  345. return lRet;
  346. }
  347. //+--------------------------------------------------------------
  348. //
  349. // Member: CExposedIterator::AddRef, public
  350. //
  351. // Synopsis: Increments the ref count
  352. //
  353. // Returns: Appropriate status code
  354. //
  355. // History: 16-Mar-92 DrewB Created
  356. //
  357. //---------------------------------------------------------------
  358. STDMETHODIMP_(ULONG) CExposedIterator::AddRef(void)
  359. {
  360. ULONG ulRet;
  361. olDebugOut((DEB_TRACE, "In CExposedIterator::AddRef()\n"));
  362. if (FAILED(Validate()))
  363. return 0;
  364. ulRet = hAddRef();
  365. olDebugOut((DEB_TRACE, "Out CExposedIterator::AddRef\n"));
  366. return ulRet;
  367. }
  368. //+--------------------------------------------------------------
  369. //
  370. // Member: CExposedIterator::QueryInterface, public
  371. //
  372. // Synopsis: Returns an object for the requested interface
  373. //
  374. // Arguments: [iid] - Interface ID
  375. // [ppvObj] - Object return
  376. //
  377. // Returns: Appropriate status code
  378. //
  379. // Modifies: [ppvObj]
  380. //
  381. // History: 26-Mar-92 DrewB Created
  382. //
  383. //---------------------------------------------------------------
  384. STDMETHODIMP CExposedIterator::QueryInterface(REFIID iid, void **ppvObj)
  385. {
  386. SCODE sc;
  387. olDebugOut((DEB_TRACE, "In CExposedIterator::QueryInterface(?, %p)\n",
  388. ppvObj));
  389. if (SUCCEEDED(sc = Validate()))
  390. sc = hQueryInterface(iid,
  391. IID_IEnumSTATSTG,
  392. (IEnumSTATSTG *)this,
  393. ppvObj);
  394. #ifdef ASYNC
  395. if (FAILED(sc) &&
  396. IsEqualIID(iid, IID_IConnectionPointContainer) &&
  397. _cpoint.IsInitialized())
  398. {
  399. *ppvObj = (IConnectionPointContainer *)this;
  400. CExposedIterator::AddRef();
  401. }
  402. #endif
  403. olDebugOut((DEB_TRACE, "Out CExposedIterator::QueryInterface => %p\n",
  404. ppvObj));
  405. return ResultFromScode(sc);
  406. }