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.

328 lines
8.8 KiB

  1. // --------------------------------------------------------------------------------
  2. // Enumhead.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "dllmain.h"
  7. #include "enumhead.h"
  8. #include "olealloc.h"
  9. #include "symcache.h"
  10. #include "demand.h"
  11. // ---------------------------------------------------------------------------
  12. // CMimeEnumHeaderRows::CMimeEnumHeaderRows
  13. // ---------------------------------------------------------------------------
  14. CMimeEnumHeaderRows::CMimeEnumHeaderRows(void)
  15. {
  16. DllAddRef();
  17. m_cRef = 1;
  18. m_ulIndex = 0;
  19. m_cRows = 0;
  20. m_prgRow = NULL;
  21. m_dwFlags = 0;
  22. InitializeCriticalSection(&m_cs);
  23. }
  24. // ---------------------------------------------------------------------------
  25. // CMimeEnumHeaderRows::~CMimeEnumHeaderRows
  26. // ---------------------------------------------------------------------------
  27. CMimeEnumHeaderRows::~CMimeEnumHeaderRows(void)
  28. {
  29. g_pMoleAlloc->FreeEnumHeaderRowArray(m_cRows, m_prgRow, TRUE);
  30. DeleteCriticalSection(&m_cs);
  31. DllRelease();
  32. }
  33. // ---------------------------------------------------------------------------
  34. // CMimeEnumHeaderRows::QueryInterface
  35. // ---------------------------------------------------------------------------
  36. STDMETHODIMP CMimeEnumHeaderRows::QueryInterface(REFIID riid, LPVOID *ppv)
  37. {
  38. // check params
  39. if (ppv == NULL)
  40. return TrapError(E_INVALIDARG);
  41. // Find IID
  42. if (IID_IUnknown == riid)
  43. *ppv = (IUnknown *)(IMimeEnumHeaderRows *)this;
  44. else if (IID_IMimeEnumHeaderRows == riid)
  45. *ppv = (IMimeEnumHeaderRows *)this;
  46. else
  47. {
  48. *ppv = NULL;
  49. return TrapError(E_NOINTERFACE);
  50. }
  51. // AddRef It
  52. ((IUnknown *)*ppv)->AddRef();
  53. // Done
  54. return S_OK;
  55. }
  56. // ---------------------------------------------------------------------------
  57. // CMimeEnumHeaderRows::AddRef
  58. // ---------------------------------------------------------------------------
  59. STDMETHODIMP_(ULONG) CMimeEnumHeaderRows::AddRef(void)
  60. {
  61. return (ULONG)InterlockedIncrement(&m_cRef);
  62. }
  63. // ---------------------------------------------------------------------------
  64. // CMimeEnumHeaderRows::Release
  65. // ---------------------------------------------------------------------------
  66. STDMETHODIMP_(ULONG) CMimeEnumHeaderRows::Release(void)
  67. {
  68. LONG cRef = InterlockedDecrement(&m_cRef);
  69. if (0 == cRef)
  70. delete this;
  71. return (ULONG)cRef;
  72. }
  73. // ---------------------------------------------------------------------------
  74. // CMimeEnumHeaderRows::Next
  75. // ---------------------------------------------------------------------------
  76. STDMETHODIMP CMimeEnumHeaderRows::Next(ULONG cWanted, LPENUMHEADERROW prgRow, ULONG *pcFetched)
  77. {
  78. // Locals
  79. HRESULT hr=S_OK;
  80. ULONG cFetch=0,
  81. ulIndex=0;
  82. LPPROPSYMBOL pSymbol;
  83. // Thread Safety
  84. EnterCriticalSection(&m_cs);
  85. // Init
  86. if (pcFetched)
  87. *pcFetched = 0;
  88. // No Internal Formats
  89. if (NULL == m_prgRow || NULL == prgRow)
  90. goto exit;
  91. // Compute number to fetch
  92. cFetch = min(cWanted, m_cRows - m_ulIndex);
  93. if (0 == cFetch)
  94. goto exit;
  95. // Init the array
  96. ZeroMemory(prgRow, sizeof(ENUMHEADERROW) * cWanted);
  97. // Copy cWanted
  98. for (ulIndex=0; ulIndex<cFetch; ulIndex++)
  99. {
  100. // Do Enumerating Only Handles
  101. if (!ISFLAGSET(m_dwFlags, HTF_ENUMHANDLESONLY))
  102. {
  103. // Cast symbol
  104. pSymbol = (LPPROPSYMBOL)m_prgRow[m_ulIndex].dwReserved;
  105. // Dup the Header Name
  106. CHECKALLOC(prgRow[ulIndex].pszHeader = PszDupA(pSymbol->pszName));
  107. // pszData
  108. if (m_prgRow[m_ulIndex].pszData)
  109. CHECKALLOC(prgRow[ulIndex].pszData = PszDupA(m_prgRow[m_ulIndex].pszData));
  110. // Size of Data
  111. prgRow[ulIndex].cchData = m_prgRow[m_ulIndex].cchData;
  112. }
  113. // Handle
  114. prgRow[ulIndex].hRow = m_prgRow[m_ulIndex].hRow;
  115. // Goto Next
  116. m_ulIndex++;
  117. }
  118. // Return fetced ?
  119. if (pcFetched)
  120. *pcFetched = cFetch;
  121. exit:
  122. // Failure
  123. if (FAILED(hr) && prgRow)
  124. g_pMoleAlloc->FreeEnumHeaderRowArray(cFetch, prgRow, FALSE);
  125. // Thread Safety
  126. LeaveCriticalSection(&m_cs);
  127. // Done
  128. return (cFetch == cWanted) ? S_OK : S_FALSE;
  129. }
  130. // ---------------------------------------------------------------------------
  131. // CMimeEnumHeaderRows::Skip
  132. // ---------------------------------------------------------------------------
  133. STDMETHODIMP CMimeEnumHeaderRows::Skip(ULONG cSkip)
  134. {
  135. // Locals
  136. HRESULT hr=S_OK;
  137. // Thread Safety
  138. EnterCriticalSection(&m_cs);
  139. // Can we do it...
  140. if (((m_ulIndex + cSkip) >= m_cRows) || NULL == m_prgRow)
  141. {
  142. hr = S_FALSE;
  143. goto exit;
  144. }
  145. // Skip
  146. m_ulIndex += cSkip;
  147. exit:
  148. // Thread Safety
  149. LeaveCriticalSection(&m_cs);
  150. // Done
  151. return hr;
  152. }
  153. // ---------------------------------------------------------------------------
  154. // CMimeEnumHeaderRows::Reset
  155. // ---------------------------------------------------------------------------
  156. STDMETHODIMP CMimeEnumHeaderRows::Reset(void)
  157. {
  158. // Thread Safety
  159. EnterCriticalSection(&m_cs);
  160. // Reset
  161. m_ulIndex = 0;
  162. // Thread Safety
  163. LeaveCriticalSection(&m_cs);
  164. // Done
  165. return S_OK;
  166. }
  167. // ---------------------------------------------------------------------------
  168. // CMimeEnumHeaderRows::Clone
  169. // ---------------------------------------------------------------------------
  170. STDMETHODIMP CMimeEnumHeaderRows::Clone(IMimeEnumHeaderRows **ppEnum)
  171. {
  172. // Locals
  173. HRESULT hr=S_OK;
  174. CMimeEnumHeaderRows *pEnum=NULL;
  175. // check params
  176. if (NULL == ppEnum)
  177. return TrapError(E_INVALIDARG);
  178. // Init
  179. *ppEnum = NULL;
  180. // Thread Safety
  181. EnterCriticalSection(&m_cs);
  182. // Allocate
  183. CHECKALLOC(pEnum = new CMimeEnumHeaderRows());
  184. // Init
  185. CHECKHR(hr = pEnum->HrInit(m_ulIndex, m_dwFlags, m_cRows, m_prgRow, TRUE));
  186. // Retrun
  187. (*ppEnum) = pEnum;
  188. (*ppEnum)->AddRef();
  189. exit:
  190. // Cleanup
  191. SafeRelease(pEnum);
  192. // Thread Safety
  193. LeaveCriticalSection(&m_cs);
  194. // Done
  195. return hr;
  196. }
  197. // ---------------------------------------------------------------------------
  198. // CMimeEnumHeaderRows::Count
  199. // ---------------------------------------------------------------------------
  200. STDMETHODIMP CMimeEnumHeaderRows::Count(ULONG *pcRows)
  201. {
  202. // check params
  203. if (NULL == pcRows)
  204. return TrapError(E_INVALIDARG);
  205. // Thread Safety
  206. EnterCriticalSection(&m_cs);
  207. // Set return
  208. *pcRows = m_cRows;
  209. // Thread Safety
  210. LeaveCriticalSection(&m_cs);
  211. // Done
  212. return S_OK;
  213. }
  214. // ---------------------------------------------------------------------------
  215. // CMimeEnumHeaderRows::HrInit
  216. // ---------------------------------------------------------------------------
  217. HRESULT CMimeEnumHeaderRows::HrInit(ULONG ulIndex, DWORD dwFlags, ULONG cRows, LPENUMHEADERROW prgRow, BOOL fDupArray)
  218. {
  219. // Locals
  220. HRESULT hr=S_OK;
  221. ULONG i;
  222. // Thread Safety
  223. EnterCriticalSection(&m_cs);
  224. // Save Lines
  225. m_ulIndex = ulIndex;
  226. m_cRows = cRows;
  227. m_dwFlags = dwFlags;
  228. // Are there lines ...
  229. if (m_cRows)
  230. {
  231. // Duplicate the Array
  232. if (fDupArray)
  233. {
  234. // Allocate memory
  235. CHECKALLOC(m_prgRow = (LPENUMHEADERROW)g_pMalloc->Alloc(m_cRows * sizeof(ENUMHEADERROW)));
  236. // ZeroInit
  237. ZeroMemory(m_prgRow, sizeof(ENUMHEADERROW) * m_cRows);
  238. // Loop
  239. for (i=0; i<m_cRows; i++)
  240. {
  241. // Take the symbol
  242. m_prgRow[i].dwReserved = prgRow[i].dwReserved;
  243. // Dup the Data
  244. if (prgRow[i].pszData)
  245. {
  246. // Alloc Memory
  247. CHECKALLOC(m_prgRow[i].pszData = (LPSTR)g_pMalloc->Alloc(prgRow[i].cchData + 1));
  248. // Copy the String
  249. CopyMemory(m_prgRow[i].pszData, prgRow[i].pszData, prgRow[i].cchData + 1);
  250. }
  251. // Save the Data Length
  252. m_prgRow[i].cchData = prgRow[i].cchData;
  253. // Save the Handle
  254. m_prgRow[i].hRow = prgRow[i].hRow;
  255. }
  256. }
  257. // Otherwise, just assume this array
  258. else
  259. m_prgRow = prgRow;
  260. }
  261. exit:
  262. // Thread Safety
  263. LeaveCriticalSection(&m_cs);
  264. // Done
  265. return hr;
  266. }