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.

227 lines
5.0 KiB

  1. // --------------------------------------------------------------------------
  2. // Enumfmt.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "enumfmt.h"
  7. #include <BadStrFunctions.h>
  8. //////////////////////////////////////////////////////////////////////////////
  9. //
  10. // CEnumFormatEtc Implementation
  11. //
  12. //////////////////////////////////////////////////////////////////////////////
  13. //
  14. // COMMENTS:
  15. // This class was designed and implemented by Kraig Brockschmidt in
  16. // is book "Inside OLE2". See Chapter 6 "Uniform Data Transfer Using
  17. // Data Objects" for more information.
  18. //
  19. // =================================================================================
  20. // CreateStreamOnHFile
  21. // =================================================================================
  22. OESTDAPI_(HRESULT) CreateEnumFormatEtc(LPUNKNOWN pUnkRef, ULONG celt, PDATAOBJINFO rgInfo, LPFORMATETC rgfe,
  23. IEnumFORMATETC ** lppstmHFile)
  24. {
  25. CEnumFormatEtc * pEnumFmt = NULL;
  26. HRESULT hr = S_OK;
  27. // Check the incoming params
  28. if ((0 == pUnkRef) || (0 == lppstmHFile) || (0 == celt) || ((0 != rgInfo) && (0 != rgfe)))
  29. {
  30. hr = E_INVALIDARG;
  31. goto exit;
  32. }
  33. // Initialize outgoing params
  34. *lppstmHFile = NULL;
  35. // Create the rules manager object
  36. if (NULL != rgInfo)
  37. {
  38. pEnumFmt = new CEnumFormatEtc(pUnkRef, rgInfo, celt);
  39. }
  40. else
  41. {
  42. pEnumFmt = new CEnumFormatEtc(pUnkRef, celt, rgfe);
  43. }
  44. if (NULL == pEnumFmt)
  45. {
  46. hr = E_OUTOFMEMORY;
  47. goto exit;
  48. }
  49. // Get the rules manager interface
  50. hr = pEnumFmt->QueryInterface(IID_IEnumFORMATETC, (void **) lppstmHFile);
  51. if (FAILED(hr))
  52. {
  53. goto exit;
  54. }
  55. pEnumFmt = NULL;
  56. // Set the proper return value
  57. hr = S_OK;
  58. exit:
  59. if (NULL != pEnumFmt)
  60. {
  61. delete pEnumFmt;
  62. }
  63. return hr;
  64. }
  65. CEnumFormatEtc::CEnumFormatEtc(LPUNKNOWN pUnkRef, PDATAOBJINFO rgInfo, ULONG celt)
  66. {
  67. UINT i;
  68. m_cRef = 0;
  69. m_pUnkRef = pUnkRef;
  70. m_iCur = 0;
  71. m_cfe = celt;
  72. m_prgfe = new FORMATETC[(UINT) celt];
  73. if (NULL != m_prgfe)
  74. {
  75. for (i = 0; i < celt; i++)
  76. m_prgfe[i] = rgInfo[i].fe;
  77. }
  78. }
  79. CEnumFormatEtc::CEnumFormatEtc(LPUNKNOWN pUnkRef, ULONG cFE, LPFORMATETC rgfe)
  80. {
  81. UINT i;
  82. m_cRef = 0;
  83. m_pUnkRef = pUnkRef;
  84. m_iCur = 0;
  85. m_cfe = cFE;
  86. m_prgfe = new FORMATETC[(UINT) cFE];
  87. if (NULL != m_prgfe)
  88. {
  89. for (i = 0; i < cFE; i++)
  90. m_prgfe[i] = rgfe[i];
  91. }
  92. }
  93. CEnumFormatEtc::~CEnumFormatEtc(void)
  94. {
  95. if (NULL != m_prgfe)
  96. delete [] m_prgfe;
  97. return;
  98. }
  99. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID* ppv)
  100. {
  101. *ppv = NULL;
  102. //
  103. // Enumerators are separate objects, not the data object, so we
  104. // only need to support our IUnknown and IEnumFORMATETC intefaces
  105. // here with no concern for aggregation.
  106. //
  107. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IEnumFORMATETC))
  108. *ppv = (LPVOID) this;
  109. if (NULL != *ppv)
  110. {
  111. ((LPUNKNOWN) *ppv)->AddRef();
  112. return (NOERROR);
  113. }
  114. return (ResultFromScode(E_NOINTERFACE));
  115. }
  116. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef(void)
  117. {
  118. ++m_cRef;
  119. m_pUnkRef->AddRef();
  120. return (m_cRef);
  121. }
  122. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release(void)
  123. {
  124. ULONG cRefT;
  125. cRefT = --m_cRef;
  126. m_pUnkRef->Release();
  127. if (0 == m_cRef)
  128. delete this;
  129. return (cRefT);
  130. }
  131. STDMETHODIMP CEnumFormatEtc::Next(ULONG cFE, LPFORMATETC pFE, ULONG* pulFE)
  132. {
  133. ULONG cReturn = 0L;
  134. if (NULL == m_prgfe)
  135. return (ResultFromScode(S_FALSE));
  136. if (NULL != pulFE)
  137. *pulFE = 0L;
  138. if (NULL == pFE || m_iCur >= m_cfe)
  139. return ResultFromScode(S_FALSE);
  140. while (m_iCur < m_cfe && cFE > 0)
  141. {
  142. *pFE++ = m_prgfe[m_iCur++];
  143. cReturn++;
  144. cFE--;
  145. }
  146. if (NULL != pulFE)
  147. *pulFE = cReturn;
  148. return (NOERROR);
  149. }
  150. STDMETHODIMP CEnumFormatEtc::Skip(ULONG cSkip)
  151. {
  152. if (((m_iCur + cSkip) >= m_cfe) || NULL == m_prgfe)
  153. return (ResultFromScode(S_FALSE));
  154. m_iCur += cSkip;
  155. return (NOERROR);
  156. }
  157. STDMETHODIMP CEnumFormatEtc::Reset(void)
  158. {
  159. m_iCur = 0;
  160. return (NOERROR);
  161. }
  162. STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC* ppEnum)
  163. {
  164. CEnumFormatEtc* pNew;
  165. *ppEnum = NULL;
  166. // Create the clone.
  167. pNew = new CEnumFormatEtc(m_pUnkRef, m_cfe, m_prgfe);
  168. if (NULL == pNew)
  169. return (ResultFromScode(E_OUTOFMEMORY));
  170. pNew->AddRef();
  171. pNew->m_iCur = m_iCur;
  172. *ppEnum = pNew;
  173. return (NOERROR);
  174. }