Implement some user marshal functions and add tests.
[wine/multimedia.git] / dlls / ole32 / usrmarshal.c
blob294be08998476f403fb40f1b2d828cc30124f414
1 /*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include <string.h>
24 #define COBJMACROS
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "winerror.h"
34 #include "ole2.h"
35 #include "oleauto.h"
36 #include "rpcproxy.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ole);
41 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
42 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
43 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
44 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
46 static void dump_user_flags(unsigned long *pFlags)
48 if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
49 TRACE("MAKELONG(NDR_LOCAL_REPRESENTATION, ");
50 else
51 TRACE("MAKELONG(0x%04x, ", HIWORD(*pFlags));
52 switch (LOWORD(*pFlags))
54 case MSHCTX_LOCAL: TRACE("MSHCTX_LOCAL)"); break;
55 case MSHCTX_NOSHAREDMEM: TRACE("MSHCTX_NOSHAREDMEM)"); break;
56 case MSHCTX_DIFFERENTMACHINE: TRACE("MSHCTX_DIFFERENTMACHINE)"); break;
57 case MSHCTX_INPROC: TRACE("MSHCTX_INPROC)"); break;
58 default: TRACE("%d)", LOWORD(*pFlags));
62 unsigned long __RPC_USER CLIPFORMAT_UserSize(unsigned long *pFlags, unsigned long StartingSize, CLIPFORMAT *pCF)
64 unsigned long size = StartingSize;
66 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, pCF);
68 size += sizeof(userCLIPFORMAT);
70 /* only need to marshal the name if it is not a pre-defined type and
71 * we are going remote */
72 if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
74 WCHAR format[255];
75 INT ret;
76 size += 3 * sizeof(INT);
77 /* urg! this function is badly designed because it won't tell us how
78 * much space is needed without doing a dummy run of storing the
79 * name into a buffer */
80 ret = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
81 if (!ret)
82 RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
83 size += (ret + 1) * sizeof(WCHAR);
85 return size;
88 unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
90 wireCLIPFORMAT wirecf = (wireCLIPFORMAT)pBuffer;
92 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &0x%04x\n", pBuffer, *pCF);
94 wirecf->u.dwValue = *pCF;
95 pBuffer += sizeof(*wirecf);
97 /* only need to marshal the name if it is not a pre-defined type and
98 * we are going remote */
99 if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
101 WCHAR format[255];
102 INT len;
103 wirecf->fContext = WDT_REMOTE_CALL;
104 len = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
105 if (!len)
106 RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
107 len += 1;
108 *(INT *)pBuffer = len;
109 pBuffer += sizeof(INT);
110 *(INT *)pBuffer = 0;
111 pBuffer += sizeof(INT);
112 *(INT *)pBuffer = len;
113 pBuffer += sizeof(INT);
114 TRACE("marshaling format name %s\n", debugstr_wn(format, len-1));
115 lstrcpynW((LPWSTR)pBuffer, format, len);
116 pBuffer += len * sizeof(WCHAR);
117 *(WCHAR *)pBuffer = '\0';
118 pBuffer += sizeof(WCHAR);
120 else
121 wirecf->fContext = WDT_INPROC_CALL;
123 return pBuffer;
126 unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
128 wireCLIPFORMAT wirecf = (wireCLIPFORMAT)pBuffer;
130 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", pBuffer, pCF);
132 pBuffer += sizeof(*wirecf);
133 if (wirecf->fContext == WDT_INPROC_CALL)
134 *pCF = (CLIPFORMAT)wirecf->u.dwValue;
135 else if (wirecf->fContext == WDT_REMOTE_CALL)
137 CLIPFORMAT cf;
138 INT len = *(INT *)pBuffer;
139 pBuffer += sizeof(INT);
140 if (*(INT *)pBuffer != 0)
141 RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
142 pBuffer += sizeof(INT);
143 if (*(INT *)pBuffer != len)
144 RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
145 pBuffer += sizeof(INT);
146 if (((WCHAR *)pBuffer)[len] != '\0')
147 RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
148 TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer));
149 cf = RegisterClipboardFormatW((LPCWSTR)pBuffer);
150 pBuffer += (len + 1) * sizeof(WCHAR);
151 if (!cf)
152 RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
153 *pCF = cf;
155 else
156 /* code not really appropriate, but nearest I can find */
157 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
158 return pBuffer;
161 void __RPC_USER CLIPFORMAT_UserFree(unsigned long *pFlags, CLIPFORMAT *pCF)
163 /* there is no inverse of the RegisterClipboardFormat function,
164 * so nothing to do */
167 static unsigned long __RPC_USER handle_UserSize(unsigned long *pFlags, unsigned long StartingSize, HANDLE *handle)
169 if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
171 ERR("can't remote a local handle\n");
172 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
173 return StartingSize;
175 return StartingSize + sizeof(RemotableHandle);
178 static unsigned char * __RPC_USER handle_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HANDLE *handle)
180 RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
181 if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
183 ERR("can't remote a local handle\n");
184 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
185 return pBuffer;
187 remhandle->fContext = WDT_INPROC_CALL;
188 remhandle->u.hInproc = (LONG_PTR)*handle;
189 return pBuffer + sizeof(RemotableHandle);
192 static unsigned char * __RPC_USER handle_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, HANDLE *handle)
194 RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
195 if (remhandle->fContext != WDT_INPROC_CALL)
196 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
197 *handle = (HANDLE)remhandle->u.hInproc;
198 return pBuffer + sizeof(RemotableHandle);
201 static void __RPC_USER handle_UserFree(unsigned long *pFlags, HANDLE *phMenu)
203 /* nothing to do */
206 #define IMPL_WIREM_HANDLE(type) \
207 unsigned long __RPC_USER type##_UserSize(unsigned long *pFlags, unsigned long StartingSize, type *handle) \
209 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, handle); \
210 return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \
213 unsigned char * __RPC_USER type##_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, type *handle) \
215 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", pBuffer, *handle); \
216 return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \
219 unsigned char * __RPC_USER type##_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, type *handle) \
221 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", pBuffer, handle); \
222 return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \
225 void __RPC_USER type##_UserFree(unsigned long *pFlags, type *handle) \
227 TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *handle); \
228 return handle_UserFree(pFlags, (HANDLE *)handle); \
231 IMPL_WIREM_HANDLE(HACCEL)
232 IMPL_WIREM_HANDLE(HMENU)
233 IMPL_WIREM_HANDLE(HWND)
235 unsigned long __RPC_USER HGLOBAL_UserSize(unsigned long *pFlags, unsigned long StartingSize, HGLOBAL *phGlobal)
237 unsigned long size = StartingSize;
239 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, phGlobal);
241 ALIGN_LENGTH(size, 3);
243 size += sizeof(ULONG);
245 if (LOWORD(*pFlags == MSHCTX_INPROC))
246 size += sizeof(HGLOBAL);
247 else
249 size += sizeof(ULONG);
250 if (*phGlobal)
252 SIZE_T ret;
253 size += 3 * sizeof(ULONG);
254 ret = GlobalSize(*phGlobal);
255 size += (unsigned long)ret;
259 return size;
262 unsigned char * __RPC_USER HGLOBAL_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
264 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", pBuffer, *phGlobal);
266 ALIGN_POINTER(pBuffer, 3);
268 if (LOWORD(*pFlags == MSHCTX_INPROC))
270 if (sizeof(*phGlobal) == 8)
271 *(ULONG *)pBuffer = WDT_INPROC64_CALL;
272 else
273 *(ULONG *)pBuffer = WDT_INPROC_CALL;
274 pBuffer += sizeof(ULONG);
275 *(HGLOBAL *)pBuffer = *phGlobal;
276 pBuffer += sizeof(HGLOBAL);
278 else
280 *(ULONG *)pBuffer = WDT_REMOTE_CALL;
281 pBuffer += sizeof(ULONG);
282 *(ULONG *)pBuffer = (ULONG)*phGlobal;
283 pBuffer += sizeof(ULONG);
284 if (*phGlobal)
286 const unsigned char *memory;
287 SIZE_T size = GlobalSize(*phGlobal);
288 *(ULONG *)pBuffer = (ULONG)size;
289 pBuffer += sizeof(ULONG);
290 *(ULONG *)pBuffer = (ULONG)*phGlobal;
291 pBuffer += sizeof(ULONG);
292 *(ULONG *)pBuffer = (ULONG)size;
293 pBuffer += sizeof(ULONG);
295 memory = GlobalLock(*phGlobal);
296 memcpy(pBuffer, memory, size);
297 pBuffer += size;
298 GlobalUnlock(*phGlobal);
302 return pBuffer;
305 unsigned char * __RPC_USER HGLOBAL_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
307 ULONG fContext;
309 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", pBuffer, *phGlobal);
311 ALIGN_POINTER(pBuffer, 3);
313 fContext = *(ULONG *)pBuffer;
314 pBuffer += sizeof(ULONG);
316 if (((fContext == WDT_INPROC_CALL) && (sizeof(*phGlobal) < 8)) ||
317 ((fContext == WDT_INPROC64_CALL) && (sizeof(*phGlobal) == 8)))
319 *phGlobal = *(HGLOBAL *)pBuffer;
320 pBuffer += sizeof(*phGlobal);
322 else if (fContext == WDT_REMOTE_CALL)
324 ULONG handle;
326 handle = *(ULONG *)pBuffer;
327 pBuffer += sizeof(ULONG);
329 if (handle)
331 ULONG size;
332 void *memory;
334 size = *(ULONG *)pBuffer;
335 pBuffer += sizeof(ULONG);
336 /* redunancy is bad - it means you have to check consistancy like
337 * this: */
338 if (*(ULONG *)pBuffer != handle)
340 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
341 return pBuffer;
343 pBuffer += sizeof(ULONG);
344 /* redunancy is bad - it means you have to check consistancy like
345 * this: */
346 if (*(ULONG *)pBuffer != size)
348 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
349 return pBuffer;
351 pBuffer += sizeof(ULONG);
353 /* FIXME: check size is not too big */
355 *phGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
356 memory = GlobalLock(*phGlobal);
357 memcpy(memory, pBuffer, size);
358 pBuffer += size;
359 GlobalUnlock(*phGlobal);
361 else
362 *phGlobal = NULL;
364 else
365 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
367 return pBuffer;
370 void __RPC_USER HGLOBAL_UserFree(unsigned long *pFlags, HGLOBAL *phGlobal)
372 TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *phGlobal);
374 if (LOWORD(*pFlags != MSHCTX_INPROC) && *phGlobal)
375 GlobalFree(*phGlobal);
378 unsigned long __RPC_USER HBITMAP_UserSize(unsigned long *pFlags, unsigned long StartingSize, HBITMAP *phBmp)
380 FIXME(":stub\n");
381 return StartingSize;
384 unsigned char * __RPC_USER HBITMAP_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HBITMAP *phBmp)
386 FIXME(":stub\n");
387 return pBuffer;
390 unsigned char * __RPC_USER HBITMAP_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, HBITMAP *phBmp)
392 FIXME(":stub\n");
393 return pBuffer;
396 void __RPC_USER HBITMAP_UserFree(unsigned long *pFlags, HBITMAP *phBmp)
398 FIXME(":stub\n");
401 unsigned long __RPC_USER HDC_UserSize(unsigned long *pFlags, unsigned long StartingSize, HDC *phdc)
403 FIXME(":stub\n");
404 return StartingSize;
407 unsigned char * __RPC_USER HDC_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HDC *phdc)
409 FIXME(":stub\n");
410 return pBuffer;
413 unsigned char * __RPC_USER HDC_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, HDC *phdc)
415 FIXME(":stub\n");
416 return pBuffer;
419 void __RPC_USER HDC_UserFree(unsigned long *pFlags, HDC *phdc)
421 FIXME(":stub\n");
424 unsigned long __RPC_USER HPALETTE_UserSize(unsigned long *pFlags, unsigned long StartingSize, HPALETTE *phPal)
426 FIXME(":stub\n");
427 return StartingSize;
430 unsigned char * __RPC_USER HPALETTE_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
432 FIXME(":stub\n");
433 return pBuffer;
436 unsigned char * __RPC_USER HPALETTE_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
438 FIXME(":stub\n");
439 return pBuffer;
442 void __RPC_USER HPALETTE_UserFree(unsigned long *pFlags, HPALETTE *phPal)
444 FIXME(":stub\n");
448 unsigned long __RPC_USER HENHMETAFILE_UserSize(unsigned long *pFlags, unsigned long StartingSize, HENHMETAFILE *phEmf)
450 unsigned long size = StartingSize;
452 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, *phEmf);
454 size += sizeof(ULONG);
455 if (LOWORD(*pFlags) == MSHCTX_INPROC)
456 size += sizeof(ULONG_PTR);
457 else
459 size += sizeof(ULONG);
461 if (*phEmf)
463 UINT emfsize;
465 size += 2 * sizeof(ULONG);
466 emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL);
467 size += emfsize;
471 return size;
474 unsigned char * __RPC_USER HENHMETAFILE_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
476 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, &%p\n", pBuffer, *phEmf);
478 if (LOWORD(*pFlags) == MSHCTX_INPROC)
480 if (sizeof(*phEmf) == 8)
481 *(ULONG *)pBuffer = WDT_INPROC64_CALL;
482 else
483 *(ULONG *)pBuffer = WDT_INPROC_CALL;
484 pBuffer += sizeof(ULONG);
485 *(HENHMETAFILE *)pBuffer = *phEmf;
486 pBuffer += sizeof(HENHMETAFILE);
488 else
490 *(ULONG *)pBuffer = WDT_REMOTE_CALL;
491 pBuffer += sizeof(ULONG);
492 *(ULONG *)pBuffer = (ULONG)(ULONG_PTR)*phEmf;
493 pBuffer += sizeof(ULONG);
495 if (*phEmf)
497 UINT emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL);
499 *(ULONG *)pBuffer = emfsize;
500 pBuffer += sizeof(ULONG);
501 *(ULONG *)pBuffer = emfsize;
502 pBuffer += sizeof(ULONG);
503 GetEnhMetaFileBits(*phEmf, emfsize, pBuffer);
504 pBuffer += emfsize;
508 return pBuffer;
511 unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
513 ULONG fContext;
515 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", pBuffer, phEmf);
517 fContext = *(ULONG *)pBuffer;
518 pBuffer += sizeof(ULONG);
520 if (((fContext == WDT_INPROC_CALL) && (sizeof(*phEmf) < 8)) ||
521 ((fContext == WDT_INPROC64_CALL) && (sizeof(*phEmf) == 8)))
523 *phEmf = *(HENHMETAFILE *)pBuffer;
524 pBuffer += sizeof(*phEmf);
526 else if (fContext == WDT_REMOTE_CALL)
528 ULONG handle;
530 handle = *(ULONG *)pBuffer;
531 pBuffer += sizeof(ULONG);
533 if (handle)
535 ULONG size;
536 size = *(ULONG *)pBuffer;
537 pBuffer += sizeof(ULONG);
538 if (size != *(ULONG *)pBuffer)
540 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
541 return pBuffer;
543 pBuffer += sizeof(ULONG);
544 *phEmf = SetEnhMetaFileBits(size, pBuffer);
545 pBuffer += size;
547 else
548 *phEmf = NULL;
550 else
551 RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
553 return pBuffer;
556 void __RPC_USER HENHMETAFILE_UserFree(unsigned long *pFlags, HENHMETAFILE *phEmf)
558 TRACE("("); dump_user_flags(pFlags); TRACE(", &%p\n", *phEmf);
560 if (LOWORD(*pFlags) != MSHCTX_INPROC)
561 DeleteEnhMetaFile(*phEmf);
564 unsigned long __RPC_USER STGMEDIUM_UserSize(unsigned long *pFlags, unsigned long StartingSize, STGMEDIUM *pStgMedium)
566 unsigned long size = StartingSize;
568 TRACE("("); dump_user_flags(pFlags); TRACE(", %ld, %p\n", StartingSize, pStgMedium);
570 ALIGN_LENGTH(size, 3);
572 size += 2 * sizeof(DWORD);
573 if (pStgMedium->tymed != TYMED_NULL)
574 size += sizeof(DWORD);
576 switch (pStgMedium->tymed)
578 case TYMED_NULL:
579 TRACE("TYMED_NULL\n");
580 break;
581 case TYMED_HGLOBAL:
582 TRACE("TYMED_HGLOBAL\n");
583 size = HGLOBAL_UserSize(pFlags, size, &pStgMedium->u.hGlobal);
584 break;
585 case TYMED_FILE:
586 FIXME("TYMED_FILE\n");
587 break;
588 case TYMED_ISTREAM:
589 FIXME("TYMED_ISTREAM\n");
590 break;
591 case TYMED_ISTORAGE:
592 FIXME("TYMED_ISTORAGE\n");
593 break;
594 case TYMED_GDI:
595 FIXME("TYMED_GDI\n");
596 break;
597 case TYMED_MFPICT:
598 FIXME("TYMED_MFPICT\n");
599 break;
600 case TYMED_ENHMF:
601 TRACE("TYMED_ENHMF\n");
602 size = HENHMETAFILE_UserSize(pFlags, size, &pStgMedium->u.hEnhMetaFile);
603 break;
604 default:
605 RaiseException(DV_E_TYMED, 0, 0, NULL);
608 if (pStgMedium->pUnkForRelease)
609 FIXME("buffer size pUnkForRelease\n");
611 return size;
614 unsigned char * __RPC_USER STGMEDIUM_UserMarshal(unsigned long *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
616 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", pBuffer, pStgMedium);
618 ALIGN_POINTER(pBuffer, 3);
620 *(DWORD *)pBuffer = pStgMedium->tymed;
621 pBuffer += sizeof(DWORD);
622 if (pStgMedium->tymed != TYMED_NULL)
624 *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->u.pstg;
625 pBuffer += sizeof(DWORD);
627 *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->pUnkForRelease;
628 pBuffer += sizeof(DWORD);
630 switch (pStgMedium->tymed)
632 case TYMED_NULL:
633 TRACE("TYMED_NULL\n");
634 break;
635 case TYMED_HGLOBAL:
636 TRACE("TYMED_HGLOBAL\n");
637 pBuffer = HGLOBAL_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
638 break;
639 case TYMED_FILE:
640 FIXME("TYMED_FILE\n");
641 break;
642 case TYMED_ISTREAM:
643 FIXME("TYMED_ISTREAM\n");
644 break;
645 case TYMED_ISTORAGE:
646 FIXME("TYMED_ISTORAGE\n");
647 break;
648 case TYMED_GDI:
649 FIXME("TYMED_GDI\n");
650 break;
651 case TYMED_MFPICT:
652 FIXME("TYMED_MFPICT\n");
653 break;
654 case TYMED_ENHMF:
655 TRACE("TYMED_ENHMF\n");
656 pBuffer = HENHMETAFILE_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
657 break;
658 default:
659 RaiseException(DV_E_TYMED, 0, 0, NULL);
662 if (pStgMedium->pUnkForRelease)
663 FIXME("marshal pUnkForRelease\n");
665 return pBuffer;
668 unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
670 DWORD content;
671 DWORD releaseunk;
673 ALIGN_POINTER(pBuffer, 3);
675 TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", pBuffer, pStgMedium);
677 pStgMedium->tymed = *(DWORD *)pBuffer;
678 pBuffer += sizeof(DWORD);
679 if (pStgMedium->tymed != TYMED_NULL)
681 content = *(DWORD *)pBuffer;
682 pBuffer += sizeof(DWORD);
684 releaseunk = *(DWORD *)pBuffer;
685 pBuffer += sizeof(DWORD);
687 switch (pStgMedium->tymed)
689 case TYMED_NULL:
690 TRACE("TYMED_NULL\n");
691 break;
692 case TYMED_HGLOBAL:
693 TRACE("TYMED_HGLOBAL\n");
694 pBuffer = HGLOBAL_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
695 break;
696 case TYMED_FILE:
697 FIXME("TYMED_FILE\n");
698 break;
699 case TYMED_ISTREAM:
700 FIXME("TYMED_ISTREAM\n");
701 break;
702 case TYMED_ISTORAGE:
703 FIXME("TYMED_ISTORAGE\n");
704 break;
705 case TYMED_GDI:
706 FIXME("TYMED_GDI\n");
707 break;
708 case TYMED_MFPICT:
709 FIXME("TYMED_MFPICT\n");
710 break;
711 case TYMED_ENHMF:
712 TRACE("TYMED_ENHMF\n");
713 pBuffer = HENHMETAFILE_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
714 break;
715 default:
716 RaiseException(DV_E_TYMED, 0, 0, NULL);
719 pStgMedium->pUnkForRelease = NULL;
720 if (releaseunk)
721 FIXME("unmarshal pUnkForRelease\n");
723 return pBuffer;
726 void __RPC_USER STGMEDIUM_UserFree(unsigned long *pFlags, STGMEDIUM *pStgMedium)
728 TRACE("("); dump_user_flags(pFlags); TRACE(", %p\n", pStgMedium);
730 ReleaseStgMedium(pStgMedium);
733 unsigned long __RPC_USER ASYNC_STGMEDIUM_UserSize(unsigned long *pFlags, unsigned long StartingSize, ASYNC_STGMEDIUM *pStgMedium)
735 FIXME(":stub\n");
736 return StartingSize;
739 unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserMarshal( unsigned long *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
741 FIXME(":stub\n");
742 return pBuffer;
745 unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
747 FIXME(":stub\n");
748 return pBuffer;
751 void __RPC_USER ASYNC_STGMEDIUM_UserFree(unsigned long *pFlags, ASYNC_STGMEDIUM *pStgMedium)
753 FIXME(":stub\n");
756 unsigned long __RPC_USER FLAG_STGMEDIUM_UserSize(unsigned long *pFlags, unsigned long StartingSize, FLAG_STGMEDIUM *pStgMedium)
758 FIXME(":stub\n");
759 return StartingSize;
762 unsigned char * __RPC_USER FLAG_STGMEDIUM_UserMarshal( unsigned long *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
764 FIXME(":stub\n");
765 return pBuffer;
768 unsigned char * __RPC_USER FLAG_STGMEDIUM_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
770 FIXME(":stub\n");
771 return pBuffer;
774 void __RPC_USER FLAG_STGMEDIUM_UserFree(unsigned long *pFlags, FLAG_STGMEDIUM *pStgMedium)
776 FIXME(":stub\n");
779 unsigned long __RPC_USER SNB_UserSize(unsigned long *pFlags, unsigned long StartingSize, SNB *pSnb)
781 FIXME(":stub\n");
782 return StartingSize;
785 unsigned char * __RPC_USER SNB_UserMarshal( unsigned long *pFlags, unsigned char *pBuffer, SNB *pSnb)
787 FIXME(":stub\n");
788 return pBuffer;
791 unsigned char * __RPC_USER SNB_UserUnmarshal(unsigned long *pFlags, unsigned char *pBuffer, SNB *pSnb)
793 FIXME(":stub\n");
794 return pBuffer;
797 void __RPC_USER SNB_UserFree(unsigned long *pFlags, SNB *pSnb)
799 FIXME(":stub\n");