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.

185 lines
3.7 KiB

  1. // Implementation of the CEnumString classs
  2. #include "zonepch.h"
  3. // Constructor - destructor.
  4. CEnumString::CEnumString() : m_ref()
  5. {
  6. pFirst = NULL;
  7. pLast = NULL;
  8. pCurrent = NULL;
  9. }
  10. CEnumString::~CEnumString( )
  11. {
  12. // Delete all the strings we created.
  13. ListStr * pNext = pFirst;
  14. while (pNext != NULL)
  15. {
  16. ListStr * pDelete = pNext;
  17. pNext = pNext->pListNext;
  18. LocalFree(pDelete->lpsz);
  19. delete pDelete;
  20. }
  21. }
  22. HRESULT CEnumString::AddString(LPCWSTR lpsz)
  23. {
  24. // First create the element.
  25. ListStr *pListStr = new ListStr;
  26. if (pListStr == NULL)
  27. return E_OUTOFMEMORY;
  28. pListStr->lpsz = StrDup(lpsz);
  29. if (pListStr->lpsz == NULL)
  30. {
  31. delete pListStr;
  32. return E_OUTOFMEMORY;
  33. }
  34. pListStr->pListNext = NULL;
  35. if (pFirst == NULL)
  36. {
  37. TransAssert(pCurrent == NULL);
  38. TransAssert(pLast == NULL);
  39. pFirst = pCurrent = pLast = pListStr;
  40. }
  41. else
  42. {
  43. TransAssert(pLast != NULL);
  44. // We don't support adding strings while an enumeration is on.
  45. TransAssert(pFirst == pCurrent);
  46. pLast->pListNext = pListStr;
  47. pLast = pListStr;
  48. }
  49. return S_OK;
  50. }
  51. // IUnknown methods.
  52. STDMETHODIMP_(ULONG) CEnumString::AddRef( )
  53. {
  54. LONG lRet = ++m_ref;
  55. return lRet;
  56. }
  57. STDMETHODIMP_(ULONG) CEnumString::Release( )
  58. {
  59. LONG lRet = --m_ref;
  60. if (m_ref == 0)
  61. {
  62. delete this;
  63. }
  64. return lRet;
  65. }
  66. STDMETHODIMP CEnumString::QueryInterface(REFIID riid, LPVOID * ppvObj)
  67. {
  68. HRESULT hr = NOERROR;
  69. if ( (riid == IID_IUnknown) || (riid == IID_IEnumString))
  70. {
  71. *ppvObj = this;
  72. AddRef();
  73. }
  74. else
  75. {
  76. *ppvObj = NULL;
  77. hr = E_NOINTERFACE;
  78. }
  79. return hr;
  80. }
  81. // IEnumString methods.
  82. STDMETHODIMP
  83. CEnumString::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
  84. {
  85. HRESULT hr = NOERROR;
  86. ULONG cFound = 0;
  87. // Check the arguments first.
  88. if (celt == 0)
  89. return S_OK;
  90. if (!rgelt)
  91. return E_INVALIDARG;
  92. do
  93. {
  94. if (pCurrent == NULL)
  95. break;
  96. DWORD cChars = lstrlenW(pCurrent->lpsz) + 1;
  97. rgelt[cFound] = (LPOLESTR)CoTaskMemAlloc(cChars * sizeof(OLECHAR));
  98. // If we don't have enough memory don't return anything.
  99. if (rgelt[cFound] == NULL)
  100. {
  101. hr = E_OUTOFMEMORY;
  102. for (DWORD dwIndex = 0 ; dwIndex < cFound ; dwIndex++ )
  103. {
  104. CoTaskMemFree(rgelt[dwIndex]);
  105. rgelt[dwIndex] = 0;
  106. }
  107. }
  108. StrCpyW(rgelt[cFound], pCurrent->lpsz);
  109. pCurrent = pCurrent->pListNext;
  110. cFound++;
  111. } while ( cFound < celt );
  112. if (hr == NOERROR)
  113. {
  114. if (pceltFetched)
  115. *pceltFetched = cFound;
  116. hr = (cFound == celt) ? NOERROR : S_FALSE;
  117. }
  118. return hr;
  119. }
  120. STDMETHODIMP
  121. CEnumString::Skip(ULONG celt)
  122. {
  123. return E_NOTIMPL;
  124. }
  125. STDMETHODIMP
  126. CEnumString::Reset( )
  127. {
  128. pCurrent = pFirst;
  129. return S_OK;
  130. }
  131. STDMETHODIMP
  132. CEnumString::Clone(IEnumString **ppEnumString)
  133. {
  134. // This should be easy to implement if we do a deep copy.
  135. // However we should be able to seperate the list from the
  136. // current pointer and do a much more efficient job.
  137. // Not impl for code complete.
  138. return E_NOTIMPL;
  139. }