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.

437 lines
12 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Utility Code
  4. **
  5. ** enumfetc.c
  6. **
  7. ** This file contains a standard implementation of IEnumFormatEtc
  8. ** interface.
  9. ** This file is part of the OLE 2.0 User Interface support library.
  10. **
  11. ** (c) Copyright Microsoft Corp. 1990 - 1995. All Rights Reserved
  12. **
  13. *************************************************************************/
  14. #define STRICT 1
  15. #include <win32.h>
  16. #include <ole2.h>
  17. #include "enumfetc.h"
  18. #ifdef SHELLOLE
  19. #ifdef _WIN32
  20. #undef Assert
  21. #include <shlobj.h>
  22. #include <shellp.h>
  23. #define CoGetMalloc(ctx, ppmalloc) SHGetMalloc(ppmalloc)
  24. #endif
  25. #endif
  26. #ifdef DAYTONA
  27. #include "olehack.h"
  28. #endif
  29. STDAPI_(void) OleStdFree(LPVOID pmem);
  30. STDAPI_(BOOL) OleStdCopyFormatEtc(LPFORMATETC petcDest, LPFORMATETC petcSrc);
  31. typedef struct tagOleStdEnumFmtEtc {
  32. IEnumFORMATETCVtbl FAR* lpVtbl;
  33. ULONG m_dwRefs; /* referance count */
  34. WORD m_wIndex; /* current index in list */
  35. WORD m_wCount; /* how many items in list */
  36. LPFORMATETC m_lpEtc; /* list of formatetc */
  37. } OLESTDENUMFMTETC, FAR* LPOLESTDENUMFMTETC;
  38. VOID OleStdEnumFmtEtc_Destroy(LPOLESTDENUMFMTETC pEtc);
  39. STDMETHODIMP OleStdEnumFmtEtc_QueryInterface(
  40. LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* ppobj);
  41. STDMETHODIMP_(ULONG) OleStdEnumFmtEtc_AddRef(LPENUMFORMATETC lpThis);
  42. STDMETHODIMP_(ULONG) OleStdEnumFmtEtc_Release(LPENUMFORMATETC lpThis);
  43. STDMETHODIMP OleStdEnumFmtEtc_Next(LPENUMFORMATETC lpThis, ULONG celt,
  44. LPFORMATETC rgelt, ULONG FAR* pceltFetched);
  45. STDMETHODIMP OleStdEnumFmtEtc_Skip(LPENUMFORMATETC lpThis, ULONG celt);
  46. STDMETHODIMP OleStdEnumFmtEtc_Reset(LPENUMFORMATETC lpThis);
  47. STDMETHODIMP OleStdEnumFmtEtc_Clone(LPENUMFORMATETC lpThis,
  48. LPENUMFORMATETC FAR* ppenum);
  49. static IEnumFORMATETCVtbl g_EnumFORMATETCVtbl = {
  50. OleStdEnumFmtEtc_QueryInterface,
  51. OleStdEnumFmtEtc_AddRef,
  52. OleStdEnumFmtEtc_Release,
  53. OleStdEnumFmtEtc_Next,
  54. OleStdEnumFmtEtc_Skip,
  55. OleStdEnumFmtEtc_Reset,
  56. OleStdEnumFmtEtc_Clone,
  57. };
  58. /////////////////////////////////////////////////////////////////////////////
  59. STDAPI_(LPENUMFORMATETC)
  60. OleStdEnumFmtEtc_Create(WORD wCount, LPFORMATETC lpEtc)
  61. //----------------------------------------------------------------------------
  62. //
  63. //----------------------------------------------------------------------------
  64. {
  65. LPMALLOC lpMalloc=NULL;
  66. LPOLESTDENUMFMTETC lpEF=NULL;
  67. DWORD dwSize;
  68. WORD i;
  69. HRESULT hRes;
  70. hRes = CoGetMalloc(MEMCTX_TASK, &lpMalloc);
  71. if (hRes != NOERROR) {
  72. return NULL;
  73. }
  74. lpEF = (LPOLESTDENUMFMTETC)lpMalloc->lpVtbl->Alloc(lpMalloc,
  75. sizeof(OLESTDENUMFMTETC));
  76. if (lpEF == NULL) {
  77. goto errReturn;
  78. }
  79. lpEF->lpVtbl = &g_EnumFORMATETCVtbl;
  80. lpEF->m_dwRefs = 1;
  81. lpEF->m_wCount = wCount;
  82. lpEF->m_wIndex = 0;
  83. dwSize = sizeof(FORMATETC) * lpEF->m_wCount;
  84. lpEF->m_lpEtc = (LPFORMATETC)lpMalloc->lpVtbl->Alloc(lpMalloc, dwSize);
  85. if (lpEF->m_lpEtc == NULL) {
  86. goto errReturn;
  87. }
  88. for (i=0; i<wCount; i++) {
  89. OleStdCopyFormatEtc(
  90. (LPFORMATETC)&(lpEF->m_lpEtc[i]), (LPFORMATETC)&(lpEtc[i]));
  91. }
  92. return (LPENUMFORMATETC)lpEF;
  93. errReturn:
  94. if (lpEF != NULL) {
  95. lpMalloc->lpVtbl->Free(lpMalloc, lpEF);
  96. }
  97. if (lpMalloc != NULL) {
  98. lpMalloc->lpVtbl->Release(lpMalloc);
  99. }
  100. return NULL;
  101. } /* OleStdEnumFmtEtc_Create()
  102. */
  103. VOID
  104. OleStdEnumFmtEtc_Destroy(LPOLESTDENUMFMTETC lpEF)
  105. //----------------------------------------------------------------------------
  106. //
  107. //----------------------------------------------------------------------------
  108. {
  109. LPMALLOC lpMalloc=NULL;
  110. WORD i;
  111. if (lpEF != NULL) {
  112. if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) == NOERROR) {
  113. /* OLE2NOTE: we MUST free any memory that was allocated for
  114. ** TARGETDEVICES contained within the FORMATETC elements.
  115. */
  116. for (i=0; i<lpEF->m_wCount; i++) {
  117. OleStdFree(lpEF->m_lpEtc[i].ptd);
  118. }
  119. if (lpEF->m_lpEtc != NULL) {
  120. lpMalloc->lpVtbl->Free(lpMalloc, lpEF->m_lpEtc);
  121. }
  122. lpMalloc->lpVtbl->Free(lpMalloc, lpEF);
  123. lpMalloc->lpVtbl->Release(lpMalloc);
  124. }
  125. }
  126. } /* OleStdEnumFmtEtc_Destroy()
  127. */
  128. STDMETHODIMP
  129. OleStdEnumFmtEtc_QueryInterface(
  130. LPENUMFORMATETC lpThis, REFIID riid, LPVOID FAR* ppobj)
  131. //----------------------------------------------------------------------------
  132. //
  133. //----------------------------------------------------------------------------
  134. {
  135. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  136. *ppobj = NULL;
  137. if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IEnumFORMATETC)){
  138. *ppobj = (LPVOID)lpEF;
  139. }
  140. if (*ppobj == NULL) return ResultFromScode(S_FALSE);
  141. else{
  142. OleStdEnumFmtEtc_AddRef(lpThis);
  143. return NOERROR;
  144. }
  145. } /* OleStdEnumFmtEtc_QueryInterface()
  146. */
  147. STDMETHODIMP_(ULONG)
  148. OleStdEnumFmtEtc_AddRef(LPENUMFORMATETC lpThis)
  149. //----------------------------------------------------------------------------
  150. //
  151. //----------------------------------------------------------------------------
  152. {
  153. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  154. return lpEF->m_dwRefs++;
  155. } /* OleStdEnumFmtEtc_AddRef()
  156. */
  157. STDMETHODIMP_(ULONG)
  158. OleStdEnumFmtEtc_Release(LPENUMFORMATETC lpThis)
  159. //----------------------------------------------------------------------------
  160. //
  161. //----------------------------------------------------------------------------
  162. {
  163. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  164. DWORD dwRefs = --lpEF->m_dwRefs;
  165. if (dwRefs == 0)
  166. OleStdEnumFmtEtc_Destroy(lpEF);
  167. return dwRefs;
  168. } /* OleStdEnumFmtEtc_Release()
  169. */
  170. STDMETHODIMP
  171. OleStdEnumFmtEtc_Next(LPENUMFORMATETC lpThis, ULONG celt, LPFORMATETC rgelt,
  172. ULONG FAR* pceltFetched)
  173. //----------------------------------------------------------------------------
  174. //
  175. //----------------------------------------------------------------------------
  176. {
  177. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  178. ULONG i=0;
  179. WORD wOffset;
  180. if (rgelt == NULL) {
  181. return ResultFromScode(E_INVALIDARG);
  182. }
  183. while (i < celt) {
  184. wOffset = lpEF->m_wIndex + (WORD)i;
  185. if (wOffset < lpEF->m_wCount) {
  186. OleStdCopyFormatEtc(
  187. (LPFORMATETC)&(rgelt[i]), (LPFORMATETC)&(lpEF->m_lpEtc[wOffset]));
  188. lpEF->m_wIndex ++;
  189. i++;
  190. }else{
  191. break;
  192. }
  193. }
  194. if (pceltFetched != NULL) {
  195. *pceltFetched = i;
  196. }
  197. if (i != celt) {
  198. return ResultFromScode(S_FALSE);
  199. }
  200. return NOERROR;
  201. } /* OleStdEnumFmtEtc_Next()
  202. */
  203. STDMETHODIMP
  204. OleStdEnumFmtEtc_Skip(LPENUMFORMATETC lpThis, ULONG celt)
  205. //----------------------------------------------------------------------------
  206. //
  207. //----------------------------------------------------------------------------
  208. {
  209. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  210. ULONG i=0;
  211. WORD wOffset;
  212. while (i < celt) {
  213. wOffset = lpEF->m_wIndex + (WORD)i;
  214. if (wOffset < lpEF->m_wCount) {
  215. lpEF->m_wIndex ++;
  216. i++;
  217. }else{
  218. break;
  219. }
  220. }
  221. if (i != celt) {
  222. return ResultFromScode(S_FALSE);
  223. }
  224. return NOERROR;
  225. } /* OleStdEnumFmtEtc_Skip()
  226. */
  227. STDMETHODIMP
  228. OleStdEnumFmtEtc_Reset(LPENUMFORMATETC lpThis)
  229. //----------------------------------------------------------------------------
  230. //
  231. //----------------------------------------------------------------------------
  232. {
  233. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  234. lpEF->m_wIndex = 0;
  235. return NOERROR;
  236. } /* OleStdEnumFmtEtc_Reset()
  237. */
  238. STDMETHODIMP
  239. OleStdEnumFmtEtc_Clone(LPENUMFORMATETC lpThis, LPENUMFORMATETC FAR* ppenum)
  240. //----------------------------------------------------------------------------
  241. //
  242. //----------------------------------------------------------------------------
  243. {
  244. LPOLESTDENUMFMTETC lpEF = (LPOLESTDENUMFMTETC)lpThis;
  245. if (ppenum == NULL) {
  246. return ResultFromScode(E_INVALIDARG);
  247. }
  248. *ppenum = OleStdEnumFmtEtc_Create(lpEF->m_wCount, lpEF->m_lpEtc);
  249. return (*ppenum != NULL ? NOERROR : ResultFromScode(E_OUTOFMEMORY));
  250. } /* OleStdEnumFmtEtc_Clone()
  251. */
  252. /* OleStdMalloc
  253. ** ------------
  254. ** allocate memory using the currently active IMalloc* allocator
  255. */
  256. STDAPI_(LPVOID) OleStdMalloc(ULONG ulSize)
  257. {
  258. LPVOID pout;
  259. LPMALLOC pmalloc;
  260. if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != S_OK) {
  261. // OleDbgAssertSz(0, szAssertMemAlloc);
  262. return NULL;
  263. }
  264. pout = (LPVOID)pmalloc->lpVtbl->Alloc(pmalloc, ulSize);
  265. if (pmalloc != NULL) {
  266. ULONG refs = pmalloc->lpVtbl->Release(pmalloc);
  267. }
  268. return pout;
  269. }
  270. /*
  271. * OleStdCopyTargetDevice()
  272. *
  273. * Purpose:
  274. * duplicate a TARGETDEVICE struct. this function allocates memory for
  275. * the copy. the caller MUST free the allocated copy when done with it
  276. * using the standard allocator returned from CoGetMalloc.
  277. * (OleStdFree can be used to free the copy).
  278. *
  279. * Parameters:
  280. * ptdSrc pointer to source TARGETDEVICE
  281. *
  282. * Return Value:
  283. * pointer to allocated copy of ptdSrc
  284. * if ptdSrc==NULL then retuns NULL is returned.
  285. * if ptdSrc!=NULL and memory allocation fails, then NULL is returned
  286. */
  287. STDAPI_(DVTARGETDEVICE FAR*) OleStdCopyTargetDevice(DVTARGETDEVICE FAR* ptdSrc)
  288. {
  289. DVTARGETDEVICE FAR* ptdDest = NULL;
  290. if (ptdSrc == NULL) {
  291. return NULL;
  292. }
  293. if ((ptdDest = (DVTARGETDEVICE FAR*)OleStdMalloc(ptdSrc->tdSize)) != NULL) {
  294. hmemcpy(ptdDest, ptdSrc, (size_t)ptdSrc->tdSize);
  295. }
  296. return ptdDest;
  297. }
  298. /*
  299. * OleStdCopyFormatEtc()
  300. *
  301. * Purpose:
  302. * Copies the contents of a FORMATETC structure. this function takes
  303. * special care to copy correctly copying the pointer to the TARGETDEVICE
  304. * contained within the source FORMATETC structure.
  305. * if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
  306. * of the TARGETDEVICE will be allocated for the destination of the
  307. * FORMATETC (petcDest).
  308. *
  309. * OLE2NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
  310. * within the destination FORMATETC when done with it
  311. * using the standard allocator returned from CoGetMalloc.
  312. * (OleStdFree can be used to free the copy).
  313. *
  314. * Parameters:
  315. * petcDest pointer to destination FORMATETC
  316. * petcSrc pointer to source FORMATETC
  317. *
  318. * Return Value:
  319. * pointer to allocated copy of ptdSrc; retuns NULL if not successful
  320. */
  321. STDAPI_(BOOL) OleStdCopyFormatEtc(LPFORMATETC petcDest, LPFORMATETC petcSrc)
  322. {
  323. if ((petcDest == NULL) || (petcSrc == NULL)) {
  324. return FALSE;
  325. }
  326. petcDest->cfFormat = petcSrc->cfFormat;
  327. petcDest->ptd = OleStdCopyTargetDevice(petcSrc->ptd);
  328. petcDest->dwAspect = petcSrc->dwAspect;
  329. petcDest->lindex = petcSrc->lindex;
  330. petcDest->tymed = petcSrc->tymed;
  331. return TRUE;
  332. }
  333. /* OleStdFree
  334. ** ----------
  335. ** free memory using the currently active IMalloc* allocator
  336. */
  337. STDAPI_(void) OleStdFree(LPVOID pmem)
  338. {
  339. LPMALLOC pmalloc;
  340. if (pmem == NULL)
  341. return;
  342. if (CoGetMalloc(MEMCTX_TASK, &pmalloc) != S_OK) {
  343. // OleDbgAssertSz(0, szAssertMemAlloc);
  344. return;
  345. }
  346. pmalloc->lpVtbl->Free(pmalloc, pmem);
  347. if (pmalloc != NULL) {
  348. ULONG refs = pmalloc->lpVtbl->Release(pmalloc);
  349. }
  350. }