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.

165 lines
3.8 KiB

  1. //
  2. // sunka.cpp
  3. //
  4. // CEnumUnknown
  5. //
  6. #include "private.h"
  7. #include "sunka.h"
  8. //////////////////////////////////////////////////////////////////////////////
  9. //////////////////////////////////////////////////////////////////////////////
  10. //
  11. // SHARED_UNKNOWN_ARRAY
  12. //
  13. //////////////////////////////////////////////////////////////////////////////
  14. //////////////////////////////////////////////////////////////////////////////
  15. //+---------------------------------------------------------------------------
  16. //
  17. // SUA_Init
  18. //
  19. //----------------------------------------------------------------------------
  20. SHARED_UNKNOWN_ARRAY *SUA_Init(ULONG cUnk, IUnknown **prgUnk)
  21. {
  22. SHARED_UNKNOWN_ARRAY *pua;
  23. pua = (SHARED_UNKNOWN_ARRAY *)cicMemAlloc(sizeof(SHARED_UNKNOWN_ARRAY)+sizeof(IUnknown)*cUnk-sizeof(IUnknown));
  24. if (pua == NULL)
  25. return NULL;
  26. pua->cRef = 1;
  27. pua->cUnk = cUnk;
  28. while (cUnk-- > 0)
  29. {
  30. pua->rgUnk[cUnk] = prgUnk[cUnk];
  31. pua->rgUnk[cUnk]->AddRef();
  32. }
  33. return pua;
  34. }
  35. //+---------------------------------------------------------------------------
  36. //
  37. // SUA_Release
  38. //
  39. //----------------------------------------------------------------------------
  40. void SUA_Release(SHARED_UNKNOWN_ARRAY *pua)
  41. {
  42. ULONG i;
  43. Assert(pua->cRef > 0);
  44. if (--pua->cRef == 0)
  45. {
  46. for (i=0; i<pua->cUnk; i++)
  47. {
  48. SafeRelease(pua->rgUnk[i]);
  49. }
  50. cicMemFree(pua);
  51. }
  52. }
  53. //////////////////////////////////////////////////////////////////////////////
  54. //////////////////////////////////////////////////////////////////////////////
  55. //
  56. // CEnumUnknown
  57. //
  58. //////////////////////////////////////////////////////////////////////////////
  59. //////////////////////////////////////////////////////////////////////////////
  60. //+---------------------------------------------------------------------------
  61. //
  62. // dtor
  63. //
  64. //----------------------------------------------------------------------------
  65. CEnumUnknown::~CEnumUnknown()
  66. {
  67. if (_prgUnk != NULL)
  68. {
  69. SUA_Release(_prgUnk);
  70. }
  71. }
  72. //+---------------------------------------------------------------------------
  73. //
  74. // Clone
  75. //
  76. //----------------------------------------------------------------------------
  77. void CEnumUnknown::Clone(CEnumUnknown *pClone)
  78. {
  79. pClone->_iCur = _iCur;
  80. pClone->_prgUnk = _prgUnk;
  81. SUA_AddRef(pClone->_prgUnk);
  82. }
  83. //+---------------------------------------------------------------------------
  84. //
  85. // Next
  86. //
  87. //----------------------------------------------------------------------------
  88. HRESULT CEnumUnknown::Next(ULONG ulCount, IUnknown **ppUnk, ULONG *pcFetched)
  89. {
  90. ULONG cFetched;
  91. if (ulCount > 0 && ppUnk == NULL)
  92. return E_INVALIDARG;
  93. if (pcFetched == NULL)
  94. {
  95. pcFetched = &cFetched;
  96. }
  97. *pcFetched = 0;
  98. while ((ULONG)_iCur < _prgUnk->cUnk && *pcFetched < ulCount)
  99. {
  100. *ppUnk = _prgUnk->rgUnk[_iCur];
  101. (*ppUnk)->AddRef();
  102. ppUnk++;
  103. *pcFetched = *pcFetched + 1;
  104. _iCur++;
  105. }
  106. return *pcFetched == ulCount ? S_OK : S_FALSE;
  107. }
  108. //+---------------------------------------------------------------------------
  109. //
  110. // Reset
  111. //
  112. //----------------------------------------------------------------------------
  113. HRESULT CEnumUnknown::Reset()
  114. {
  115. _iCur = 0;
  116. return S_OK;
  117. }
  118. //+---------------------------------------------------------------------------
  119. //
  120. // Skip
  121. //
  122. //----------------------------------------------------------------------------
  123. HRESULT CEnumUnknown::Skip(ULONG ulCount)
  124. {
  125. _iCur += ulCount;
  126. if ((ULONG)_iCur >= _prgUnk->cUnk)
  127. {
  128. _iCur = _prgUnk->cUnk; // prevent overflow for repeated calls
  129. return S_FALSE;
  130. }
  131. return S_OK;
  132. }