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.

1153 lines
26 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved
  3. Module Name:
  4. wsbenum.cpp
  5. Abstract:
  6. These classes provides enumerators (iterators) for the collection classes.
  7. Author:
  8. Chuck Bardeen [cbardeen] 29-Oct-1996
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "wsbenum.h"
  13. HRESULT
  14. CWsbIndexedEnum::Clone(
  15. OUT IWsbEnum** ppEnum
  16. )
  17. /*++
  18. Implements:
  19. IWsbEnum::Clone
  20. --*/
  21. {
  22. HRESULT hr = S_OK;
  23. CComPtr<IWsbEnum> pWsbEnum;
  24. WsbTraceIn(OLESTR("CWsbIndexedEnum::Clone(IWsbEnum)"), OLESTR(""));
  25. try {
  26. // Create a new enumeration instance.
  27. WsbAffirmHr(CoCreateInstance(CLSID_CWsbIndexedEnum, NULL, CLSCTX_ALL, IID_IWsbEnum, (void**) &pWsbEnum));
  28. // It should reference the same collection.
  29. WsbAffirmHr(pWsbEnum->Init((IWsbCollection*) m_pCollection));
  30. // It should reference the same item in the collection.
  31. WsbAffirmHr(pWsbEnum->SkipTo(m_currentIndex));
  32. *ppEnum = pWsbEnum;
  33. pWsbEnum.p->AddRef();
  34. } WsbCatch(hr);
  35. WsbTraceOut(OLESTR("CWsbIndexedEnum::Clone(IWbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  36. return(hr);
  37. }
  38. HRESULT
  39. CWsbIndexedEnum::Clone(
  40. OUT IWsbEnumEx** ppEnum
  41. )
  42. /*++
  43. Implements:
  44. IWsbEnumEx::Clone
  45. --*/
  46. {
  47. HRESULT hr = S_OK;
  48. CComPtr<IWsbEnumEx> pWsbEnum;
  49. WsbTraceIn(OLESTR("CWsbIndexedEnum::Clone(IWsbEnumEx)"), OLESTR(""));
  50. try {
  51. // Create a new enumeration instance.
  52. WsbAffirmHr(CoCreateInstance(CLSID_CWsbIndexedEnum, NULL, CLSCTX_ALL, IID_IWsbEnumEx, (void**) &pWsbEnum));
  53. // It should reference the same collection.
  54. WsbAffirmHr(pWsbEnum->Init((IWsbCollection*) m_pCollection));
  55. // It should reference the same item in the collection.
  56. WsbAffirmHr(pWsbEnum->SkipTo(m_currentIndex));
  57. *ppEnum = pWsbEnum;
  58. pWsbEnum.p->AddRef();
  59. } WsbCatch(hr);
  60. WsbTraceOut(OLESTR("CWsbIndexedEnum::Clone(IWbEnumEx)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  61. return(hr);
  62. }
  63. HRESULT
  64. CWsbIndexedEnum::Clone(
  65. OUT IEnumUnknown** ppEnum
  66. )
  67. /*++
  68. Implements:
  69. IEnumUknown::Clone
  70. --*/
  71. {
  72. HRESULT hr = S_OK;
  73. CComPtr<IWsbEnum> pWsbEnum;
  74. WsbTraceIn(OLESTR("CWsbIndexedEnum::Clone(IEnumUnknown)"), OLESTR(""));
  75. try {
  76. // This does the major part of the work.
  77. WsbAffirmHr(Clone(&pWsbEnum));
  78. // Now get them the interace that they wanted.
  79. WsbAffirmHr(pWsbEnum->QueryInterface(IID_IEnumUnknown, (void**) ppEnum));
  80. } WsbCatch(hr);
  81. WsbTraceOut(OLESTR("CWsbIndexedEnum::Clone(IEnumUnknown)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  82. return(hr);
  83. }
  84. #pragma optimize("g", off)
  85. HRESULT
  86. CWsbIndexedEnum::FinalConstruct(
  87. void
  88. )
  89. /*++
  90. Implements:
  91. CComObjectRoot::FinalConstruct
  92. --*/
  93. {
  94. HRESULT hr = S_OK;
  95. try {
  96. WsbAffirmHr(CComObjectRoot::FinalConstruct());
  97. m_currentIndex = 0;
  98. } WsbCatch(hr);
  99. return(hr);
  100. }
  101. #pragma optimize("", on)
  102. HRESULT
  103. CWsbIndexedEnum::Find(
  104. IN IUnknown* pCollectable,
  105. IN REFIID riid,
  106. OUT void** ppElement
  107. )
  108. /*++
  109. Implements:
  110. IWsbEnum::Find
  111. --*/
  112. {
  113. HRESULT hr = S_OK;
  114. ULONG elementsFetched;
  115. WsbTraceIn(OLESTR("CWsbIndexedEnum::Find(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  116. try {
  117. hr = m_pCollection->CopyIfMatches(WSB_COLLECTION_MIN_INDEX, WSB_COLLECTION_MAX_INDEX, pCollectable, 1, riid, ppElement, &elementsFetched, &m_currentIndex);
  118. } WsbCatch(hr);
  119. WsbTraceOut(OLESTR("CWsbIndexedEnum::Find(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  120. return(hr);
  121. }
  122. HRESULT
  123. CWsbIndexedEnum::Find(
  124. IN IUnknown* pCollectable,
  125. IN ULONG element,
  126. IN REFIID riid,
  127. OUT void** elements,
  128. OUT ULONG* pElementsFetched
  129. )
  130. /*++
  131. Implements:
  132. IWsbEnumEx::Find
  133. --*/
  134. {
  135. HRESULT hr = S_OK;
  136. WsbTraceIn(OLESTR("CWsbIndexedEnum::Find(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  137. try {
  138. hr = m_pCollection->CopyIfMatches(WSB_COLLECTION_MIN_INDEX, WSB_COLLECTION_MAX_INDEX, pCollectable, element, riid, elements, pElementsFetched, &m_currentIndex);
  139. } WsbCatch(hr);
  140. WsbTraceOut(OLESTR("CWsbIndexedEnum::Find(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%ls>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  141. return(hr);
  142. }
  143. HRESULT
  144. CWsbIndexedEnum::FindNext(
  145. IN IUnknown* pCollectable,
  146. IN REFIID riid,
  147. OUT void** ppElement
  148. )
  149. /*++
  150. Implements:
  151. IWsbEnum::FindNext
  152. --*/
  153. {
  154. HRESULT hr = S_OK;
  155. ULONG elementsFetched;
  156. WsbTraceIn(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  157. try {
  158. // If we are already at the end of the list, then you can't go any
  159. // further.
  160. WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
  161. hr = m_pCollection->CopyIfMatches(m_currentIndex + 1, WSB_COLLECTION_MAX_INDEX, pCollectable, 1, riid, ppElement, &elementsFetched, &m_currentIndex);
  162. } WsbCatch(hr);
  163. WsbTraceOut(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  164. return(hr);
  165. }
  166. HRESULT
  167. CWsbIndexedEnum::FindNext(
  168. IN IUnknown* pCollectable,
  169. IN ULONG element,
  170. IN REFIID riid,
  171. OUT void** elements,
  172. OUT ULONG* pElementsFetched
  173. )
  174. /*++
  175. Implements:
  176. IWsbEnumEx::FindNext
  177. --*/
  178. {
  179. HRESULT hr = S_OK;
  180. WsbTraceIn(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  181. try {
  182. // If we are already at the end of the list, then you can't go any
  183. // further.
  184. WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
  185. hr = m_pCollection->CopyIfMatches(m_currentIndex + 1, WSB_COLLECTION_MAX_INDEX, pCollectable, element, riid, elements, pElementsFetched, &m_currentIndex);
  186. } WsbCatch(hr);
  187. WsbTraceOut(OLESTR("CWsbIndexedEnum::FindNext(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%ls>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  188. return(hr);
  189. }
  190. HRESULT
  191. CWsbIndexedEnum::FindPrevious(
  192. IN IUnknown* pCollectable,
  193. IN REFIID riid,
  194. OUT void** ppElement
  195. )
  196. /*++
  197. Implements:
  198. IWsbEnum::FindPrevious
  199. --*/
  200. {
  201. HRESULT hr = S_OK;
  202. ULONG elementsFetched;
  203. WsbTraceIn(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  204. try {
  205. // If we are already at the beginning of the list, then you can't go any
  206. // further.
  207. WsbAffirm(WSB_COLLECTION_MIN_INDEX != m_currentIndex, WSB_E_NOTFOUND);
  208. hr = m_pCollection->CopyIfMatches(m_currentIndex - 1, WSB_COLLECTION_MIN_INDEX, pCollectable, 1, riid, ppElement, &elementsFetched, &m_currentIndex);
  209. } WsbCatch(hr);
  210. WsbTraceOut(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  211. return(hr);
  212. }
  213. HRESULT
  214. CWsbIndexedEnum::FindPrevious(
  215. IN IUnknown* pCollectable,
  216. IN ULONG element,
  217. IN REFIID riid,
  218. OUT void** elements,
  219. OUT ULONG* pElementsFetched
  220. )
  221. /*++
  222. Implements:
  223. IWsbEnumEx::FindPrevious
  224. --*/
  225. {
  226. HRESULT hr = S_OK;
  227. WsbTraceIn(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  228. try {
  229. // If we are already at the beginning of the list, then you can't go any
  230. // further.
  231. WsbAffirm(WSB_COLLECTION_MIN_INDEX != m_currentIndex, WSB_E_NOTFOUND);
  232. hr = m_pCollection->CopyIfMatches(m_currentIndex - 1, WSB_COLLECTION_MIN_INDEX, pCollectable, element, riid, elements, pElementsFetched, &m_currentIndex);
  233. } WsbCatch(hr);
  234. WsbTraceOut(OLESTR("CWsbIndexedEnum::FindPrevious(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%ls>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  235. return(hr);
  236. }
  237. HRESULT
  238. CWsbIndexedEnum::First(
  239. IN REFIID riid,
  240. OUT void** ppElement
  241. )
  242. /*++
  243. Implements:
  244. IWsbEnum::First
  245. --*/
  246. {
  247. HRESULT hr = S_OK;
  248. ULONG fetched = 0;
  249. WsbTraceIn(OLESTR("CWsbIndexedEnum::First(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  250. try {
  251. // Since we aren't doing any addition to the number of elements, the
  252. // Copy command does all the range checking that we need.
  253. WsbAffirmHr(m_pCollection->Copy(WSB_COLLECTION_MIN_INDEX, 0, riid, ppElement, &fetched));
  254. // If items were read, then update the current index, and return to
  255. // them the number of elements fetched if they wanted to know.
  256. m_currentIndex = 0;
  257. } WsbCatch(hr);
  258. WsbTraceOut(OLESTR("CWsbIndexedEnum::First(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  259. return(hr);
  260. }
  261. HRESULT
  262. CWsbIndexedEnum::First(
  263. IN ULONG element,
  264. IN REFIID riid,
  265. OUT void** elements,
  266. OUT ULONG* pElementsFetched
  267. )
  268. /*++
  269. Implements:
  270. IWsbEnumEx::First
  271. --*/
  272. {
  273. HRESULT hr = S_OK;
  274. ULONG fetched = 0;
  275. WsbTraceIn(OLESTR("CWsbIndexedEnum::First(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  276. try {
  277. WsbAssert((0 != pElementsFetched), E_POINTER);
  278. // Since we aren't doing any addition to the number of elements, the
  279. // Copy command does all the range checking that we need.
  280. WsbAffirmHr(m_pCollection->Copy(WSB_COLLECTION_MIN_INDEX, element - 1, riid, elements, &fetched));
  281. // If items were read, then update the current index, and return to
  282. // them the number of elements fetched if they wanted to know.
  283. m_currentIndex = fetched - 1;
  284. *pElementsFetched = fetched;
  285. } WsbCatch(hr);
  286. WsbTraceOut(OLESTR("CWsbIndexedEnum::First(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), fetched);
  287. return(hr);
  288. }
  289. HRESULT
  290. CWsbIndexedEnum::Init(
  291. IN IWsbCollection* pCollection
  292. )
  293. /*++
  294. Implements:
  295. IWsbEnum::Init
  296. --*/
  297. {
  298. HRESULT hr = S_OK;
  299. WsbTraceIn(OLESTR("CWsbIndexedEnum::Init"), OLESTR(""));
  300. try {
  301. WsbAssert(0 != pCollection, E_POINTER);
  302. // Only let them initialize the enumeration once.
  303. WsbAssert(m_pCollection == 0, S_FALSE);
  304. // Since this enum is for indexed collections, get an indexed
  305. // interface to it.
  306. WsbAffirmHr(pCollection->QueryInterface(IID_IWsbIndexedCollection, (void**) &m_pCollection));
  307. } WsbCatch(hr);
  308. WsbTraceOut(OLESTR("CWsbIndexedEnum::Init"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  309. return(hr);
  310. };
  311. HRESULT
  312. CWsbIndexedEnum::Last(
  313. IN REFIID riid,
  314. OUT void** ppElement
  315. )
  316. /*++
  317. Implements:
  318. IWsbEnum::Last
  319. --*/
  320. {
  321. HRESULT hr = S_OK;
  322. ULONG entries;
  323. ULONG fetched;
  324. WsbTraceIn(OLESTR("CWsbIndexedEnum::Last(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  325. try {
  326. // Find out where the end is located.
  327. WsbAffirmHr(m_pCollection->GetEntries(&entries));
  328. // We must have some entries.
  329. WsbAffirm(entries != 0, WSB_E_NOTFOUND);
  330. WsbAffirmHr(m_pCollection->Copy(entries - 1, entries - 1, riid, ppElement, &fetched));
  331. // If items were read, then update the current index, and return to
  332. // them the number of elements fetched if they wanted to know.
  333. m_currentIndex = entries - fetched;
  334. } WsbCatch(hr);
  335. WsbTraceOut(OLESTR("CWsbIndexedEnum::Last(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  336. return(hr);
  337. }
  338. HRESULT
  339. CWsbIndexedEnum::Last(
  340. IN ULONG element,
  341. IN REFIID riid,
  342. OUT void** elements,
  343. OUT ULONG* pElementsFetched
  344. )
  345. /*++
  346. Implements:
  347. IWsbEnumEx::Last
  348. --*/
  349. {
  350. HRESULT hr = S_OK;
  351. ULONG entries;
  352. ULONG fetched;
  353. WsbTraceIn(OLESTR("CWsbIndexedEnum::Last(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  354. try {
  355. WsbAssertPointer(pElementsFetched);
  356. // Find out where the end is located.
  357. WsbAffirmHr(m_pCollection->GetEntries(&entries));
  358. // We must have some entries.
  359. WsbAffirm(entries != 0, WSB_E_NOTFOUND);
  360. // If they have asked for more elements than could be represented by
  361. // then index, then don't let the index wrap around.
  362. if (element > entries) {
  363. WsbAffirmHr(m_pCollection->Copy(entries - 1, WSB_COLLECTION_MIN_INDEX, riid, elements, &fetched));
  364. // Let them know that they didn't get all the items they requested.
  365. hr = S_FALSE;
  366. } else {
  367. WsbAffirmHr(m_pCollection->Copy(entries - 1, entries - element, riid, elements, &fetched));
  368. }
  369. // If items were read, then update the current index, and return to
  370. // them the number of elements fetched if they wanted to know.
  371. m_currentIndex = entries - fetched;
  372. *pElementsFetched = fetched;
  373. } WsbCatch(hr);
  374. WsbTraceOut(OLESTR("CWsbIndexedEnum::Last(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  375. return(hr);
  376. }
  377. HRESULT
  378. CWsbIndexedEnum::Next(
  379. IN ULONG element,
  380. OUT IUnknown** elements,
  381. OUT ULONG* pElementsFetched
  382. )
  383. /*++
  384. Implements:
  385. IEnumUknown::Next
  386. --*/
  387. {
  388. HRESULT hr = S_OK;
  389. WsbTraceIn(OLESTR("CWsbIndexedEnum::Next(IEnumUnknown)"), OLESTR("element = <%lu>"), element);
  390. hr = Next(element, IID_IUnknown, (void**) elements, pElementsFetched);
  391. WsbTraceOut(OLESTR("CWsbIndexedEnum::Next(IEnumUnknown)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  392. return(hr);
  393. }
  394. HRESULT
  395. CWsbIndexedEnum::Next(
  396. IN REFIID riid,
  397. OUT void** ppElement
  398. )
  399. /*++
  400. Implements:
  401. IWsbEnum::Next
  402. --*/
  403. {
  404. HRESULT hr = S_OK;
  405. ULONG fetched;
  406. WsbTraceIn(OLESTR("CWsbIndexedEnum::Next(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  407. try {
  408. // If we are already at the end of the list, then you can't go any
  409. // further.
  410. WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
  411. WsbAffirmHr(m_pCollection->Copy(m_currentIndex + 1, m_currentIndex + 1, riid, ppElement, &fetched));
  412. m_currentIndex += fetched;
  413. } WsbCatch(hr);
  414. WsbTraceOut(OLESTR("CWsbIndexedEnum::Next(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  415. return(hr);
  416. }
  417. HRESULT
  418. CWsbIndexedEnum::Next(
  419. IN ULONG element,
  420. IN REFIID riid,
  421. OUT void** elements,
  422. OUT ULONG* pElementsFetched
  423. )
  424. /*++
  425. Implements:
  426. IWsbEnumEx::Next
  427. --*/
  428. {
  429. HRESULT hr = S_OK;
  430. ULONG fetched;
  431. WsbTraceIn(OLESTR("CWsbIndexedEnum::Next(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  432. try {
  433. WsbAssert(0 != element, E_INVALIDARG);
  434. WsbAssertPointer(pElementsFetched);
  435. // If we are already at the end of the list, then you can't go any
  436. // further.
  437. WsbAffirm(WSB_COLLECTION_MAX_INDEX != m_currentIndex, WSB_E_NOTFOUND);
  438. // If they have asked for more elements than could be represented by
  439. // then index, then don't let the index wrap around.
  440. if ((WSB_COLLECTION_MAX_INDEX - m_currentIndex) < element) {
  441. WsbAffirmHr(m_pCollection->Copy(m_currentIndex + 1, WSB_COLLECTION_MAX_INDEX, riid, elements, &fetched));
  442. // Let them know that they didn't get all the items they requested.
  443. hr = S_FALSE;
  444. } else {
  445. WsbAffirmHr(m_pCollection->Copy(m_currentIndex + 1, m_currentIndex + element, riid, elements, &fetched));
  446. }
  447. m_currentIndex += fetched;
  448. *pElementsFetched = fetched;
  449. } WsbCatch(hr);
  450. WsbTraceOut(OLESTR("CWsbIndexedEnum::Next(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  451. return(hr);
  452. }
  453. HRESULT
  454. CWsbIndexedEnum::Previous(
  455. IN REFIID riid,
  456. OUT void** ppElement
  457. )
  458. /*++
  459. Implements:
  460. IWsbEnum::Previous
  461. --*/
  462. {
  463. HRESULT hr = S_OK;
  464. ULONG fetched;
  465. WsbTraceIn(OLESTR("CWsbIndexedEnum::Previous(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  466. try {
  467. // If we are already at the beginning of the list, then you can't go any
  468. // further.
  469. WsbAffirm(m_currentIndex != WSB_COLLECTION_MIN_INDEX, WSB_E_NOTFOUND);
  470. WsbAffirmHr(m_pCollection->Copy(m_currentIndex - 1, m_currentIndex - 1, riid, ppElement, &fetched));
  471. m_currentIndex -= fetched;
  472. } WsbCatch(hr);
  473. WsbTraceOut(OLESTR("CWsbIndexedEnum::Previous(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  474. return(hr);
  475. }
  476. HRESULT
  477. CWsbIndexedEnum::Previous(
  478. IN ULONG element,
  479. IN REFIID riid,
  480. OUT void** elements,
  481. IN ULONG* pElementsFetched
  482. )
  483. /*++
  484. Implements:
  485. IWsbEnum::Previous
  486. --*/
  487. {
  488. HRESULT hr = S_OK;
  489. ULONG fetched;
  490. WsbTraceIn(OLESTR("CWsbIndexedEnum::Previous(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  491. try {
  492. WsbAssertPointer(pElementsFetched);
  493. // If we are already at the beginning of the list, then you can't go any
  494. // further.
  495. WsbAffirm(m_currentIndex != WSB_COLLECTION_MIN_INDEX, WSB_E_NOTFOUND);
  496. // If they have asked for more elements than are before us in the
  497. // collection, then don't let the index wrap around.
  498. if (m_currentIndex < element) {
  499. WsbAffirmHr(m_pCollection->Copy(m_currentIndex - 1, WSB_COLLECTION_MIN_INDEX, riid, elements, &fetched));
  500. // Let them know that they didn't get all the items they requested.
  501. hr = S_FALSE;
  502. } else {
  503. WsbAffirmHr(m_pCollection->Copy(m_currentIndex - 1, m_currentIndex - element, riid, elements, &fetched));
  504. }
  505. m_currentIndex -= fetched;
  506. *pElementsFetched = fetched;
  507. } WsbCatch(hr);
  508. WsbTraceOut(OLESTR("CWsbIndexedEnum::Previous(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  509. return(hr);
  510. }
  511. HRESULT
  512. CWsbIndexedEnum::Reset(
  513. void
  514. )
  515. /*++
  516. Implements:
  517. IEnumUnknown::Reset
  518. --*/
  519. {
  520. HRESULT hr = S_OK;
  521. WsbTraceIn(OLESTR("CWsbIndexedEnum::Reset"), OLESTR(""));
  522. hr = SkipToFirst();
  523. WsbTraceOut(OLESTR("CWsbIndexedEnum::Reset"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  524. return(S_OK);
  525. }
  526. HRESULT
  527. CWsbIndexedEnum::Skip(
  528. IN ULONG element
  529. )
  530. /*++
  531. Implements:
  532. IEnumUnknown::Skip
  533. --*/
  534. {
  535. HRESULT hr = S_OK;
  536. WsbTraceIn(OLESTR("CWsbIndexedEnum::Skip"), OLESTR("element = <%lu>"), element);
  537. hr = SkipNext(element);
  538. WsbTraceOut(OLESTR("CWsbIndexedEnum::Skip"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  539. return(hr);
  540. }
  541. HRESULT
  542. CWsbIndexedEnum::SkipNext(
  543. IN ULONG element
  544. )
  545. /*++
  546. Implements:
  547. IWsbEnum::SkipNext
  548. --*/
  549. {
  550. HRESULT hr = S_OK;
  551. ULONG entries;
  552. WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipNext"), OLESTR("element = <%lu>"), element);
  553. try {
  554. // Find out where the end is located.
  555. WsbAffirmHr(m_pCollection->GetEntries(&entries));
  556. // If there aren't any entries, then put it at the beginning
  557. // and let them no it was empty.
  558. if (0 == entries) {
  559. hr = S_FALSE;
  560. m_currentIndex = WSB_COLLECTION_MIN_INDEX;
  561. }
  562. // Are we already at the end of the list, or have they requested
  563. // to go beyond the end of the list?
  564. else if ((m_currentIndex >= (entries - 1)) ||
  565. ((entries - m_currentIndex) < element)) {
  566. hr = S_FALSE;
  567. m_currentIndex = entries - 1;
  568. }
  569. // They asked for something legal.
  570. else {
  571. m_currentIndex += element;
  572. }
  573. } WsbCatch(hr);
  574. WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipNext"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  575. return(hr);
  576. }
  577. HRESULT
  578. CWsbIndexedEnum::SkipPrevious(
  579. IN ULONG element
  580. )
  581. /*++
  582. Implements:
  583. IWsbEnum::SkipPrevious
  584. --*/
  585. {
  586. HRESULT hr = S_OK;
  587. WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipPrevious"), OLESTR("element = <%lu>"), element);
  588. // If we are already at the beginning of the list, then you can't go any
  589. // further.
  590. if (m_currentIndex == WSB_COLLECTION_MIN_INDEX) {
  591. hr = S_FALSE;
  592. }
  593. // If they have asked for more elements than could be represented by
  594. // then index, then don't let the index wrap around.
  595. else if (m_currentIndex < element) {
  596. m_currentIndex = WSB_COLLECTION_MIN_INDEX;
  597. // Let them know that they didn't get all the items they requested.
  598. hr = S_FALSE;
  599. }
  600. // They asked for something legal.
  601. else {
  602. m_currentIndex -= element;
  603. }
  604. WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipPrevious"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  605. return(hr);
  606. }
  607. HRESULT
  608. CWsbIndexedEnum::SkipTo(
  609. IN ULONG index
  610. )
  611. /*++
  612. Implements:
  613. IWsbEnum::SkipTo
  614. --*/
  615. {
  616. HRESULT hr = S_OK;
  617. ULONG entries;
  618. WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipToIndex"), OLESTR("index = <%lu>"), index);
  619. try {
  620. // Find out where the end is located.
  621. WsbAffirmHr(m_pCollection->GetEntries(&entries));
  622. // If there aren't any entries, then put it at the beginning
  623. // and let them no it was empty.
  624. if (0 == entries) {
  625. hr = S_FALSE;
  626. m_currentIndex = WSB_COLLECTION_MIN_INDEX;
  627. }
  628. // They asked for something beyond the end of the collection, so
  629. // put them at the end of the collection and let them now there
  630. // was a problem.
  631. else if (index > (entries - 1)) {
  632. hr = S_FALSE;
  633. m_currentIndex = entries - 1;
  634. }
  635. // They asked for something legal.
  636. else {
  637. m_currentIndex = index;
  638. }
  639. } WsbCatch(hr);
  640. WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipToIndex"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  641. return(hr);
  642. }
  643. HRESULT
  644. CWsbIndexedEnum::SkipToFirst(
  645. void
  646. )
  647. /*++
  648. Implements:
  649. IWsbEnum::SkipToFirst
  650. --*/
  651. {
  652. HRESULT hr = S_OK;
  653. ULONG entries;
  654. WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipToFirst"), OLESTR(""));
  655. try {
  656. // Find out where the end is located.
  657. WsbAffirmHr(m_pCollection->GetEntries(&entries));
  658. // If there aren't any entries, then put it at the beginning
  659. // and let them no it was empty.
  660. if (0 == entries) {
  661. hr = S_FALSE;
  662. }
  663. m_currentIndex = WSB_COLLECTION_MIN_INDEX;
  664. } WsbCatch(hr);
  665. WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipToFirst"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  666. return(hr);
  667. }
  668. HRESULT
  669. CWsbIndexedEnum::SkipToLast(
  670. void
  671. )
  672. /*++
  673. Implements:
  674. IWsbEnum::SkipToLast
  675. --*/
  676. {
  677. HRESULT hr = S_OK;
  678. ULONG entries;
  679. WsbTraceIn(OLESTR("CWsbIndexedEnum::SkipToLast"), OLESTR(""));
  680. try {
  681. // Find out where the end is located.
  682. WsbAffirmHr(m_pCollection->GetEntries(&entries));
  683. // If there aren't any entries, then put it at the beginning
  684. // and let them no it was empty.
  685. if (0 == entries) {
  686. hr = S_FALSE;
  687. m_currentIndex = WSB_COLLECTION_MIN_INDEX;
  688. }
  689. // They asked for something legal.
  690. else {
  691. m_currentIndex = entries - 1;
  692. }
  693. } WsbCatch(hr);
  694. WsbTraceOut(OLESTR("CWsbIndexedEnum::SkipToLast"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  695. return(hr);
  696. }
  697. HRESULT
  698. CWsbIndexedEnum::This(
  699. IN REFIID riid,
  700. OUT void** ppElement
  701. )
  702. /*++
  703. Implements:
  704. IWsbEnum::This
  705. --*/
  706. {
  707. HRESULT hr = S_OK;
  708. ULONG fetched;
  709. WsbTraceIn(OLESTR("CWsbIndexedEnum::This(IWsbEnum)"), OLESTR("riid = <%ls>"), WsbGuidAsString(riid));
  710. try {
  711. WsbAssert(0 != ppElement, E_POINTER);
  712. WsbAffirmHr(m_pCollection->Copy(m_currentIndex, m_currentIndex, riid, ppElement, &fetched));
  713. } WsbCatch(hr);
  714. WsbTraceOut(OLESTR("CWsbIndexedEnum::This(IWsbEnum)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  715. return(hr);
  716. }
  717. HRESULT
  718. CWsbIndexedEnum::This(
  719. IN ULONG element,
  720. IN REFIID riid,
  721. OUT void** elements,
  722. OUT ULONG* pElementsFetched
  723. )
  724. /*++
  725. Implements:
  726. IWsbEnum::This
  727. --*/
  728. {
  729. HRESULT hr = S_OK;
  730. ULONG fetched;
  731. WsbTraceIn(OLESTR("CWsbIndexedEnum::This(IWsbEnumEx)"), OLESTR("element = <%lu>, riid = <%ls>"), element, WsbGuidAsString(riid));
  732. try {
  733. WsbAssert(0 != element, E_INVALIDARG);
  734. WsbAssertPointer(elements);
  735. WsbAssertPointer(pElementsFetched);
  736. // If they have asked for more elements than could be represented by
  737. // then index, then don't let the index wrap around.
  738. if ((WSB_COLLECTION_MAX_INDEX - m_currentIndex) <= element) {
  739. WsbAffirmHr(m_pCollection->Copy(m_currentIndex, WSB_COLLECTION_MAX_INDEX, riid, elements, &fetched));
  740. // Let them know that they didn't get all the items they requested.
  741. hr = S_FALSE;
  742. } else {
  743. WsbAffirmHr(m_pCollection->Copy(m_currentIndex, m_currentIndex + element - 1, riid, elements, &fetched));
  744. }
  745. *pElementsFetched = fetched - 1;
  746. } WsbCatch(hr);
  747. WsbTraceOut(OLESTR("CWsbIndexedEnum::This(IWsbEnumEx)"), OLESTR("hr = <%ls>, fetched = <%lu>"), WsbHrAsString(hr), WsbPtrToUlongAsString(pElementsFetched));
  748. return(hr);
  749. }