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.

137 lines
2.8 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // dsenum.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file defines the class DBEnumerator.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/20/1998 Original version.
  16. // 04/15/1998 Initialize refCount to zero in constructor.
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include <ias.h>
  20. #include <iasutil.h>
  21. #include <dsenum.h>
  22. DBEnumerator::DBEnumerator(DBObject* container, IRowset* members)
  23. : refCount(0),
  24. parent(container),
  25. items(members),
  26. readAccess(createReadAccessor(members))
  27. { }
  28. STDMETHODIMP_(ULONG) DBEnumerator::AddRef()
  29. {
  30. return InterlockedIncrement(&refCount);
  31. }
  32. STDMETHODIMP_(ULONG) DBEnumerator::Release()
  33. {
  34. LONG l = InterlockedDecrement(&refCount);
  35. if (l == 0) { delete this; }
  36. return l;
  37. }
  38. STDMETHODIMP DBEnumerator::QueryInterface(const IID& iid, void** ppv)
  39. {
  40. if (iid == __uuidof(IUnknown))
  41. {
  42. *ppv = static_cast<IUnknown*>(this);
  43. }
  44. else if (iid == __uuidof(IEnumVARIANT))
  45. {
  46. *ppv = static_cast<IEnumVARIANT*>(this);
  47. }
  48. else
  49. {
  50. return E_NOINTERFACE;
  51. }
  52. InterlockedIncrement(&refCount);
  53. return S_OK;
  54. }
  55. STDMETHODIMP DBEnumerator::Next(ULONG celt,
  56. VARIANT* rgVar,
  57. ULONG* pCeltFetched)
  58. {
  59. if (rgVar == NULL) { return E_INVALIDARG; }
  60. //////////
  61. // Initialize the out parameters.
  62. //////////
  63. if (pCeltFetched != NULL) { *pCeltFetched = celt; }
  64. for (ULONG i=0; i<celt; ++i) { VariantInit(rgVar + i); }
  65. try
  66. {
  67. //////////
  68. // Move through the items at most 'celt' times.
  69. //////////
  70. while (celt && items.moveNext())
  71. {
  72. // Get the row data.
  73. items.getData(readAccess, this);
  74. // Never return the root from an enumerator.
  75. if (identity == 1) { continue; }
  76. // Create an object.
  77. V_DISPATCH(rgVar) = parent->spawn(identity, name);
  78. V_VT(rgVar) = VT_DISPATCH;
  79. // Update the state.
  80. --celt;
  81. ++rgVar;
  82. }
  83. }
  84. catch (...)
  85. { }
  86. // Subtract off any elements that weren't fetched.
  87. if (pCeltFetched) { *pCeltFetched -= celt; }
  88. return celt ? S_FALSE : S_OK;
  89. }
  90. STDMETHODIMP DBEnumerator::Skip(ULONG celt)
  91. {
  92. try
  93. {
  94. while (celt && items.moveNext()) { --celt; }
  95. }
  96. CATCH_AND_RETURN()
  97. return celt ? S_FALSE : S_OK;
  98. }
  99. STDMETHODIMP DBEnumerator::Reset()
  100. {
  101. try
  102. {
  103. items.reset();
  104. }
  105. CATCH_AND_RETURN()
  106. return S_OK;
  107. }
  108. STDMETHODIMP DBEnumerator::Clone(IEnumVARIANT** ppEnum)
  109. {
  110. return E_NOTIMPL;
  111. }