2 * Miscellaneous Marshaling Routines
4 * Copyright 2005 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ole);
42 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
43 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
44 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
45 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
47 static const char* debugstr_user_flags(ULONG *pFlags)
51 switch (LOWORD(*pFlags))
54 loword="MSHCTX_LOCAL";
56 case MSHCTX_NOSHAREDMEM:
57 loword="MSHCTX_NOSHAREDMEM";
59 case MSHCTX_DIFFERENTMACHINE:
60 loword="MSHCTX_DIFFERENTMACHINE";
63 loword="MSHCTX_INPROC";
66 sprintf(buf, "%d", LOWORD(*pFlags));
70 if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
71 return wine_dbg_sprintf("MAKELONG(NDR_LOCAL_REPRESENTATION, %s)", loword);
73 return wine_dbg_sprintf("MAKELONG(0x%04x, %s)", HIWORD(*pFlags), loword);
76 /******************************************************************************
77 * CLIPFORMAT_UserSize [OLE32.@]
79 * Calculates the buffer size required to marshal a clip format.
82 * pFlags [I] Flags. See notes.
83 * StartingSize [I] Starting size of the buffer. This value is added on to
84 * the buffer size required for the clip format.
85 * pCF [I] Clip format to size.
88 * The buffer size required to marshal a clip format plus the starting size.
91 * Even though the function is documented to take a pointer to an unsigned
92 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
93 * the first parameter is an unsigned long.
94 * This function is only intended to be called by the RPC runtime.
96 ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG StartingSize, CLIPFORMAT *pCF)
98 ULONG size = StartingSize;
100 TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pCF);
102 size += sizeof(userCLIPFORMAT);
104 /* only need to marshal the name if it is not a pre-defined type and
105 * we are going remote */
106 if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
110 size += 3 * sizeof(INT);
111 /* urg! this function is badly designed because it won't tell us how
112 * much space is needed without doing a dummy run of storing the
113 * name into a buffer */
114 ret = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
116 RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
117 size += (ret + 1) * sizeof(WCHAR);
122 /******************************************************************************
123 * CLIPFORMAT_UserMarshal [OLE32.@]
125 * Marshals a clip format into a buffer.
128 * pFlags [I] Flags. See notes.
129 * pBuffer [I] Buffer to marshal the clip format into.
130 * pCF [I] Clip format to marshal.
133 * The end of the marshaled data in the buffer.
136 * Even though the function is documented to take a pointer to an unsigned
137 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
138 * the first parameter is an unsigned long.
139 * This function is only intended to be called by the RPC runtime.
141 unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
143 wireCLIPFORMAT wirecf = (wireCLIPFORMAT)pBuffer;
145 TRACE("(%s, %p, &0x%04x\n", debugstr_user_flags(pFlags), pBuffer, *pCF);
147 wirecf->u.dwValue = *pCF;
148 pBuffer += sizeof(*wirecf);
150 /* only need to marshal the name if it is not a pre-defined type and
151 * we are going remote */
152 if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
156 wirecf->fContext = WDT_REMOTE_CALL;
157 len = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
159 RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
161 *(INT *)pBuffer = len;
162 pBuffer += sizeof(INT);
164 pBuffer += sizeof(INT);
165 *(INT *)pBuffer = len;
166 pBuffer += sizeof(INT);
167 TRACE("marshaling format name %s\n", debugstr_wn(format, len-1));
168 lstrcpynW((LPWSTR)pBuffer, format, len);
169 pBuffer += len * sizeof(WCHAR);
170 *(WCHAR *)pBuffer = '\0';
171 pBuffer += sizeof(WCHAR);
174 wirecf->fContext = WDT_INPROC_CALL;
179 /******************************************************************************
180 * CLIPFORMAT_UserUnmarshal [OLE32.@]
182 * Unmarshals a clip format from a buffer.
185 * pFlags [I] Flags. See notes.
186 * pBuffer [I] Buffer to marshal the clip format from.
187 * pCF [O] Address that receive the unmarshaled clip format.
190 * The end of the marshaled data in the buffer.
193 * Even though the function is documented to take a pointer to an unsigned
194 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
195 * the first parameter is an unsigned long.
196 * This function is only intended to be called by the RPC runtime.
198 unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
200 wireCLIPFORMAT wirecf = (wireCLIPFORMAT)pBuffer;
202 TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pCF);
204 pBuffer += sizeof(*wirecf);
205 if (wirecf->fContext == WDT_INPROC_CALL)
206 *pCF = (CLIPFORMAT)wirecf->u.dwValue;
207 else if (wirecf->fContext == WDT_REMOTE_CALL)
210 INT len = *(INT *)pBuffer;
211 pBuffer += sizeof(INT);
212 if (*(INT *)pBuffer != 0)
213 RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
214 pBuffer += sizeof(INT);
215 if (*(INT *)pBuffer != len)
216 RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
217 pBuffer += sizeof(INT);
218 if (((WCHAR *)pBuffer)[len] != '\0')
219 RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
220 TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer));
221 cf = RegisterClipboardFormatW((LPCWSTR)pBuffer);
222 pBuffer += (len + 1) * sizeof(WCHAR);
224 RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
228 /* code not really appropriate, but nearest I can find */
229 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
233 /******************************************************************************
234 * CLIPFORMAT_UserFree [OLE32.@]
236 * Frees an unmarshaled clip format.
239 * pFlags [I] Flags. See notes.
240 * pCF [I] Clip format to free.
243 * The end of the marshaled data in the buffer.
246 * Even though the function is documented to take a pointer to an unsigned
247 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB
248 * structure, of which the first parameter is an unsigned long.
249 * This function is only intended to be called by the RPC runtime.
251 void __RPC_USER CLIPFORMAT_UserFree(ULONG *pFlags, CLIPFORMAT *pCF)
253 /* there is no inverse of the RegisterClipboardFormat function,
254 * so nothing to do */
257 static ULONG __RPC_USER handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle)
259 if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
261 ERR("can't remote a local handle\n");
262 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
265 return StartingSize + sizeof(RemotableHandle);
268 static unsigned char * __RPC_USER handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
270 RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
271 if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
273 ERR("can't remote a local handle\n");
274 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
277 remhandle->fContext = WDT_INPROC_CALL;
278 remhandle->u.hInproc = (LONG_PTR)*handle;
279 return pBuffer + sizeof(RemotableHandle);
282 static unsigned char * __RPC_USER handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
284 RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
285 if (remhandle->fContext != WDT_INPROC_CALL)
286 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
287 *handle = (HANDLE)remhandle->u.hInproc;
288 return pBuffer + sizeof(RemotableHandle);
291 static void __RPC_USER handle_UserFree(ULONG *pFlags, HANDLE *phMenu)
296 #define IMPL_WIREM_HANDLE(type) \
297 ULONG __RPC_USER type##_UserSize(ULONG *pFlags, ULONG StartingSize, type *handle) \
299 TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, handle); \
300 return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \
303 unsigned char * __RPC_USER type##_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
305 TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *handle); \
306 return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \
309 unsigned char * __RPC_USER type##_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
311 TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, handle); \
312 return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \
315 void __RPC_USER type##_UserFree(ULONG *pFlags, type *handle) \
317 TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *handle); \
318 return handle_UserFree(pFlags, (HANDLE *)handle); \
321 IMPL_WIREM_HANDLE(HACCEL)
322 IMPL_WIREM_HANDLE(HMENU)
323 IMPL_WIREM_HANDLE(HWND)
325 /******************************************************************************
326 * HGLOBAL_UserSize [OLE32.@]
328 ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal)
330 ULONG size = StartingSize;
332 TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, phGlobal);
334 ALIGN_LENGTH(size, 3);
336 size += sizeof(ULONG);
338 if (LOWORD(*pFlags == MSHCTX_INPROC))
339 size += sizeof(HGLOBAL);
342 size += sizeof(ULONG);
346 size += 3 * sizeof(ULONG);
347 ret = GlobalSize(*phGlobal);
355 unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
357 TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal);
359 ALIGN_POINTER(pBuffer, 3);
361 if (LOWORD(*pFlags == MSHCTX_INPROC))
363 if (sizeof(*phGlobal) == 8)
364 *(ULONG *)pBuffer = WDT_INPROC64_CALL;
366 *(ULONG *)pBuffer = WDT_INPROC_CALL;
367 pBuffer += sizeof(ULONG);
368 *(HGLOBAL *)pBuffer = *phGlobal;
369 pBuffer += sizeof(HGLOBAL);
373 *(ULONG *)pBuffer = WDT_REMOTE_CALL;
374 pBuffer += sizeof(ULONG);
375 *(ULONG *)pBuffer = (ULONG)*phGlobal;
376 pBuffer += sizeof(ULONG);
379 const unsigned char *memory;
380 SIZE_T size = GlobalSize(*phGlobal);
381 *(ULONG *)pBuffer = (ULONG)size;
382 pBuffer += sizeof(ULONG);
383 *(ULONG *)pBuffer = (ULONG)*phGlobal;
384 pBuffer += sizeof(ULONG);
385 *(ULONG *)pBuffer = (ULONG)size;
386 pBuffer += sizeof(ULONG);
388 memory = GlobalLock(*phGlobal);
389 memcpy(pBuffer, memory, size);
391 GlobalUnlock(*phGlobal);
398 unsigned char * __RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
402 TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal);
404 ALIGN_POINTER(pBuffer, 3);
406 fContext = *(ULONG *)pBuffer;
407 pBuffer += sizeof(ULONG);
409 if (((fContext == WDT_INPROC_CALL) && (sizeof(*phGlobal) < 8)) ||
410 ((fContext == WDT_INPROC64_CALL) && (sizeof(*phGlobal) == 8)))
412 *phGlobal = *(HGLOBAL *)pBuffer;
413 pBuffer += sizeof(*phGlobal);
415 else if (fContext == WDT_REMOTE_CALL)
419 handle = *(ULONG *)pBuffer;
420 pBuffer += sizeof(ULONG);
427 size = *(ULONG *)pBuffer;
428 pBuffer += sizeof(ULONG);
429 /* redundancy is bad - it means you have to check consistency like
431 if (*(ULONG *)pBuffer != handle)
433 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
436 pBuffer += sizeof(ULONG);
437 /* redundancy is bad - it means you have to check consistency like
439 if (*(ULONG *)pBuffer != size)
441 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
444 pBuffer += sizeof(ULONG);
446 /* FIXME: check size is not too big */
448 *phGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
449 memory = GlobalLock(*phGlobal);
450 memcpy(memory, pBuffer, size);
452 GlobalUnlock(*phGlobal);
458 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
463 /******************************************************************************
464 * HGLOBAL_UserFree [OLE32.@]
466 void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
468 TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phGlobal);
470 if (LOWORD(*pFlags != MSHCTX_INPROC) && *phGlobal)
471 GlobalFree(*phGlobal);
474 ULONG __RPC_USER HBITMAP_UserSize(ULONG *pFlags, ULONG StartingSize, HBITMAP *phBmp)
480 unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HBITMAP *phBmp)
486 unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HBITMAP *phBmp)
492 void __RPC_USER HBITMAP_UserFree(ULONG *pFlags, HBITMAP *phBmp)
497 ULONG __RPC_USER HDC_UserSize(ULONG *pFlags, ULONG StartingSize, HDC *phdc)
503 unsigned char * __RPC_USER HDC_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HDC *phdc)
509 unsigned char * __RPC_USER HDC_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HDC *phdc)
515 void __RPC_USER HDC_UserFree(ULONG *pFlags, HDC *phdc)
520 ULONG __RPC_USER HPALETTE_UserSize(ULONG *pFlags, ULONG StartingSize, HPALETTE *phPal)
526 unsigned char * __RPC_USER HPALETTE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
532 unsigned char * __RPC_USER HPALETTE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
538 void __RPC_USER HPALETTE_UserFree(ULONG *pFlags, HPALETTE *phPal)
544 ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG StartingSize, HENHMETAFILE *phEmf)
546 ULONG size = StartingSize;
548 TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, *phEmf);
550 size += sizeof(ULONG);
551 if (LOWORD(*pFlags) == MSHCTX_INPROC)
552 size += sizeof(ULONG_PTR);
555 size += sizeof(ULONG);
561 size += 2 * sizeof(ULONG);
562 emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL);
570 unsigned char * __RPC_USER HENHMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
572 TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phEmf);
574 if (LOWORD(*pFlags) == MSHCTX_INPROC)
576 if (sizeof(*phEmf) == 8)
577 *(ULONG *)pBuffer = WDT_INPROC64_CALL;
579 *(ULONG *)pBuffer = WDT_INPROC_CALL;
580 pBuffer += sizeof(ULONG);
581 *(HENHMETAFILE *)pBuffer = *phEmf;
582 pBuffer += sizeof(HENHMETAFILE);
586 *(ULONG *)pBuffer = WDT_REMOTE_CALL;
587 pBuffer += sizeof(ULONG);
588 *(ULONG *)pBuffer = (ULONG)(ULONG_PTR)*phEmf;
589 pBuffer += sizeof(ULONG);
593 UINT emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL);
595 *(ULONG *)pBuffer = emfsize;
596 pBuffer += sizeof(ULONG);
597 *(ULONG *)pBuffer = emfsize;
598 pBuffer += sizeof(ULONG);
599 GetEnhMetaFileBits(*phEmf, emfsize, pBuffer);
607 unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
611 TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, phEmf);
613 fContext = *(ULONG *)pBuffer;
614 pBuffer += sizeof(ULONG);
616 if (((fContext == WDT_INPROC_CALL) && (sizeof(*phEmf) < 8)) ||
617 ((fContext == WDT_INPROC64_CALL) && (sizeof(*phEmf) == 8)))
619 *phEmf = *(HENHMETAFILE *)pBuffer;
620 pBuffer += sizeof(*phEmf);
622 else if (fContext == WDT_REMOTE_CALL)
626 handle = *(ULONG *)pBuffer;
627 pBuffer += sizeof(ULONG);
632 size = *(ULONG *)pBuffer;
633 pBuffer += sizeof(ULONG);
634 if (size != *(ULONG *)pBuffer)
636 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
639 pBuffer += sizeof(ULONG);
640 *phEmf = SetEnhMetaFileBits(size, pBuffer);
647 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
652 void __RPC_USER HENHMETAFILE_UserFree(ULONG *pFlags, HENHMETAFILE *phEmf)
654 TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phEmf);
656 if (LOWORD(*pFlags) != MSHCTX_INPROC)
657 DeleteEnhMetaFile(*phEmf);
660 ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM *pStgMedium)
662 ULONG size = StartingSize;
664 TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pStgMedium);
666 ALIGN_LENGTH(size, 3);
668 size += 2 * sizeof(DWORD);
669 if (pStgMedium->tymed != TYMED_NULL)
670 size += sizeof(DWORD);
672 switch (pStgMedium->tymed)
675 TRACE("TYMED_NULL\n");
678 TRACE("TYMED_HGLOBAL\n");
679 size = HGLOBAL_UserSize(pFlags, size, &pStgMedium->u.hGlobal);
682 FIXME("TYMED_FILE\n");
685 FIXME("TYMED_ISTREAM\n");
688 FIXME("TYMED_ISTORAGE\n");
691 FIXME("TYMED_GDI\n");
694 FIXME("TYMED_MFPICT\n");
697 TRACE("TYMED_ENHMF\n");
698 size = HENHMETAFILE_UserSize(pFlags, size, &pStgMedium->u.hEnhMetaFile);
701 RaiseException(DV_E_TYMED, 0, 0, NULL);
704 if (pStgMedium->pUnkForRelease)
705 FIXME("buffer size pUnkForRelease\n");
710 unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
712 TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pStgMedium);
714 ALIGN_POINTER(pBuffer, 3);
716 *(DWORD *)pBuffer = pStgMedium->tymed;
717 pBuffer += sizeof(DWORD);
718 if (pStgMedium->tymed != TYMED_NULL)
720 *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->u.pstg;
721 pBuffer += sizeof(DWORD);
723 *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->pUnkForRelease;
724 pBuffer += sizeof(DWORD);
726 switch (pStgMedium->tymed)
729 TRACE("TYMED_NULL\n");
732 TRACE("TYMED_HGLOBAL\n");
733 pBuffer = HGLOBAL_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
736 FIXME("TYMED_FILE\n");
739 FIXME("TYMED_ISTREAM\n");
742 FIXME("TYMED_ISTORAGE\n");
745 FIXME("TYMED_GDI\n");
748 FIXME("TYMED_MFPICT\n");
751 TRACE("TYMED_ENHMF\n");
752 pBuffer = HENHMETAFILE_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
755 RaiseException(DV_E_TYMED, 0, 0, NULL);
758 if (pStgMedium->pUnkForRelease)
759 FIXME("marshal pUnkForRelease\n");
764 unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
769 ALIGN_POINTER(pBuffer, 3);
771 TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pStgMedium);
773 pStgMedium->tymed = *(DWORD *)pBuffer;
774 pBuffer += sizeof(DWORD);
775 if (pStgMedium->tymed != TYMED_NULL)
777 content = *(DWORD *)pBuffer;
778 pBuffer += sizeof(DWORD);
780 releaseunk = *(DWORD *)pBuffer;
781 pBuffer += sizeof(DWORD);
783 switch (pStgMedium->tymed)
786 TRACE("TYMED_NULL\n");
789 TRACE("TYMED_HGLOBAL\n");
790 pBuffer = HGLOBAL_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
793 FIXME("TYMED_FILE\n");
796 FIXME("TYMED_ISTREAM\n");
799 FIXME("TYMED_ISTORAGE\n");
802 FIXME("TYMED_GDI\n");
805 FIXME("TYMED_MFPICT\n");
808 TRACE("TYMED_ENHMF\n");
809 pBuffer = HENHMETAFILE_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
812 RaiseException(DV_E_TYMED, 0, 0, NULL);
815 pStgMedium->pUnkForRelease = NULL;
817 FIXME("unmarshal pUnkForRelease\n");
822 void __RPC_USER STGMEDIUM_UserFree(ULONG *pFlags, STGMEDIUM *pStgMedium)
824 TRACE("(%s, %p\n", debugstr_user_flags(pFlags), pStgMedium);
826 ReleaseStgMedium(pStgMedium);
829 ULONG __RPC_USER ASYNC_STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, ASYNC_STGMEDIUM *pStgMedium)
835 unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserMarshal( ULONG *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
841 unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
847 void __RPC_USER ASYNC_STGMEDIUM_UserFree(ULONG *pFlags, ASYNC_STGMEDIUM *pStgMedium)
852 ULONG __RPC_USER FLAG_STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, FLAG_STGMEDIUM *pStgMedium)
858 unsigned char * __RPC_USER FLAG_STGMEDIUM_UserMarshal( ULONG *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
864 unsigned char * __RPC_USER FLAG_STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
870 void __RPC_USER FLAG_STGMEDIUM_UserFree(ULONG *pFlags, FLAG_STGMEDIUM *pStgMedium)
875 ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
881 unsigned char * __RPC_USER SNB_UserMarshal( ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
887 unsigned char * __RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
893 void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)