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.

388 lines
9.7 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. //---------------------------------------------------------------
  11. #include "exphead.cxx"
  12. #include "expiter.hxx"
  13. #include "h/sstream.hxx"
  14. //+--------------------------------------------------------------
  15. //
  16. // Member: CExposedIterator::CExposedIterator, public
  17. //
  18. // Synopsis: Constructor
  19. //
  20. // Arguments: [ppdf] - Public Docfile
  21. // [pKey] - Initial cursor (doc file name)
  22. //
  23. //---------------------------------------------------------------
  24. CExposedIterator::CExposedIterator(CExposedDocFile *ppdf, CDfName *pKey)
  25. {
  26. olDebugOut((DEB_ITRACE, "In CExposedIterator::CExposedIterator("
  27. "%p, %p)\n", ppdf, pKey));
  28. _dfnKey.Set(pKey);
  29. _ppdf = ppdf;
  30. // keep a ref, so that the pointer is valid throughout life time
  31. // of iterator
  32. _ppdf->AddRef();
  33. _cReferences = 1;
  34. _sig = CEXPOSEDITER_SIG;
  35. olDebugOut((DEB_ITRACE,
  36. "Out CExposedIterator::CExposedIterator\n"));
  37. }
  38. //+--------------------------------------------------------------
  39. //
  40. // Member: CExposedIterator::~CExposedIterator, public
  41. //
  42. // Synopsis: Destructor
  43. //
  44. //---------------------------------------------------------------
  45. CExposedIterator::~CExposedIterator(void)
  46. {
  47. olDebugOut((DEB_ITRACE, "In CExposedIterator::~CExposedIterator\n"));
  48. _sig = CEXPOSEDITER_SIGDEL;
  49. olAssert(_cReferences == 0);
  50. if (_ppdf) _ppdf->Release();
  51. olDebugOut((DEB_ITRACE, "Out CExposedIterator::~CExposedIterator\n"));
  52. }
  53. //+--------------------------------------------------------------
  54. //
  55. // Member: CExposedIterator::Next, public
  56. //
  57. // Synopsis: Gets N entries from an iterator
  58. //
  59. // Arguments: [celt] - Count of elements
  60. // [rgelt] - Array for element return
  61. // [pceltFetched] - If non-NULL, contains the number of
  62. // elements fetched
  63. //
  64. // Returns: Appropriate status code
  65. //
  66. // Modifies: [rgelt]
  67. // [pceltFetched]
  68. //
  69. //---------------------------------------------------------------
  70. SCODE CExposedIterator::Next(ULONG celt,
  71. STATSTGW FAR *rgelt,
  72. ULONG *pceltFetched)
  73. {
  74. SCODE sc;
  75. STATSTGW stat, *pelt = rgelt;
  76. ULONG celtDone;
  77. CDfName dfnInitial;
  78. olDebugOut((DEB_ITRACE, "In CExposedIterator::Next(%lu, %p, %p)\n",
  79. celt, rgelt, pceltFetched));
  80. TRY
  81. {
  82. if (pceltFetched)
  83. {
  84. olChk(ValidateBuffer(pceltFetched, sizeof(ULONG)));
  85. *pceltFetched = 0;
  86. }
  87. else if (celt > 1)
  88. olErr(EH_Err, STG_E_INVALIDPARAMETER);
  89. olAssert(0xffffUL/sizeof(STATSTGW) >= celt);
  90. olChkTo(EH_RetSc,
  91. ValidateOutBuffer(rgelt, sizeof(STATSTGW)*celt));
  92. memset(rgelt, 0, (size_t)(sizeof(STATSTGW)*celt));
  93. olChk(Validate());
  94. olChk(_ppdf->CheckReverted());
  95. dfnInitial.Set(&_dfnKey); // preserve initial key to reset on failure
  96. for (; pelt<rgelt+celt; pelt++)
  97. {
  98. sc = _ppdf->FindGreaterEntry(&_dfnKey, NULL, &stat);
  99. if (FAILED(sc))
  100. {
  101. if (sc == STG_E_NOMOREFILES) sc = S_FALSE;
  102. break;
  103. }
  104. _dfnKey.Set(stat.pwcsName); // advance key
  105. stat.grfMode = 0;
  106. stat.grfLocksSupported = 0;
  107. stat.reserved = 0;
  108. *pelt = stat;
  109. }
  110. }
  111. CATCH(CException, e)
  112. {
  113. sc = e.GetErrorCode();
  114. }
  115. END_CATCH
  116. // Can't move this down because dfnInitial isn't set for all EH_Err cases
  117. if (FAILED(sc)) _dfnKey.Set(&dfnInitial);
  118. olDebugOut((DEB_ITRACE, "Out CExposedIterator::Next => %lX\n", sc));
  119. EH_Err:
  120. celtDone = pelt-rgelt;
  121. if (FAILED(sc))
  122. {
  123. ULONG i;
  124. for (i = 0; i<celtDone; i++)
  125. delete[] rgelt[i].pwcsName;
  126. memset(rgelt, 0, (size_t)(sizeof(STATSTGW)*celt));
  127. }
  128. else if (pceltFetched)
  129. *pceltFetched = celtDone;
  130. EH_RetSc:
  131. return sc;
  132. }
  133. //+--------------------------------------------------------------
  134. //
  135. // Member: CExposedIterator::Skip, public
  136. //
  137. // Synopsis: Skips N entries from an iterator
  138. //
  139. // Arguments: [celt] - Count of elements
  140. //
  141. // Returns: Appropriate status code
  142. //
  143. //---------------------------------------------------------------
  144. STDMETHODIMP CExposedIterator::Skip(ULONG celt)
  145. {
  146. SCODE sc;
  147. CDfName dfnNext;
  148. olDebugOut((DEB_ITRACE, "In CExposedIterator::Skip(%lu)\n", celt));
  149. TRY
  150. {
  151. olChk(Validate());
  152. olChk(_ppdf->CheckReverted());
  153. for (; celt>0; celt--)
  154. {
  155. sc = _ppdf->FindGreaterEntry(&_dfnKey, &dfnNext, NULL);
  156. if (FAILED(sc))
  157. {
  158. if (sc == STG_E_NOMOREFILES)
  159. sc = S_FALSE;
  160. break;
  161. }
  162. _dfnKey.Set(&dfnNext); // advance the cursor
  163. }
  164. }
  165. CATCH(CException, e)
  166. {
  167. sc = e.GetErrorCode();
  168. }
  169. END_CATCH
  170. olDebugOut((DEB_ITRACE, "Out CExposedIterator::Skip\n"));
  171. EH_Err:
  172. return ResultFromScode(sc);
  173. }
  174. //+--------------------------------------------------------------
  175. //
  176. // Member: CExposedIterator::Reset, public
  177. //
  178. // Synopsis: Rewinds the iterator
  179. //
  180. // Returns: Appropriate status code
  181. //
  182. //---------------------------------------------------------------
  183. STDMETHODIMP CExposedIterator::Reset(void)
  184. {
  185. SCODE sc;
  186. olDebugOut((DEB_ITRACE, "In CExposedIterator::Reset()\n"));
  187. TRY
  188. {
  189. olChk(Validate());
  190. _dfnKey.Set((WORD)0, (BYTE*)NULL); // set to smallest key
  191. sc = _ppdf->CheckReverted();
  192. }
  193. CATCH(CException, e)
  194. {
  195. sc = e.GetErrorCode();
  196. }
  197. END_CATCH
  198. olDebugOut((DEB_ITRACE, "Out CExposedIterator::Reset\n"));
  199. EH_Err:
  200. return ResultFromScode(sc);
  201. }
  202. //+--------------------------------------------------------------
  203. //
  204. // Member: CExposedIterator::Clone, public
  205. //
  206. // Synopsis: Clones this iterator
  207. //
  208. // Arguments: [ppenm] - Clone return
  209. //
  210. // Returns: Appropriate status code
  211. //
  212. // Modifies: [ppenm]
  213. //
  214. //---------------------------------------------------------------
  215. STDMETHODIMP CExposedIterator::Clone(IEnumSTATSTG **ppenm)
  216. {
  217. SCODE sc;
  218. CExposedIterator *piExp;
  219. olDebugOut((DEB_ITRACE, "In CExposedIterator::Clone(%p)\n", ppenm));
  220. TRY
  221. {
  222. olChk(ValidateOutPtrBuffer(ppenm));
  223. *ppenm = NULL;
  224. olChk(Validate());
  225. olChk(_ppdf->CheckReverted());
  226. olMem(piExp = new CExposedIterator(_ppdf, &_dfnKey));
  227. *ppenm = piExp;
  228. }
  229. CATCH(CException, e)
  230. {
  231. sc = e.GetErrorCode();
  232. }
  233. END_CATCH
  234. olDebugOut((DEB_ITRACE, "Out CExposedIterator::Clone => %p\n",
  235. SAFE_DREF(ppenm)));
  236. // Fall through
  237. EH_Err:
  238. return ResultFromScode(sc);
  239. }
  240. //+--------------------------------------------------------------
  241. //
  242. // Member: CExposedIterator::Release, public
  243. //
  244. // Synopsis: Releases resources for the iterator
  245. //
  246. // Returns: Appropriate status code
  247. //
  248. //---------------------------------------------------------------
  249. STDMETHODIMP_(ULONG) CExposedIterator::Release(void)
  250. {
  251. ULONG lRet;
  252. olDebugOut((DEB_ITRACE, "In CExposedIterator::Release()\n"));
  253. TRY
  254. {
  255. if (FAILED(Validate()))
  256. return 0;
  257. olAssert(_cReferences > 0);
  258. lRet = --(_cReferences);
  259. if (_cReferences <= 0)
  260. delete this;
  261. }
  262. CATCH(CException, e)
  263. {
  264. UNREFERENCED_PARM(e);
  265. lRet = 0;
  266. }
  267. END_CATCH
  268. olDebugOut((DEB_ITRACE, "Out CExposedIterator::Release\n"));
  269. return lRet;
  270. }
  271. //+--------------------------------------------------------------
  272. //
  273. // Member: CExposedIterator::AddRef, public
  274. //
  275. // Synopsis: Increments the ref count
  276. //
  277. // Returns: Appropriate status code
  278. //
  279. //---------------------------------------------------------------
  280. STDMETHODIMP_(ULONG) CExposedIterator::AddRef(void)
  281. {
  282. ULONG ulRet;
  283. olDebugOut((DEB_ITRACE, "In CExposedIterator::AddRef()\n"));
  284. TRY
  285. {
  286. if (FAILED(Validate())) return 0;
  287. ulRet = ++(_cReferences);
  288. }
  289. CATCH(CException, e)
  290. {
  291. UNREFERENCED_PARM(e);
  292. ulRet = 0;
  293. }
  294. END_CATCH
  295. olDebugOut((DEB_ITRACE, "Out CExposedIterator::AddRef\n"));
  296. return ulRet;
  297. }
  298. //+--------------------------------------------------------------
  299. //
  300. // Member: CExposedIterator::QueryInterface, public
  301. //
  302. // Synopsis: Returns an object for the requested interface
  303. //
  304. // Arguments: [iid] - Interface ID
  305. // [ppvObj] - Object return
  306. //
  307. // Returns: Appropriate status code
  308. //
  309. // Modifies: [ppvObj]
  310. //
  311. //---------------------------------------------------------------
  312. STDMETHODIMP CExposedIterator::QueryInterface(REFIID iid, void **ppvObj)
  313. {
  314. SCODE sc;
  315. olDebugOut((DEB_ITRACE, "In CExposedIterator::QueryInterface(?, %p)\n",
  316. ppvObj));
  317. TRY
  318. {
  319. olChk(Validate());
  320. olChk(ValidateOutPtrBuffer(ppvObj));
  321. *ppvObj = NULL;
  322. olChk(_ppdf->CheckReverted());
  323. olChk(ValidateIid(iid));
  324. if (IsEqualIID(iid, IID_IEnumSTATSTG) || IsEqualIID(iid, IID_IUnknown))
  325. {
  326. *ppvObj = this;
  327. AddRef();
  328. sc = S_OK;
  329. }
  330. else
  331. {
  332. sc = E_NOINTERFACE;
  333. }
  334. }
  335. CATCH(CException, e)
  336. {
  337. sc = e.GetErrorCode();
  338. }
  339. END_CATCH
  340. olDebugOut((DEB_ITRACE, "Out CExposedIterator::QueryInterface => %p\n",
  341. SAFE_DREF(ppvObj)));
  342. EH_Err:
  343. return ResultFromScode(sc);
  344. }