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.

304 lines
8.0 KiB

  1. // --------------------------------------------------------------------------------
  2. // AddrEnum.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "dllmain.h"
  7. #include "addrenum.h"
  8. #include "olealloc.h"
  9. #include "addressx.h"
  10. // --------------------------------------------------------------------------------
  11. // CMimeEnumAddressTypes::CMimeEnumAddressTypes
  12. // --------------------------------------------------------------------------------
  13. CMimeEnumAddressTypes::CMimeEnumAddressTypes(void)
  14. {
  15. DllAddRef();
  16. m_cRef = 1;
  17. m_pTable = NULL;
  18. m_iAddress = 0;
  19. ZeroMemory(&m_rList, sizeof(ADDRESSLIST));
  20. InitializeCriticalSection(&m_cs);
  21. }
  22. // --------------------------------------------------------------------------------
  23. // CMimeEnumAddressTypes::~CMimeEnumAddressTypes
  24. // --------------------------------------------------------------------------------
  25. CMimeEnumAddressTypes::~CMimeEnumAddressTypes(void)
  26. {
  27. g_pMoleAlloc->FreeAddressList(&m_rList);
  28. SafeRelease(m_pTable);
  29. DeleteCriticalSection(&m_cs);
  30. DllRelease();
  31. }
  32. // --------------------------------------------------------------------------------
  33. // CMimeEnumAddressTypes::QueryInterface
  34. // --------------------------------------------------------------------------------
  35. STDMETHODIMP CMimeEnumAddressTypes::QueryInterface(REFIID riid, LPVOID *ppv)
  36. {
  37. // check params
  38. if (ppv == NULL)
  39. return TrapError(E_INVALIDARG);
  40. // Find IID
  41. if (IID_IUnknown == riid)
  42. *ppv = (IUnknown *)this;
  43. else if (IID_IMimeEnumAddressTypes == riid)
  44. *ppv = (IMimeEnumAddressTypes *)this;
  45. else
  46. {
  47. *ppv = NULL;
  48. return TrapError(E_NOINTERFACE);
  49. }
  50. // AddRef It
  51. ((IUnknown *)*ppv)->AddRef();
  52. // Done
  53. return S_OK;
  54. }
  55. // --------------------------------------------------------------------------------
  56. // CMimeEnumAddressTypes::QueryInterface
  57. // --------------------------------------------------------------------------------
  58. STDMETHODIMP_(ULONG) CMimeEnumAddressTypes::AddRef(void)
  59. {
  60. return InterlockedIncrement(&m_cRef);
  61. }
  62. // --------------------------------------------------------------------------------
  63. // CMimeEnumAddressTypes::Release
  64. // --------------------------------------------------------------------------------
  65. STDMETHODIMP_(ULONG) CMimeEnumAddressTypes::Release(void)
  66. {
  67. ULONG cRef = InterlockedDecrement(&m_cRef);
  68. if (0 == cRef)
  69. delete this;
  70. return cRef;
  71. }
  72. // --------------------------------------------------------------------------------
  73. // CMimeEnumAddressTypes::Next
  74. // --------------------------------------------------------------------------------
  75. STDMETHODIMP CMimeEnumAddressTypes::Next(ULONG cWanted, LPADDRESSPROPS prgAdr, ULONG *pcFetched)
  76. {
  77. // Locals
  78. HRESULT hr=S_OK;
  79. ULONG cFetch=0,
  80. iAddress=0;
  81. // Thread Safety
  82. EnterCriticalSection(&m_cs);
  83. // Init
  84. if (pcFetched)
  85. *pcFetched = 0;
  86. // No Internal Formats
  87. if (NULL == m_rList.prgAdr)
  88. goto exit;
  89. // Compute number to fetch
  90. cFetch = min(cWanted, m_rList.cAdrs - m_iAddress);
  91. if (0 == cFetch)
  92. goto exit;
  93. // Invalid Arg
  94. if (NULL == prgAdr)
  95. {
  96. hr = TrapError(E_INVALIDARG);
  97. goto exit;
  98. }
  99. // Copy cWanted
  100. for (iAddress=0; iAddress<cFetch; iAddress++)
  101. {
  102. // Zero
  103. ZeroMemory(&prgAdr[iAddress], sizeof(ADDRESSPROPS));
  104. // Copy Props
  105. CHECKHR(hr = HrCopyAddressProps(&m_rList.prgAdr[m_iAddress], &prgAdr[iAddress]));
  106. // Next
  107. m_iAddress++;
  108. }
  109. // Return fetced ?
  110. if (pcFetched)
  111. *pcFetched = cFetch;
  112. exit:
  113. // Thread Safety
  114. LeaveCriticalSection(&m_cs);
  115. // Done
  116. return (cFetch == cWanted) ? S_OK : S_FALSE;
  117. }
  118. // --------------------------------------------------------------------------------
  119. // CMimeEnumAddressTypes::Skip
  120. // --------------------------------------------------------------------------------
  121. STDMETHODIMP CMimeEnumAddressTypes::Skip(ULONG cSkip)
  122. {
  123. // Locals
  124. HRESULT hr=S_OK;
  125. // Thread Safety
  126. EnterCriticalSection(&m_cs);
  127. // Can we do it...
  128. if (((m_iAddress + cSkip) >= m_rList.cAdrs) || NULL == m_rList.prgAdr)
  129. {
  130. hr = S_FALSE;
  131. goto exit;
  132. }
  133. // Skip
  134. m_iAddress += cSkip;
  135. exit:
  136. // Thread Safety
  137. LeaveCriticalSection(&m_cs);
  138. // Done
  139. return hr;
  140. }
  141. // --------------------------------------------------------------------------------
  142. // CMimeEnumAddressTypes::Reset
  143. // --------------------------------------------------------------------------------
  144. STDMETHODIMP CMimeEnumAddressTypes::Reset(void)
  145. {
  146. EnterCriticalSection(&m_cs);
  147. m_iAddress = 0;
  148. LeaveCriticalSection(&m_cs);
  149. return S_OK;
  150. }
  151. // --------------------------------------------------------------------------------
  152. // CMimeEnumAddressTypes::Count
  153. // --------------------------------------------------------------------------------
  154. STDMETHODIMP CMimeEnumAddressTypes::Count(ULONG *pcCount)
  155. {
  156. // Invalid Arg
  157. if (NULL == pcCount)
  158. return TrapError(E_INVALIDARG);
  159. // Thread Safety
  160. EnterCriticalSection(&m_cs);
  161. // Set Count
  162. *pcCount = m_rList.cAdrs;
  163. // Thread Safety
  164. LeaveCriticalSection(&m_cs);
  165. // Done
  166. return S_OK;
  167. }
  168. // --------------------------------------------------------------------------------
  169. // CMimeEnumAddressTypes::Clone
  170. // --------------------------------------------------------------------------------
  171. STDMETHODIMP CMimeEnumAddressTypes::Clone(IMimeEnumAddressTypes **ppEnum)
  172. {
  173. // Locals
  174. HRESULT hr=S_OK;
  175. CMimeEnumAddressTypes *pEnum=NULL;
  176. // Invalid Arg
  177. if (NULL == ppEnum)
  178. return TrapError(E_INVALIDARG);
  179. // Thread Safety
  180. EnterCriticalSection(&m_cs);
  181. // Init
  182. *ppEnum = NULL;
  183. // Create the clone.
  184. CHECKALLOC(pEnum = new CMimeEnumAddressTypes);
  185. // Init
  186. CHECKHR(hr = pEnum->HrInit(m_pTable, m_iAddress, &m_rList, TRUE));
  187. // Set Return
  188. *ppEnum = pEnum;
  189. (*ppEnum)->AddRef();
  190. exit:
  191. // Cleanup
  192. SafeRelease(pEnum);
  193. // Thread Safety
  194. LeaveCriticalSection(&m_cs);
  195. // Done
  196. return hr;
  197. }
  198. // --------------------------------------------------------------------------------
  199. // CMimeEnumAddressTypes::HrInit
  200. // --------------------------------------------------------------------------------
  201. HRESULT CMimeEnumAddressTypes::HrInit(IMimeAddressTable *pTable, ULONG iAddress, LPADDRESSLIST pList, BOOL fDuplicate)
  202. {
  203. // Locals
  204. HRESULT hr=S_OK;
  205. ULONG i;
  206. // Invalid Arg
  207. Assert(pTable && pList);
  208. // Thread Safety
  209. EnterCriticalSection(&m_cs);
  210. // Check param
  211. Assert(m_iAddress == 0 && m_rList.cAdrs == 0 && m_rList.prgAdr == NULL);
  212. // Empty Enumerator ?
  213. if (0 == pList->cAdrs)
  214. {
  215. Assert(pList->prgAdr == NULL);
  216. goto exit;
  217. }
  218. // No Duplicate ?
  219. if (FALSE == fDuplicate)
  220. CopyMemory(&m_rList, pList, sizeof(ADDRESSLIST));
  221. // Otherwise
  222. else
  223. {
  224. // Allocat an internal array
  225. CHECKHR(hr = HrAlloc((LPVOID *)&m_rList.prgAdr, sizeof(ADDRESSPROPS) * pList->cAdrs));
  226. // Copy prgPart
  227. for (i=0; i<pList->cAdrs; i++)
  228. {
  229. // Zero Dest
  230. ZeroMemory(&m_rList.prgAdr[i], sizeof(ADDRESSPROPS));
  231. // Copy Address Props
  232. CHECKHR(hr = HrCopyAddressProps(&pList->prgAdr[i], &m_rList.prgAdr[i]));
  233. }
  234. // Save Size and State
  235. m_rList.cAdrs = pList->cAdrs;
  236. }
  237. // Save Current Index
  238. Assert(iAddress < m_rList.cAdrs);
  239. m_iAddress = iAddress;
  240. // Assume the Table
  241. m_pTable = pTable;
  242. m_pTable->AddRef();
  243. exit:
  244. // Thread Safety
  245. LeaveCriticalSection(&m_cs);
  246. // Done
  247. return hr;
  248. }