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.

336 lines
9.3 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Utility Code
  4. **
  5. ** enumstat.c
  6. **
  7. ** This file contains a standard implementation of IEnumStatData
  8. ** interface.
  9. ** This file is part of the OLE 2.0 User Interface support library.
  10. **
  11. ** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
  12. **
  13. *************************************************************************/
  14. #define STRICT 1
  15. #include "ole2ui.h"
  16. typedef struct tagOleStdEnumStatData {
  17. IEnumSTATDATAVtbl FAR* lpVtbl;
  18. ULONG m_dwRefs; /* referance count */
  19. ULONG m_nIndex; /* current index in list */
  20. ULONG m_nCount; /* how many items in list */
  21. LPSTATDATA m_lpStat; /* list of STATDATA */
  22. } OLESTDENUMSTATDATA, FAR* LPOLESTDENUMSTATDATA;
  23. VOID OleStdEnumStatData_Destroy(LPOLESTDENUMSTATDATA pStat);
  24. STDMETHODIMP OleStdEnumStatData_QueryInterface(
  25. LPENUMSTATDATA lpThis, REFIID riid, LPVOID FAR* ppobj);
  26. STDMETHODIMP_(ULONG) OleStdEnumStatData_AddRef(LPENUMSTATDATA lpThis);
  27. STDMETHODIMP_(ULONG) OleStdEnumStatData_Release(LPENUMSTATDATA lpThis);
  28. STDMETHODIMP OleStdEnumStatData_Next(LPENUMSTATDATA lpThis, ULONG celt,
  29. LPSTATDATA rgelt, ULONG FAR* pceltFetched);
  30. STDMETHODIMP OleStdEnumStatData_Skip(LPENUMSTATDATA lpThis, ULONG celt);
  31. STDMETHODIMP OleStdEnumStatData_Reset(LPENUMSTATDATA lpThis);
  32. STDMETHODIMP OleStdEnumStatData_Clone(LPENUMSTATDATA lpThis,
  33. LPENUMSTATDATA FAR* ppenum);
  34. static IEnumSTATDATAVtbl g_EnumSTATDATAVtbl = {
  35. OleStdEnumStatData_QueryInterface,
  36. OleStdEnumStatData_AddRef,
  37. OleStdEnumStatData_Release,
  38. OleStdEnumStatData_Next,
  39. OleStdEnumStatData_Skip,
  40. OleStdEnumStatData_Reset,
  41. OleStdEnumStatData_Clone,
  42. };
  43. /////////////////////////////////////////////////////////////////////////////
  44. STDAPI_(BOOL)
  45. OleStdCopyStatData(LPSTATDATA pDest, LPSTATDATA pSrc)
  46. //----------------------------------------------------------------------------
  47. //
  48. //----------------------------------------------------------------------------
  49. {
  50. if ((pDest == NULL) || (pSrc == NULL)) {
  51. return FALSE;
  52. }
  53. if (OleStdCopyFormatEtc(&pDest->formatetc, &pSrc->formatetc) == FALSE) {
  54. return FALSE;
  55. }
  56. pDest->advf = pSrc->advf;
  57. pDest->pAdvSink = pSrc->pAdvSink;
  58. pDest->dwConnection = pSrc->dwConnection;
  59. if (pDest->pAdvSink != NULL) {
  60. pDest->pAdvSink->lpVtbl->AddRef(pDest->pAdvSink);
  61. }
  62. return TRUE;
  63. } /* OleStdCopyStatData()
  64. */
  65. STDAPI_(LPENUMSTATDATA)
  66. OleStdEnumStatData_Create(ULONG nCount, LPSTATDATA lpStatOrg)
  67. //----------------------------------------------------------------------------
  68. //
  69. //----------------------------------------------------------------------------
  70. {
  71. LPMALLOC lpMalloc=NULL;
  72. LPOLESTDENUMSTATDATA lpSD=NULL;
  73. DWORD dwSize;
  74. WORD i;
  75. HRESULT hRes;
  76. hRes = CoGetMalloc(MEMCTX_TASK, &lpMalloc);
  77. if (hRes != NOERROR) {
  78. return NULL;
  79. }
  80. lpSD = (LPOLESTDENUMSTATDATA)lpMalloc->lpVtbl->Alloc(lpMalloc,
  81. sizeof(OLESTDENUMSTATDATA));
  82. if (lpSD == NULL) {
  83. goto errReturn;
  84. }
  85. lpSD->lpVtbl = &g_EnumSTATDATAVtbl;
  86. lpSD->m_dwRefs = 1;
  87. lpSD->m_nCount = nCount;
  88. lpSD->m_nIndex = 0;
  89. dwSize = sizeof(STATDATA) * lpSD->m_nCount;
  90. lpSD->m_lpStat = (LPSTATDATA)lpMalloc->lpVtbl->Alloc(lpMalloc, dwSize);
  91. if (lpSD->m_lpStat == NULL)
  92. goto errReturn;
  93. lpMalloc->lpVtbl->Release(lpMalloc);
  94. for (i=0; i<nCount; i++) {
  95. OleStdCopyStatData(
  96. (LPSTATDATA)&(lpSD->m_lpStat[i]), (LPSTATDATA)&(lpStatOrg[i]));
  97. }
  98. return (LPENUMSTATDATA)lpSD;
  99. errReturn:
  100. if (lpSD != NULL)
  101. lpMalloc->lpVtbl->Free(lpMalloc, lpSD);
  102. if (lpMalloc != NULL)
  103. lpMalloc->lpVtbl->Release(lpMalloc);
  104. return NULL;
  105. } /* OleStdEnumStatData_Create()
  106. */
  107. VOID
  108. OleStdEnumStatData_Destroy(LPOLESTDENUMSTATDATA lpSD)
  109. //----------------------------------------------------------------------------
  110. //
  111. //----------------------------------------------------------------------------
  112. {
  113. LPMALLOC lpMalloc=NULL;
  114. WORD i;
  115. if (lpSD != NULL) {
  116. if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) == NOERROR) {
  117. /* OLE2NOTE: we MUST free any memory that was allocated for
  118. ** TARGETDEVICES contained within the STATDATA elements.
  119. */
  120. for (i=0; i<lpSD->m_nCount; i++) {
  121. if( lpSD->m_lpStat[i].pAdvSink )
  122. lpSD->m_lpStat[i].pAdvSink->lpVtbl->Release(lpSD->m_lpStat[i].pAdvSink);
  123. OleStdFree(lpSD->m_lpStat[i].formatetc.ptd);
  124. }
  125. if (lpSD->m_lpStat != NULL) {
  126. lpMalloc->lpVtbl->Free(lpMalloc, lpSD->m_lpStat);
  127. }
  128. lpMalloc->lpVtbl->Free(lpMalloc, lpSD);
  129. lpMalloc->lpVtbl->Release(lpMalloc);
  130. }
  131. }
  132. } /* OleStdEnumStatData_Destroy()
  133. */
  134. STDMETHODIMP
  135. OleStdEnumStatData_QueryInterface(
  136. LPENUMSTATDATA lpThis, REFIID riid, LPVOID FAR* ppobj)
  137. //----------------------------------------------------------------------------
  138. //
  139. //----------------------------------------------------------------------------
  140. {
  141. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  142. *ppobj = NULL;
  143. if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IEnumSTATDATA)){
  144. *ppobj = (LPVOID)lpSD;
  145. }
  146. if (*ppobj == NULL) return ResultFromScode(E_NOINTERFACE);
  147. else{
  148. OleStdEnumStatData_AddRef(lpThis);
  149. return NOERROR;
  150. }
  151. } /* OleStdEnumStatData_QueryInterface()
  152. */
  153. STDMETHODIMP_(ULONG)
  154. OleStdEnumStatData_AddRef(LPENUMSTATDATA lpThis)
  155. //----------------------------------------------------------------------------
  156. //
  157. //----------------------------------------------------------------------------
  158. {
  159. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  160. return lpSD->m_dwRefs++;
  161. } /* OleStdEnumStatData_AddRef()
  162. */
  163. STDMETHODIMP_(ULONG)
  164. OleStdEnumStatData_Release(LPENUMSTATDATA lpThis)
  165. //----------------------------------------------------------------------------
  166. //
  167. //----------------------------------------------------------------------------
  168. {
  169. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  170. DWORD dwRefs = --lpSD->m_dwRefs;
  171. if (dwRefs == 0)
  172. OleStdEnumStatData_Destroy(lpSD);
  173. return dwRefs;
  174. } /* OleStdEnumStatData_Release()
  175. */
  176. STDMETHODIMP
  177. OleStdEnumStatData_Next(LPENUMSTATDATA lpThis, ULONG celt, LPSTATDATA rgelt,
  178. ULONG FAR* pceltFetched)
  179. //----------------------------------------------------------------------------
  180. //
  181. //----------------------------------------------------------------------------
  182. {
  183. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  184. ULONG i=0;
  185. ULONG nOffset;
  186. if (rgelt == NULL) {
  187. return ResultFromScode(E_INVALIDARG);
  188. }
  189. while (i < celt) {
  190. nOffset = lpSD->m_nIndex + i;
  191. if (nOffset < lpSD->m_nCount) {
  192. OleStdCopyStatData(
  193. (LPSTATDATA)&(rgelt[i]), (LPSTATDATA)&(lpSD->m_lpStat[nOffset]));
  194. i++;
  195. }else{
  196. break;
  197. }
  198. }
  199. lpSD->m_nIndex += (WORD)i;
  200. if (pceltFetched != NULL) {
  201. *pceltFetched = i;
  202. }
  203. if (i != celt) {
  204. return ResultFromScode(S_FALSE);
  205. }
  206. return NOERROR;
  207. } /* OleStdEnumStatData_Next()
  208. */
  209. STDMETHODIMP
  210. OleStdEnumStatData_Skip(LPENUMSTATDATA lpThis, ULONG celt)
  211. //----------------------------------------------------------------------------
  212. //
  213. //----------------------------------------------------------------------------
  214. {
  215. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  216. ULONG i=0;
  217. ULONG nOffset;
  218. while (i < celt) {
  219. nOffset = lpSD->m_nIndex + i;
  220. if (nOffset < lpSD->m_nCount) {
  221. i++;
  222. }else{
  223. break;
  224. }
  225. }
  226. lpSD->m_nIndex += (WORD)i;
  227. if (i != celt) {
  228. return ResultFromScode(S_FALSE);
  229. }
  230. return NOERROR;
  231. } /* OleStdEnumStatData_Skip()
  232. */
  233. STDMETHODIMP
  234. OleStdEnumStatData_Reset(LPENUMSTATDATA lpThis)
  235. //----------------------------------------------------------------------------
  236. //
  237. //----------------------------------------------------------------------------
  238. {
  239. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  240. lpSD->m_nIndex = 0;
  241. return NOERROR;
  242. } /* OleStdEnumStatData_Reset()
  243. */
  244. STDMETHODIMP
  245. OleStdEnumStatData_Clone(LPENUMSTATDATA lpThis, LPENUMSTATDATA FAR* ppenum)
  246. //----------------------------------------------------------------------------
  247. //
  248. //----------------------------------------------------------------------------
  249. {
  250. LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
  251. if (ppenum == NULL) {
  252. return ResultFromScode(E_INVALIDARG);
  253. }
  254. *ppenum = OleStdEnumStatData_Create(lpSD->m_nCount, lpSD->m_lpStat);
  255. // make sure cloned enumerator has same index state as the original
  256. if (*ppenum) {
  257. LPOLESTDENUMSTATDATA lpSDClone = (LPOLESTDENUMSTATDATA)*ppenum;
  258. lpSDClone->m_nIndex = lpSD->m_nIndex;
  259. return NOERROR;
  260. } else
  261. return ResultFromScode(E_OUTOFMEMORY);
  262. } /* OleStdEnumStatData_Clone()
  263. */