xref: /reactos/dll/win32/ole32/usrmarshal.c (revision 595b846d)
1 /*
2  * Miscellaneous Marshaling Routines
3  *
4  * Copyright 2005 Robert Shearman
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include "precomp.h"
22 
23 WINE_DEFAULT_DEBUG_CHANNEL(ole);
24 
25 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
26 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
27 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
28 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
29 
30 #define USER_MARSHAL_PTR_PREFIX \
31   ( (DWORD)'U'         | ( (DWORD)'s' << 8 ) | \
32   ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) )
33 
34 static const char* debugstr_user_flags(ULONG *pFlags)
35 {
36     char buf[12];
37     const char* loword;
38     switch (LOWORD(*pFlags))
39     {
40     case MSHCTX_LOCAL:
41         loword="MSHCTX_LOCAL";
42         break;
43     case MSHCTX_NOSHAREDMEM:
44         loword="MSHCTX_NOSHAREDMEM";
45         break;
46     case MSHCTX_DIFFERENTMACHINE:
47         loword="MSHCTX_DIFFERENTMACHINE";
48         break;
49     case MSHCTX_INPROC:
50         loword="MSHCTX_INPROC";
51         break;
52     default:
53         sprintf(buf, "%d", LOWORD(*pFlags));
54         loword=buf;
55     }
56 
57     if (HIWORD(*pFlags) == NDR_LOCAL_DATA_REPRESENTATION)
58         return wine_dbg_sprintf("MAKELONG(%s, NDR_LOCAL_DATA_REPRESENTATION)", loword);
59     else
60         return wine_dbg_sprintf("MAKELONG(%s, 0x%04x)", loword, HIWORD(*pFlags));
61 }
62 
63 /******************************************************************************
64  *           CLIPFORMAT_UserSize [OLE32.@]
65  *
66  * Calculates the buffer size required to marshal a clip format.
67  *
68  * PARAMS
69  *  pFlags       [I] Flags. See notes.
70  *  StartingSize [I] Starting size of the buffer. This value is added on to
71  *                   the buffer size required for the clip format.
72  *  pCF          [I] Clip format to size.
73  *
74  * RETURNS
75  *  The buffer size required to marshal a clip format plus the starting size.
76  *
77  * NOTES
78  *  Even though the function is documented to take a pointer to an unsigned
79  *  long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
80  *  the first parameter is an unsigned long.
81  *  This function is only intended to be called by the RPC runtime.
82  */
83 ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF)
84 {
85     TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), size, pCF);
86 
87     ALIGN_LENGTH(size, 3);
88 
89     size += 8;
90 
91     /* only need to marshal the name if it is not a pre-defined type and
92      * we are going remote */
93     if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
94     {
95         WCHAR format[255];
96         INT ret;
97         size += 3 * sizeof(UINT);
98         /* urg! this function is badly designed because it won't tell us how
99          * much space is needed without doing a dummy run of storing the
100          * name into a buffer */
101         ret = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
102         if (!ret)
103             RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
104         size += (ret + 1) * sizeof(WCHAR);
105     }
106     return size;
107 }
108 
109 /******************************************************************************
110  *           CLIPFORMAT_UserMarshal [OLE32.@]
111  *
112  * Marshals a clip format into a buffer.
113  *
114  * PARAMS
115  *  pFlags  [I] Flags. See notes.
116  *  pBuffer [I] Buffer to marshal the clip format into.
117  *  pCF     [I] Clip format to marshal.
118  *
119  * RETURNS
120  *  The end of the marshaled data in the buffer.
121  *
122  * NOTES
123  *  Even though the function is documented to take a pointer to an unsigned
124  *  long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
125  *  the first parameter is an unsigned long.
126  *  This function is only intended to be called by the RPC runtime.
127  */
128 unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
129 {
130     TRACE("(%s, %p, &0x%04x\n", debugstr_user_flags(pFlags), pBuffer, *pCF);
131 
132     ALIGN_POINTER(pBuffer, 3);
133 
134     /* only need to marshal the name if it is not a pre-defined type and
135      * we are going remote */
136     if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
137     {
138         WCHAR format[255];
139         UINT len;
140 
141         *(DWORD *)pBuffer = WDT_REMOTE_CALL;
142         pBuffer += 4;
143         *(DWORD *)pBuffer = *pCF;
144         pBuffer += 4;
145 
146         len = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
147         if (!len)
148             RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
149         len += 1;
150         *(UINT *)pBuffer = len;
151         pBuffer += sizeof(UINT);
152         *(UINT *)pBuffer = 0;
153         pBuffer += sizeof(UINT);
154         *(UINT *)pBuffer = len;
155         pBuffer += sizeof(UINT);
156         TRACE("marshaling format name %s\n", debugstr_w(format));
157         memcpy(pBuffer, format, len * sizeof(WCHAR));
158         pBuffer += len * sizeof(WCHAR);
159     }
160     else
161     {
162         *(DWORD *)pBuffer = WDT_INPROC_CALL;
163         pBuffer += 4;
164         *(DWORD *)pBuffer = *pCF;
165         pBuffer += 4;
166     }
167 
168     return pBuffer;
169 }
170 
171 /******************************************************************************
172  *           CLIPFORMAT_UserUnmarshal [OLE32.@]
173  *
174  * Unmarshals a clip format from a buffer.
175  *
176  * PARAMS
177  *  pFlags  [I] Flags. See notes.
178  *  pBuffer [I] Buffer to marshal the clip format from.
179  *  pCF     [O] Address that receive the unmarshaled clip format.
180  *
181  * RETURNS
182  *  The end of the marshaled data in the buffer.
183  *
184  * NOTES
185  *  Even though the function is documented to take a pointer to an unsigned
186  *  long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
187  *  the first parameter is an unsigned long.
188  *  This function is only intended to be called by the RPC runtime.
189  */
190 unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
191 {
192     LONG fContext;
193 
194     TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pCF);
195 
196     ALIGN_POINTER(pBuffer, 3);
197 
198     fContext = *(DWORD *)pBuffer;
199     pBuffer += 4;
200 
201     if (fContext == WDT_INPROC_CALL)
202     {
203         *pCF = *(CLIPFORMAT *)pBuffer;
204         pBuffer += 4;
205     }
206     else if (fContext == WDT_REMOTE_CALL)
207     {
208         CLIPFORMAT cf;
209         UINT len;
210 
211         /* pointer ID for registered clip format string */
212         if (*(DWORD *)pBuffer == 0)
213             RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
214         pBuffer += 4;
215 
216         len = *(UINT *)pBuffer;
217         pBuffer += sizeof(UINT);
218         if (*(UINT *)pBuffer != 0)
219             RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
220         pBuffer += sizeof(UINT);
221         if (*(UINT *)pBuffer != len)
222             RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
223         pBuffer += sizeof(UINT);
224         if (((WCHAR *)pBuffer)[len - 1] != '\0')
225             RaiseException(RPC_S_INVALID_BOUND, 0, 0, NULL);
226         TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer));
227         cf = RegisterClipboardFormatW((LPCWSTR)pBuffer);
228         pBuffer += len * sizeof(WCHAR);
229         if (!cf)
230             RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
231         *pCF = cf;
232     }
233     else
234         /* code not really appropriate, but nearest I can find */
235         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
236     return pBuffer;
237 }
238 
239 /******************************************************************************
240  *           CLIPFORMAT_UserFree [OLE32.@]
241  *
242  * Frees an unmarshaled clip format.
243  *
244  * PARAMS
245  *  pFlags  [I] Flags. See notes.
246  *  pCF     [I] Clip format to free.
247  *
248  * RETURNS
249  *  The end of the marshaled data in the buffer.
250  *
251  * NOTES
252  *  Even though the function is documented to take a pointer to an unsigned
253  *  long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB
254  *  structure, of which the first parameter is an unsigned long.
255  *  This function is only intended to be called by the RPC runtime.
256  */
257 void __RPC_USER CLIPFORMAT_UserFree(ULONG *pFlags, CLIPFORMAT *pCF)
258 {
259     /* there is no inverse of the RegisterClipboardFormat function,
260      * so nothing to do */
261 }
262 
263 static ULONG handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle)
264 {
265     if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
266     {
267         ERR("can't remote a local handle\n");
268         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
269         return StartingSize;
270     }
271 
272     ALIGN_LENGTH(StartingSize, 3);
273     return StartingSize + sizeof(RemotableHandle);
274 }
275 
276 static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
277 {
278     RemotableHandle *remhandle;
279     if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
280     {
281         ERR("can't remote a local handle\n");
282         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
283         return pBuffer;
284     }
285 
286     ALIGN_POINTER(pBuffer, 3);
287     remhandle = (RemotableHandle *)pBuffer;
288     remhandle->fContext = WDT_INPROC_CALL;
289     remhandle->u.hInproc = (LONG_PTR)*handle;
290     return pBuffer + sizeof(RemotableHandle);
291 }
292 
293 static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
294 {
295     RemotableHandle *remhandle;
296 
297     ALIGN_POINTER(pBuffer, 3);
298     remhandle = (RemotableHandle *)pBuffer;
299     if (remhandle->fContext != WDT_INPROC_CALL)
300         RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
301     *handle = (HANDLE)(LONG_PTR)remhandle->u.hInproc;
302     return pBuffer + sizeof(RemotableHandle);
303 }
304 
305 static void handle_UserFree(ULONG *pFlags, HANDLE *handle)
306 {
307     /* nothing to do */
308 }
309 
310 #define IMPL_WIREM_HANDLE(type) \
311     ULONG __RPC_USER type##_UserSize(ULONG *pFlags, ULONG StartingSize, type *handle) \
312     { \
313         TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, handle); \
314         return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \
315     } \
316     \
317     unsigned char * __RPC_USER type##_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
318     { \
319         TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *handle); \
320         return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \
321     } \
322     \
323     unsigned char * __RPC_USER type##_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
324     { \
325         TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, handle); \
326         return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \
327     } \
328     \
329     void __RPC_USER type##_UserFree(ULONG *pFlags, type *handle) \
330     { \
331         TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *handle); \
332         handle_UserFree(pFlags, (HANDLE *)handle); \
333     }
334 
335 IMPL_WIREM_HANDLE(HACCEL)
336 IMPL_WIREM_HANDLE(HMENU)
337 IMPL_WIREM_HANDLE(HWND)
338 IMPL_WIREM_HANDLE(HDC)
339 IMPL_WIREM_HANDLE(HICON)
340 IMPL_WIREM_HANDLE(HBRUSH)
341 
342 /******************************************************************************
343  *           HGLOBAL_UserSize [OLE32.@]
344  *
345  * Calculates the buffer size required to marshal an HGLOBAL.
346  *
347  * PARAMS
348  *  pFlags       [I] Flags. See notes.
349  *  StartingSize [I] Starting size of the buffer. This value is added on to
350  *                   the buffer size required for the clip format.
351  *  phGlobal     [I] HGLOBAL to size.
352  *
353  * RETURNS
354  *  The buffer size required to marshal an HGLOBAL plus the starting size.
355  *
356  * NOTES
357  *  Even though the function is documented to take a pointer to a ULONG in
358  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
359  *  the first parameter is a ULONG.
360  *  This function is only intended to be called by the RPC runtime.
361  */
362 ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal)
363 {
364     ULONG size = StartingSize;
365 
366     TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, phGlobal);
367 
368     ALIGN_LENGTH(size, 3);
369 
370     size += sizeof(ULONG);
371 
372     if (LOWORD(*pFlags == MSHCTX_INPROC))
373         size += sizeof(HGLOBAL);
374     else
375     {
376         size += sizeof(ULONG);
377         if (*phGlobal)
378         {
379             SIZE_T ret;
380             size += 3 * sizeof(ULONG);
381             ret = GlobalSize(*phGlobal);
382             size += (ULONG)ret;
383         }
384     }
385 
386     return size;
387 }
388 
389 /******************************************************************************
390  *           HGLOBAL_UserMarshal [OLE32.@]
391  *
392  * Marshals an HGLOBAL into a buffer.
393  *
394  * PARAMS
395  *  pFlags   [I] Flags. See notes.
396  *  pBuffer  [I] Buffer to marshal the clip format into.
397  *  phGlobal [I] HGLOBAL to marshal.
398  *
399  * RETURNS
400  *  The end of the marshaled data in the buffer.
401  *
402  * NOTES
403  *  Even though the function is documented to take a pointer to a ULONG in
404  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
405  *  the first parameter is a ULONG.
406  *  This function is only intended to be called by the RPC runtime.
407  */
408 unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
409 {
410     TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal);
411 
412     ALIGN_POINTER(pBuffer, 3);
413 
414     if (LOWORD(*pFlags == MSHCTX_INPROC))
415     {
416         if (sizeof(*phGlobal) == 8)
417             *(ULONG *)pBuffer = WDT_INPROC64_CALL;
418         else
419             *(ULONG *)pBuffer = WDT_INPROC_CALL;
420         pBuffer += sizeof(ULONG);
421         *(HGLOBAL *)pBuffer = *phGlobal;
422         pBuffer += sizeof(HGLOBAL);
423     }
424     else
425     {
426         *(ULONG *)pBuffer = WDT_REMOTE_CALL;
427         pBuffer += sizeof(ULONG);
428         *(ULONG *)pBuffer = HandleToULong(*phGlobal);
429         pBuffer += sizeof(ULONG);
430         if (*phGlobal)
431         {
432             const unsigned char *memory;
433             SIZE_T size = GlobalSize(*phGlobal);
434             *(ULONG *)pBuffer = (ULONG)size;
435             pBuffer += sizeof(ULONG);
436             *(ULONG *)pBuffer = HandleToULong(*phGlobal);
437             pBuffer += sizeof(ULONG);
438             *(ULONG *)pBuffer = (ULONG)size;
439             pBuffer += sizeof(ULONG);
440 
441             memory = GlobalLock(*phGlobal);
442             memcpy(pBuffer, memory, size);
443             pBuffer += size;
444             GlobalUnlock(*phGlobal);
445         }
446     }
447 
448     return pBuffer;
449 }
450 
451 /******************************************************************************
452  *           HGLOBAL_UserUnmarshal [OLE32.@]
453  *
454  * Unmarshals an HGLOBAL from a buffer.
455  *
456  * PARAMS
457  *  pFlags   [I] Flags. See notes.
458  *  pBuffer  [I] Buffer to marshal the clip format from.
459  *  phGlobal [O] Address that receive the unmarshaled HGLOBAL.
460  *
461  * RETURNS
462  *  The end of the marshaled data in the buffer.
463  *
464  * NOTES
465  *  Even though the function is documented to take a pointer to an ULONG in
466  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
467  *  the first parameter is an ULONG.
468  *  This function is only intended to be called by the RPC runtime.
469  */
470 unsigned char * __RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
471 {
472     ULONG fContext;
473 
474     TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal);
475 
476     ALIGN_POINTER(pBuffer, 3);
477 
478     fContext = *(ULONG *)pBuffer;
479     pBuffer += sizeof(ULONG);
480 
481     if (((fContext == WDT_INPROC_CALL) && (sizeof(*phGlobal) < 8)) ||
482         ((fContext == WDT_INPROC64_CALL) && (sizeof(*phGlobal) == 8)))
483     {
484         *phGlobal = *(HGLOBAL *)pBuffer;
485         pBuffer += sizeof(*phGlobal);
486     }
487     else if (fContext == WDT_REMOTE_CALL)
488     {
489         ULONG handle;
490 
491         handle = *(ULONG *)pBuffer;
492         pBuffer += sizeof(ULONG);
493 
494         if (handle)
495         {
496             ULONG size;
497             void *memory;
498 
499             size = *(ULONG *)pBuffer;
500             pBuffer += sizeof(ULONG);
501             /* redundancy is bad - it means you have to check consistency like
502              * this: */
503             if (*(ULONG *)pBuffer != handle)
504             {
505                 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
506                 return pBuffer;
507             }
508             pBuffer += sizeof(ULONG);
509             /* redundancy is bad - it means you have to check consistency like
510              * this: */
511             if (*(ULONG *)pBuffer != size)
512             {
513                 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
514                 return pBuffer;
515             }
516             pBuffer += sizeof(ULONG);
517 
518             /* FIXME: check size is not too big */
519 
520             *phGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
521             memory = GlobalLock(*phGlobal);
522             memcpy(memory, pBuffer, size);
523             pBuffer += size;
524             GlobalUnlock(*phGlobal);
525         }
526         else
527             *phGlobal = NULL;
528     }
529     else
530         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
531 
532     return pBuffer;
533 }
534 
535 /******************************************************************************
536  *           HGLOBAL_UserFree [OLE32.@]
537  *
538  * Frees an unmarshaled HGLOBAL.
539  *
540  * PARAMS
541  *  pFlags   [I] Flags. See notes.
542  *  phGlobal [I] HGLOBAL to free.
543  *
544  * RETURNS
545  *  The end of the marshaled data in the buffer.
546  *
547  * NOTES
548  *  Even though the function is documented to take a pointer to a ULONG in
549  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
550  *  which the first parameter is a ULONG.
551  *  This function is only intended to be called by the RPC runtime.
552  */
553 void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
554 {
555     TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phGlobal);
556 
557     if (LOWORD(*pFlags != MSHCTX_INPROC) && *phGlobal)
558         GlobalFree(*phGlobal);
559 }
560 
561 /******************************************************************************
562  *           HBITMAP_UserSize [OLE32.@]
563  *
564  * Calculates the buffer size required to marshal a bitmap.
565  *
566  * PARAMS
567  *  pFlags       [I] Flags. See notes.
568  *  StartingSize [I] Starting size of the buffer. This value is added on to
569  *                   the buffer size required for the clip format.
570  *  phBmp        [I] Bitmap to size.
571  *
572  * RETURNS
573  *  The buffer size required to marshal an bitmap plus the starting size.
574  *
575  * NOTES
576  *  Even though the function is documented to take a pointer to a ULONG in
577  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
578  *  the first parameter is a ULONG.
579  *  This function is only intended to be called by the RPC runtime.
580  */
581 ULONG __RPC_USER HBITMAP_UserSize(ULONG *flags, ULONG size, HBITMAP *bmp)
582 {
583     TRACE("(%s, %d, %p)\n", debugstr_user_flags(flags), size, *bmp);
584 
585     ALIGN_LENGTH(size, 3);
586 
587     size += sizeof(ULONG);
588     if (LOWORD(*flags) == MSHCTX_INPROC)
589         size += sizeof(ULONG);
590     else
591     {
592         size += sizeof(ULONG);
593 
594         if (*bmp)
595         {
596             size += sizeof(ULONG);
597             size += FIELD_OFFSET(userBITMAP, cbSize);
598             size += GetBitmapBits(*bmp, 0, NULL);
599         }
600     }
601 
602     return size;
603 }
604 
605 /******************************************************************************
606 *           HBITMAP_UserMarshal [OLE32.@]
607 *
608 * Marshals a bitmap into a buffer.
609 *
610 * PARAMS
611 *  pFlags  [I] Flags. See notes.
612 *  pBuffer [I] Buffer to marshal the clip format into.
613 *  phBmp   [I] Bitmap to marshal.
614 *
615 * RETURNS
616 *  The end of the marshaled data in the buffer.
617 *
618 * NOTES
619 *  Even though the function is documented to take a pointer to a ULONG in
620 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
621 *  the first parameter is a ULONG.
622 *  This function is only intended to be called by the RPC runtime.
623 */
624 unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
625 {
626     TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, *bmp);
627 
628     ALIGN_POINTER(buffer, 3);
629 
630     if (LOWORD(*flags) == MSHCTX_INPROC)
631     {
632         *(ULONG *)buffer = WDT_INPROC_CALL;
633         buffer += sizeof(ULONG);
634         *(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp;
635         buffer += sizeof(ULONG);
636     }
637     else
638     {
639         *(ULONG *)buffer = WDT_REMOTE_CALL;
640         buffer += sizeof(ULONG);
641         *(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp;
642         buffer += sizeof(ULONG);
643 
644         if (*bmp)
645         {
646             static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
647             BITMAP bitmap;
648             ULONG bitmap_size;
649 
650             bitmap_size = GetBitmapBits(*bmp, 0, NULL);
651             *(ULONG *)buffer = bitmap_size;
652             buffer += sizeof(ULONG);
653 
654             GetObjectW(*bmp, sizeof(BITMAP), &bitmap);
655             memcpy(buffer, &bitmap, header_size);
656             buffer += header_size;
657 
658             GetBitmapBits(*bmp, bitmap_size, buffer);
659             buffer += bitmap_size;
660         }
661     }
662     return buffer;
663 }
664 
665 /******************************************************************************
666  *           HBITMAP_UserUnmarshal [OLE32.@]
667  *
668  * Unmarshals a bitmap from a buffer.
669  *
670  * PARAMS
671  *  pFlags   [I] Flags. See notes.
672  *  pBuffer  [I] Buffer to marshal the clip format from.
673  *  phBmp    [O] Address that receive the unmarshaled bitmap.
674  *
675  * RETURNS
676  *  The end of the marshaled data in the buffer.
677  *
678  * NOTES
679  *  Even though the function is documented to take a pointer to an ULONG in
680  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
681  *  the first parameter is an ULONG.
682  *  This function is only intended to be called by the RPC runtime.
683  */
684 unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
685 {
686     ULONG context;
687 
688     TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, bmp);
689 
690     ALIGN_POINTER(buffer, 3);
691 
692     context = *(ULONG *)buffer;
693     buffer += sizeof(ULONG);
694 
695     if (context == WDT_INPROC_CALL)
696     {
697         *bmp = *(HBITMAP *)buffer;
698         buffer += sizeof(*bmp);
699     }
700     else if (context == WDT_REMOTE_CALL)
701     {
702         ULONG handle = *(ULONG *)buffer;
703         buffer += sizeof(ULONG);
704 
705         if (handle)
706         {
707             static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
708             BITMAP bitmap;
709             ULONG bitmap_size;
710             unsigned char *bits;
711 
712             bitmap_size = *(ULONG *)buffer;
713             buffer += sizeof(ULONG);
714             bits = HeapAlloc(GetProcessHeap(), 0, bitmap_size);
715 
716             memcpy(&bitmap, buffer, header_size);
717             buffer += header_size;
718 
719             memcpy(bits, buffer, bitmap_size);
720             buffer += bitmap_size;
721 
722             bitmap.bmBits = bits;
723             *bmp = CreateBitmapIndirect(&bitmap);
724 
725             HeapFree(GetProcessHeap(), 0, bits);
726         }
727         else
728             *bmp = NULL;
729     }
730     else
731         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
732 
733     return buffer;
734 }
735 
736 /******************************************************************************
737  *           HBITMAP_UserFree [OLE32.@]
738  *
739  * Frees an unmarshaled bitmap.
740  *
741  * PARAMS
742  *  pFlags   [I] Flags. See notes.
743  *  phBmp    [I] Bitmap to free.
744  *
745  * RETURNS
746  *  The end of the marshaled data in the buffer.
747  *
748  * NOTES
749  *  Even though the function is documented to take a pointer to a ULONG in
750  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
751  *  which the first parameter is a ULONG.
752  *  This function is only intended to be called by the RPC runtime.
753  */
754 void __RPC_USER HBITMAP_UserFree(ULONG *flags, HBITMAP *bmp)
755 {
756     TRACE("(%s, %p)\n", debugstr_user_flags(flags), *bmp);
757 
758     if (LOWORD(*flags) != MSHCTX_INPROC)
759         DeleteObject(*bmp);
760 }
761 
762 /******************************************************************************
763  *           HPALETTE_UserSize [OLE32.@]
764  *
765  * Calculates the buffer size required to marshal a palette.
766  *
767  * PARAMS
768  *  pFlags       [I] Flags. See notes.
769  *  StartingSize [I] Starting size of the buffer. This value is added on to
770  *                   the buffer size required for the clip format.
771  *  phPal        [I] Palette to size.
772  *
773  * RETURNS
774  *  The buffer size required to marshal a palette plus the starting size.
775  *
776  * NOTES
777  *  Even though the function is documented to take a pointer to a ULONG in
778  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
779  *  the first parameter is a ULONG.
780  *  This function is only intended to be called by the RPC runtime.
781  */
782 ULONG __RPC_USER HPALETTE_UserSize(ULONG *pFlags, ULONG StartingSize, HPALETTE *phPal)
783 {
784     FIXME(":stub\n");
785     return StartingSize;
786 }
787 
788 /******************************************************************************
789  *           HPALETTE_UserMarshal [OLE32.@]
790  *
791  * Marshals a palette into a buffer.
792  *
793  * PARAMS
794  *  pFlags  [I] Flags. See notes.
795  *  pBuffer [I] Buffer to marshal the clip format into.
796  *  phPal   [I] Palette to marshal.
797  *
798  * RETURNS
799  *  The end of the marshaled data in the buffer.
800  *
801  * NOTES
802  *  Even though the function is documented to take a pointer to a ULONG in
803  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
804  *  the first parameter is a ULONG.
805  *  This function is only intended to be called by the RPC runtime.
806  */
807 unsigned char * __RPC_USER HPALETTE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
808 {
809     FIXME(":stub\n");
810     return pBuffer;
811 }
812 
813 /******************************************************************************
814  *           HPALETTE_UserUnmarshal [OLE32.@]
815  *
816  * Unmarshals a palette from a buffer.
817  *
818  * PARAMS
819  *  pFlags   [I] Flags. See notes.
820  *  pBuffer  [I] Buffer to marshal the clip format from.
821  *  phPal    [O] Address that receive the unmarshaled palette.
822  *
823  * RETURNS
824  *  The end of the marshaled data in the buffer.
825  *
826  * NOTES
827  *  Even though the function is documented to take a pointer to an ULONG in
828  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
829  *  the first parameter is an ULONG.
830  *  This function is only intended to be called by the RPC runtime.
831  */
832 unsigned char * __RPC_USER HPALETTE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
833 {
834     FIXME(":stub\n");
835     return pBuffer;
836 }
837 
838 /******************************************************************************
839  *           HPALETTE_UserFree [OLE32.@]
840  *
841  * Frees an unmarshaled palette.
842  *
843  * PARAMS
844  *  pFlags   [I] Flags. See notes.
845  *  phPal    [I] Palette to free.
846  *
847  * RETURNS
848  *  The end of the marshaled data in the buffer.
849  *
850  * NOTES
851  *  Even though the function is documented to take a pointer to a ULONG in
852  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
853  *  which the first parameter is a ULONG.
854  *  This function is only intended to be called by the RPC runtime.
855  */
856 void __RPC_USER HPALETTE_UserFree(ULONG *pFlags, HPALETTE *phPal)
857 {
858     FIXME(":stub\n");
859 }
860 
861 
862 /******************************************************************************
863  *           HMETAFILE_UserSize [OLE32.@]
864  *
865  * Calculates the buffer size required to marshal a metafile.
866  *
867  * PARAMS
868  *  pFlags       [I] Flags. See notes.
869  *  StartingSize [I] Starting size of the buffer. This value is added on to
870  *                   the buffer size required for the clip format.
871  *  phmf         [I] Metafile to size.
872  *
873  * RETURNS
874  *  The buffer size required to marshal a metafile plus the starting size.
875  *
876  * NOTES
877  *  Even though the function is documented to take a pointer to a ULONG in
878  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
879  *  the first parameter is a ULONG.
880  *  This function is only intended to be called by the RPC runtime.
881  */
882 ULONG __RPC_USER HMETAFILE_UserSize(ULONG *pFlags, ULONG StartingSize, HMETAFILE *phmf)
883 {
884     ULONG size = StartingSize;
885 
886     TRACE("(%s, %d, &%p\n", debugstr_user_flags(pFlags), StartingSize, *phmf);
887 
888     ALIGN_LENGTH(size, 3);
889 
890     size += sizeof(ULONG);
891     if (LOWORD(*pFlags) == MSHCTX_INPROC)
892         size += sizeof(ULONG_PTR);
893     else
894     {
895         size += sizeof(ULONG);
896 
897         if (*phmf)
898         {
899             UINT mfsize;
900 
901             size += 2 * sizeof(ULONG);
902             mfsize = GetMetaFileBitsEx(*phmf, 0, NULL);
903             size += mfsize;
904         }
905     }
906 
907     return size;
908 }
909 
910 /******************************************************************************
911  *           HMETAFILE_UserMarshal [OLE32.@]
912  *
913  * Marshals a metafile into a buffer.
914  *
915  * PARAMS
916  *  pFlags  [I] Flags. See notes.
917  *  pBuffer [I] Buffer to marshal the clip format into.
918  *  phEmf   [I] Metafile to marshal.
919  *
920  * RETURNS
921  *  The end of the marshaled data in the buffer.
922  *
923  * NOTES
924  *  Even though the function is documented to take a pointer to a ULONG in
925  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
926  *  the first parameter is a ULONG.
927  *  This function is only intended to be called by the RPC runtime.
928  */
929 unsigned char * __RPC_USER HMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILE *phmf)
930 {
931     TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phmf);
932 
933     ALIGN_POINTER(pBuffer, 3);
934 
935     if (LOWORD(*pFlags) == MSHCTX_INPROC)
936     {
937         if (sizeof(*phmf) == 8)
938             *(ULONG *)pBuffer = WDT_INPROC64_CALL;
939         else
940             *(ULONG *)pBuffer = WDT_INPROC_CALL;
941         pBuffer += sizeof(ULONG);
942         *(HMETAFILE *)pBuffer = *phmf;
943         pBuffer += sizeof(HMETAFILE);
944     }
945     else
946     {
947         *(ULONG *)pBuffer = WDT_REMOTE_CALL;
948         pBuffer += sizeof(ULONG);
949         *(ULONG *)pBuffer = (ULONG)(ULONG_PTR)*phmf;
950         pBuffer += sizeof(ULONG);
951 
952         if (*phmf)
953         {
954             UINT mfsize = GetMetaFileBitsEx(*phmf, 0, NULL);
955 
956             *(ULONG *)pBuffer = mfsize;
957             pBuffer += sizeof(ULONG);
958             *(ULONG *)pBuffer = mfsize;
959             pBuffer += sizeof(ULONG);
960             GetMetaFileBitsEx(*phmf, mfsize, pBuffer);
961             pBuffer += mfsize;
962         }
963     }
964 
965     return pBuffer;
966 }
967 
968 /******************************************************************************
969  *           HMETAFILE_UserUnmarshal [OLE32.@]
970  *
971  * Unmarshals a metafile from a buffer.
972  *
973  * PARAMS
974  *  pFlags   [I] Flags. See notes.
975  *  pBuffer  [I] Buffer to marshal the clip format from.
976  *  phmf     [O] Address that receive the unmarshaled metafile.
977  *
978  * RETURNS
979  *  The end of the marshaled data in the buffer.
980  *
981  * NOTES
982  *  Even though the function is documented to take a pointer to an ULONG in
983  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
984  *  the first parameter is an ULONG.
985  *  This function is only intended to be called by the RPC runtime.
986  */
987 unsigned char * __RPC_USER HMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILE *phmf)
988 {
989     ULONG fContext;
990 
991     TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, phmf);
992 
993     ALIGN_POINTER(pBuffer, 3);
994 
995     fContext = *(ULONG *)pBuffer;
996     pBuffer += sizeof(ULONG);
997 
998     if (((fContext == WDT_INPROC_CALL) && (sizeof(*phmf) < 8)) ||
999         ((fContext == WDT_INPROC64_CALL) && (sizeof(*phmf) == 8)))
1000     {
1001         *phmf = *(HMETAFILE *)pBuffer;
1002         pBuffer += sizeof(*phmf);
1003     }
1004     else if (fContext == WDT_REMOTE_CALL)
1005     {
1006         ULONG handle;
1007 
1008         handle = *(ULONG *)pBuffer;
1009         pBuffer += sizeof(ULONG);
1010 
1011         if (handle)
1012         {
1013             ULONG size;
1014             size = *(ULONG *)pBuffer;
1015             pBuffer += sizeof(ULONG);
1016             if (size != *(ULONG *)pBuffer)
1017             {
1018                 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
1019                 return pBuffer;
1020             }
1021             pBuffer += sizeof(ULONG);
1022             *phmf = SetMetaFileBitsEx(size, pBuffer);
1023             pBuffer += size;
1024         }
1025         else
1026             *phmf = NULL;
1027     }
1028     else
1029         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
1030 
1031     return pBuffer;
1032 }
1033 
1034 /******************************************************************************
1035  *           HMETAFILE_UserFree [OLE32.@]
1036  *
1037  * Frees an unmarshaled metafile.
1038  *
1039  * PARAMS
1040  *  pFlags   [I] Flags. See notes.
1041  *  phmf     [I] Metafile to free.
1042  *
1043  * RETURNS
1044  *  The end of the marshaled data in the buffer.
1045  *
1046  * NOTES
1047  *  Even though the function is documented to take a pointer to a ULONG in
1048  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
1049  *  which the first parameter is a ULONG.
1050  *  This function is only intended to be called by the RPC runtime.
1051  */
1052 void __RPC_USER HMETAFILE_UserFree(ULONG *pFlags, HMETAFILE *phmf)
1053 {
1054     TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phmf);
1055 
1056     if (LOWORD(*pFlags) != MSHCTX_INPROC)
1057         DeleteMetaFile(*phmf);
1058 }
1059 
1060 /******************************************************************************
1061 *           HENHMETAFILE_UserSize [OLE32.@]
1062 *
1063 * Calculates the buffer size required to marshal an enhanced metafile.
1064 *
1065 * PARAMS
1066 *  pFlags       [I] Flags. See notes.
1067 *  StartingSize [I] Starting size of the buffer. This value is added on to
1068 *                   the buffer size required for the clip format.
1069 *  phEmf        [I] Enhanced metafile to size.
1070 *
1071 * RETURNS
1072 *  The buffer size required to marshal an enhanced metafile plus the starting size.
1073 *
1074 * NOTES
1075 *  Even though the function is documented to take a pointer to a ULONG in
1076 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1077 *  the first parameter is a ULONG.
1078 *  This function is only intended to be called by the RPC runtime.
1079 */
1080 ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG size, HENHMETAFILE *phEmf)
1081 {
1082     TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), size, *phEmf);
1083 
1084     ALIGN_LENGTH(size, 3);
1085 
1086     size += sizeof(ULONG);
1087     if (LOWORD(*pFlags) == MSHCTX_INPROC)
1088         size += sizeof(ULONG_PTR);
1089     else
1090     {
1091         size += sizeof(ULONG);
1092 
1093         if (*phEmf)
1094         {
1095             UINT emfsize;
1096 
1097             size += 2 * sizeof(ULONG);
1098             emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL);
1099             size += emfsize;
1100         }
1101     }
1102 
1103     return size;
1104 }
1105 
1106 /******************************************************************************
1107  *           HENHMETAFILE_UserMarshal [OLE32.@]
1108  *
1109  * Marshals an enhance metafile into a buffer.
1110  *
1111  * PARAMS
1112  *  pFlags  [I] Flags. See notes.
1113  *  pBuffer [I] Buffer to marshal the clip format into.
1114  *  phEmf   [I] Enhanced metafile to marshal.
1115  *
1116  * RETURNS
1117  *  The end of the marshaled data in the buffer.
1118  *
1119  * NOTES
1120  *  Even though the function is documented to take a pointer to a ULONG in
1121  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1122  *  the first parameter is a ULONG.
1123  *  This function is only intended to be called by the RPC runtime.
1124  */
1125 unsigned char * __RPC_USER HENHMETAFILE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
1126 {
1127     TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phEmf);
1128 
1129     ALIGN_POINTER(pBuffer, 3);
1130 
1131     if (LOWORD(*pFlags) == MSHCTX_INPROC)
1132     {
1133         if (sizeof(*phEmf) == 8)
1134             *(ULONG *)pBuffer = WDT_INPROC64_CALL;
1135         else
1136             *(ULONG *)pBuffer = WDT_INPROC_CALL;
1137         pBuffer += sizeof(ULONG);
1138         *(HENHMETAFILE *)pBuffer = *phEmf;
1139         pBuffer += sizeof(HENHMETAFILE);
1140     }
1141     else
1142     {
1143         *(ULONG *)pBuffer = WDT_REMOTE_CALL;
1144         pBuffer += sizeof(ULONG);
1145         *(ULONG *)pBuffer = (ULONG)(ULONG_PTR)*phEmf;
1146         pBuffer += sizeof(ULONG);
1147 
1148         if (*phEmf)
1149         {
1150             UINT emfsize = GetEnhMetaFileBits(*phEmf, 0, NULL);
1151 
1152             *(ULONG *)pBuffer = emfsize;
1153             pBuffer += sizeof(ULONG);
1154             *(ULONG *)pBuffer = emfsize;
1155             pBuffer += sizeof(ULONG);
1156             GetEnhMetaFileBits(*phEmf, emfsize, pBuffer);
1157             pBuffer += emfsize;
1158         }
1159     }
1160 
1161     return pBuffer;
1162 }
1163 
1164 /******************************************************************************
1165  *           HENHMETAFILE_UserUnmarshal [OLE32.@]
1166  *
1167  * Unmarshals an enhanced metafile from a buffer.
1168  *
1169  * PARAMS
1170  *  pFlags   [I] Flags. See notes.
1171  *  pBuffer  [I] Buffer to marshal the clip format from.
1172  *  phEmf    [O] Address that receive the unmarshaled enhanced metafile.
1173  *
1174  * RETURNS
1175  *  The end of the marshaled data in the buffer.
1176  *
1177  * NOTES
1178  *  Even though the function is documented to take a pointer to an ULONG in
1179  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1180  *  the first parameter is an ULONG.
1181  *  This function is only intended to be called by the RPC runtime.
1182  */
1183 unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HENHMETAFILE *phEmf)
1184 {
1185     ULONG fContext;
1186 
1187     TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, phEmf);
1188 
1189     ALIGN_POINTER(pBuffer, 3);
1190 
1191     fContext = *(ULONG *)pBuffer;
1192     pBuffer += sizeof(ULONG);
1193 
1194     if (((fContext == WDT_INPROC_CALL) && (sizeof(*phEmf) < 8)) ||
1195         ((fContext == WDT_INPROC64_CALL) && (sizeof(*phEmf) == 8)))
1196     {
1197         *phEmf = *(HENHMETAFILE *)pBuffer;
1198         pBuffer += sizeof(*phEmf);
1199     }
1200     else if (fContext == WDT_REMOTE_CALL)
1201     {
1202         ULONG handle;
1203 
1204         handle = *(ULONG *)pBuffer;
1205         pBuffer += sizeof(ULONG);
1206 
1207         if (handle)
1208         {
1209             ULONG size;
1210             size = *(ULONG *)pBuffer;
1211             pBuffer += sizeof(ULONG);
1212             if (size != *(ULONG *)pBuffer)
1213             {
1214                 RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
1215                 return pBuffer;
1216             }
1217             pBuffer += sizeof(ULONG);
1218             *phEmf = SetEnhMetaFileBits(size, pBuffer);
1219             pBuffer += size;
1220         }
1221         else
1222             *phEmf = NULL;
1223     }
1224     else
1225         RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
1226 
1227     return pBuffer;
1228 }
1229 
1230 /******************************************************************************
1231  *           HENHMETAFILE_UserFree [OLE32.@]
1232  *
1233  * Frees an unmarshaled enhanced metafile.
1234  *
1235  * PARAMS
1236  *  pFlags   [I] Flags. See notes.
1237  *  phEmf    [I] Enhanced metafile to free.
1238  *
1239  * RETURNS
1240  *  The end of the marshaled data in the buffer.
1241  *
1242  * NOTES
1243  *  Even though the function is documented to take a pointer to a ULONG in
1244  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
1245  *  which the first parameter is a ULONG.
1246  *  This function is only intended to be called by the RPC runtime.
1247  */
1248 void __RPC_USER HENHMETAFILE_UserFree(ULONG *pFlags, HENHMETAFILE *phEmf)
1249 {
1250     TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phEmf);
1251 
1252     if (LOWORD(*pFlags) != MSHCTX_INPROC)
1253         DeleteEnhMetaFile(*phEmf);
1254 }
1255 
1256 /******************************************************************************
1257  *           HMETAFILEPICT_UserSize [OLE32.@]
1258  *
1259  * Calculates the buffer size required to marshal an metafile pict.
1260  *
1261  * PARAMS
1262  *  pFlags       [I] Flags. See notes.
1263  *  StartingSize [I] Starting size of the buffer. This value is added on to
1264  *                   the buffer size required for the clip format.
1265  *  phMfp        [I] Metafile pict to size.
1266  *
1267  * RETURNS
1268  *  The buffer size required to marshal a metafile pict plus the starting size.
1269  *
1270  * NOTES
1271  *  Even though the function is documented to take a pointer to a ULONG in
1272  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1273  *  the first parameter is a ULONG.
1274  *  This function is only intended to be called by the RPC runtime.
1275  */
1276 ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG size, HMETAFILEPICT *phMfp)
1277 {
1278     TRACE("(%s, %d, &%p)\n", debugstr_user_flags(pFlags), size, *phMfp);
1279 
1280     ALIGN_LENGTH(size, 3);
1281 
1282     size += sizeof(ULONG);
1283 
1284     if(LOWORD(*pFlags) == MSHCTX_INPROC)
1285         size += sizeof(HMETAFILEPICT);
1286     else
1287     {
1288         size += sizeof(ULONG);
1289 
1290         if (*phMfp)
1291         {
1292             METAFILEPICT *mfpict = GlobalLock(*phMfp);
1293 
1294             /* FIXME: raise an exception if mfpict is NULL? */
1295             size += 3 * sizeof(ULONG);
1296             size += sizeof(ULONG);
1297 
1298             size = HMETAFILE_UserSize(pFlags, size, &mfpict->hMF);
1299 
1300             GlobalUnlock(*phMfp);
1301         }
1302     }
1303 
1304     return size;
1305 }
1306 
1307 /******************************************************************************
1308  *           HMETAFILEPICT_UserMarshal [OLE32.@]
1309  *
1310  * Marshals a metafile pict into a buffer.
1311  *
1312  * PARAMS
1313  *  pFlags  [I] Flags. See notes.
1314  *  pBuffer [I] Buffer to marshal the clip format into.
1315  *  phMfp   [I] Metafile pict to marshal.
1316  *
1317  * RETURNS
1318  *  The end of the marshaled data in the buffer.
1319  *
1320  * NOTES
1321  *  Even though the function is documented to take a pointer to a ULONG in
1322  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1323  *  the first parameter is a ULONG.
1324  *  This function is only intended to be called by the RPC runtime.
1325  */
1326 unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILEPICT *phMfp)
1327 {
1328     TRACE("(%s, %p, &%p)\n", debugstr_user_flags(pFlags), pBuffer, *phMfp);
1329 
1330     ALIGN_POINTER(pBuffer, 3);
1331 
1332     if (LOWORD(*pFlags) == MSHCTX_INPROC)
1333     {
1334         if (sizeof(HMETAFILEPICT) == 8)
1335             *(ULONG *)pBuffer = WDT_INPROC64_CALL;
1336         else
1337             *(ULONG *)pBuffer = WDT_INPROC_CALL;
1338         pBuffer += sizeof(ULONG);
1339         *(HMETAFILEPICT *)pBuffer = *phMfp;
1340         pBuffer += sizeof(HMETAFILEPICT);
1341     }
1342     else
1343     {
1344         *(ULONG *)pBuffer = WDT_REMOTE_CALL;
1345         pBuffer += sizeof(ULONG);
1346         *(ULONG *)pBuffer = (ULONG)(ULONG_PTR)*phMfp;
1347         pBuffer += sizeof(ULONG);
1348 
1349         if (*phMfp)
1350         {
1351             METAFILEPICT *mfpict = GlobalLock(*phMfp);
1352             remoteMETAFILEPICT * remmfpict = (remoteMETAFILEPICT *)pBuffer;
1353 
1354             /* FIXME: raise an exception if mfpict is NULL? */
1355             remmfpict->mm = mfpict->mm;
1356             remmfpict->xExt = mfpict->xExt;
1357             remmfpict->yExt = mfpict->yExt;
1358             pBuffer += 3 * sizeof(ULONG);
1359             *(ULONG *)pBuffer = USER_MARSHAL_PTR_PREFIX;
1360             pBuffer += sizeof(ULONG);
1361 
1362             pBuffer = HMETAFILE_UserMarshal(pFlags, pBuffer, &mfpict->hMF);
1363 
1364             GlobalUnlock(*phMfp);
1365         }
1366     }
1367     return pBuffer;
1368 }
1369 
1370 /******************************************************************************
1371  *           HMETAFILEPICT_UserUnmarshal [OLE32.@]
1372  *
1373  * Unmarshals an metafile pict from a buffer.
1374  *
1375  * PARAMS
1376  *  pFlags   [I] Flags. See notes.
1377  *  pBuffer  [I] Buffer to marshal the clip format from.
1378  *  phMfp    [O] Address that receive the unmarshaled metafile pict.
1379  *
1380  * RETURNS
1381  *  The end of the marshaled data in the buffer.
1382  *
1383  * NOTES
1384  *  Even though the function is documented to take a pointer to an ULONG in
1385  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1386  *  the first parameter is an ULONG.
1387  *  This function is only intended to be called by the RPC runtime.
1388  */
1389 unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HMETAFILEPICT *phMfp)
1390 {
1391     ULONG fContext;
1392 
1393     TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, phMfp);
1394 
1395     ALIGN_POINTER(pBuffer, 3);
1396 
1397     fContext = *(ULONG *)pBuffer;
1398     pBuffer += sizeof(ULONG);
1399 
1400     if ((fContext == WDT_INPROC_CALL) || fContext == WDT_INPROC64_CALL)
1401     {
1402         *phMfp = *(HMETAFILEPICT *)pBuffer;
1403         pBuffer += sizeof(HMETAFILEPICT);
1404     }
1405     else
1406     {
1407         ULONG handle = *(ULONG *)pBuffer;
1408         pBuffer += sizeof(ULONG);
1409         *phMfp = NULL;
1410 
1411         if(handle)
1412         {
1413             METAFILEPICT *mfpict;
1414             const remoteMETAFILEPICT *remmfpict;
1415             ULONG user_marshal_prefix;
1416 
1417             remmfpict = (const remoteMETAFILEPICT *)pBuffer;
1418 
1419             *phMfp = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT));
1420             if (!*phMfp)
1421                 RpcRaiseException(E_OUTOFMEMORY);
1422 
1423             mfpict = GlobalLock(*phMfp);
1424             mfpict->mm = remmfpict->mm;
1425             mfpict->xExt = remmfpict->xExt;
1426             mfpict->yExt = remmfpict->yExt;
1427             pBuffer += 3 * sizeof(ULONG);
1428             user_marshal_prefix = *(ULONG *)pBuffer;
1429             pBuffer += sizeof(ULONG);
1430 
1431             if (user_marshal_prefix != USER_MARSHAL_PTR_PREFIX)
1432                 RpcRaiseException(RPC_X_INVALID_TAG);
1433 
1434             pBuffer = HMETAFILE_UserUnmarshal(pFlags, pBuffer, &mfpict->hMF);
1435 
1436             GlobalUnlock(*phMfp);
1437         }
1438     }
1439     return pBuffer;
1440 }
1441 
1442 /******************************************************************************
1443  *           HMETAFILEPICT_UserFree [OLE32.@]
1444  *
1445  * Frees an unmarshaled metafile pict.
1446  *
1447  * PARAMS
1448  *  pFlags   [I] Flags. See notes.
1449  *  phMfp    [I] Metafile pict to free.
1450  *
1451  * RETURNS
1452  *  The end of the marshaled data in the buffer.
1453  *
1454  * NOTES
1455  *  Even though the function is documented to take a pointer to a ULONG in
1456  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
1457  *  which the first parameter is a ULONG.
1458  *  This function is only intended to be called by the RPC runtime.
1459  */
1460 void __RPC_USER HMETAFILEPICT_UserFree(ULONG *pFlags, HMETAFILEPICT *phMfp)
1461 {
1462     TRACE("(%s, &%p)\n", debugstr_user_flags(pFlags), *phMfp);
1463 
1464     if ((LOWORD(*pFlags) != MSHCTX_INPROC) && *phMfp)
1465     {
1466         METAFILEPICT *mfpict;
1467 
1468         mfpict = GlobalLock(*phMfp);
1469         /* FIXME: raise an exception if mfpict is NULL? */
1470         HMETAFILE_UserFree(pFlags, &mfpict->hMF);
1471         GlobalUnlock(*phMfp);
1472 
1473         GlobalFree(*phMfp);
1474     }
1475 }
1476 
1477 /******************************************************************************
1478  *           WdtpInterfacePointer_UserSize [OLE32.@]
1479  *
1480  * Calculates the buffer size required to marshal an interface pointer.
1481  *
1482  * PARAMS
1483  *  pFlags       [I] Flags. See notes.
1484  *  RealFlags    [I] The MSHCTX to use when marshaling the interface.
1485  *  punk         [I] Interface pointer to size.
1486  *  StartingSize [I] Starting size of the buffer. This value is added on to
1487  *                   the buffer size required for the clip format.
1488  *  riid         [I] ID of interface to size.
1489  *
1490  * RETURNS
1491  *  The buffer size required to marshal an interface pointer plus the starting size.
1492  *
1493  * NOTES
1494  *  Even though the function is documented to take a pointer to a ULONG in
1495  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1496  *  the first parameter is a ULONG.
1497  */
1498 ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
1499 {
1500     DWORD marshal_size = 0;
1501     HRESULT hr;
1502 
1503     TRACE("(%s, 0%x, %d, %p, %s)\n", debugstr_user_flags(pFlags), RealFlags, StartingSize, punk, debugstr_guid(riid));
1504 
1505     hr = CoGetMarshalSizeMax(&marshal_size, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL);
1506     if(FAILED(hr)) return StartingSize;
1507 
1508     ALIGN_LENGTH(StartingSize, 3);
1509     StartingSize += 2 * sizeof(DWORD);
1510     return StartingSize + marshal_size;
1511 }
1512 
1513 /******************************************************************************
1514  *           WdtpInterfacePointer_UserMarshal [OLE32.@]
1515  *
1516  * Marshals an interface pointer into a buffer.
1517  *
1518  * PARAMS
1519  *  pFlags    [I] Flags. See notes.
1520  *  RealFlags [I] The MSHCTX to use when marshaling the interface.
1521  *  pBuffer   [I] Buffer to marshal the clip format into.
1522  *  punk      [I] Interface pointer to marshal.
1523  *  riid      [I] ID of interface to marshal.
1524  *
1525  * RETURNS
1526  *  The end of the marshaled data in the buffer.
1527  *
1528  * NOTES
1529  *  Even though the function is documented to take a pointer to a ULONG in
1530  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1531  *  the first parameter is a ULONG.
1532  */
1533 unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
1534 {
1535     HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, 0);
1536     IStream *stm;
1537     DWORD size;
1538     void *ptr;
1539 
1540     TRACE("(%s, 0x%x, %p, &%p, %s)\n", debugstr_user_flags(pFlags), RealFlags, pBuffer, punk, debugstr_guid(riid));
1541 
1542     if(!h) return NULL;
1543     if(CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
1544     {
1545         GlobalFree(h);
1546         return NULL;
1547     }
1548 
1549     if(CoMarshalInterface(stm, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL) != S_OK)
1550     {
1551         IStream_Release(stm);
1552         return pBuffer;
1553     }
1554 
1555     ALIGN_POINTER(pBuffer, 3);
1556     size = GlobalSize(h);
1557 
1558     *(DWORD *)pBuffer = size;
1559     pBuffer += sizeof(DWORD);
1560     *(DWORD *)pBuffer = size;
1561     pBuffer += sizeof(DWORD);
1562 
1563     ptr = GlobalLock(h);
1564     memcpy(pBuffer, ptr, size);
1565     GlobalUnlock(h);
1566 
1567     IStream_Release(stm);
1568     return pBuffer + size;
1569 }
1570 
1571 /******************************************************************************
1572  *           WdtpInterfacePointer_UserUnmarshal [OLE32.@]
1573  *
1574  * Unmarshals an interface pointer from a buffer.
1575  *
1576  * PARAMS
1577  *  pFlags   [I] Flags. See notes.
1578  *  pBuffer  [I] Buffer to marshal the clip format from.
1579  *  ppunk    [I/O] Address that receives the unmarshaled interface pointer.
1580  *  riid     [I] ID of interface to unmarshal.
1581  *
1582  * RETURNS
1583  *  The end of the marshaled data in the buffer.
1584  *
1585  * NOTES
1586  *  Even though the function is documented to take a pointer to an ULONG in
1587  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1588  *  the first parameter is an ULONG.
1589  */
1590 unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
1591 {
1592     HRESULT hr;
1593     HGLOBAL h;
1594     IStream *stm;
1595     DWORD size;
1596     void *ptr;
1597     IUnknown *orig;
1598 
1599     TRACE("(%s, %p, %p, %s)\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
1600 
1601     ALIGN_POINTER(pBuffer, 3);
1602 
1603     size = *(DWORD *)pBuffer;
1604     pBuffer += sizeof(DWORD);
1605     if(size != *(DWORD *)pBuffer)
1606         RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
1607 
1608     pBuffer += sizeof(DWORD);
1609 
1610     /* FIXME: sanity check on size */
1611 
1612     h = GlobalAlloc(GMEM_MOVEABLE, size);
1613     if(!h) RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
1614 
1615     if(CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
1616     {
1617         GlobalFree(h);
1618         RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
1619     }
1620 
1621     ptr = GlobalLock(h);
1622     memcpy(ptr, pBuffer, size);
1623     GlobalUnlock(h);
1624 
1625     orig = *ppunk;
1626     hr = CoUnmarshalInterface(stm, riid, (void**)ppunk);
1627     IStream_Release(stm);
1628 
1629     if(hr != S_OK) RaiseException(hr, 0, 0, NULL);
1630 
1631     if(orig) IUnknown_Release(orig);
1632 
1633     return pBuffer + size;
1634 }
1635 
1636 /******************************************************************************
1637  *           WdtpInterfacePointer_UserFree [OLE32.@]
1638  *
1639  * Releases an unmarshaled interface pointer.
1640  *
1641  * PARAMS
1642  *  punk    [I] Interface pointer to release.
1643  *
1644  * RETURNS
1645  *  Nothing.
1646  */
1647 void WINAPI WdtpInterfacePointer_UserFree(IUnknown *punk)
1648 {
1649     TRACE("(%p)\n", punk);
1650     if(punk) IUnknown_Release(punk);
1651 }
1652 
1653 /******************************************************************************
1654 *           STGMEDIUM_UserSize [OLE32.@]
1655 *
1656 * Calculates the buffer size required to marshal an STGMEDIUM.
1657 *
1658 * PARAMS
1659 *  pFlags       [I] Flags. See notes.
1660 *  StartingSize [I] Starting size of the buffer. This value is added on to
1661 *                   the buffer size required for the clip format.
1662 *  pStgMedium   [I] STGMEDIUM to size.
1663 *
1664 * RETURNS
1665 *  The buffer size required to marshal an STGMEDIUM plus the starting size.
1666 *
1667 * NOTES
1668 *  Even though the function is documented to take a pointer to a ULONG in
1669 *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1670 *  the first parameter is a ULONG.
1671 *  This function is only intended to be called by the RPC runtime.
1672 */
1673 ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM *pStgMedium)
1674 {
1675     ULONG size = StartingSize;
1676 
1677     TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pStgMedium);
1678 
1679     ALIGN_LENGTH(size, 3);
1680 
1681     size += 2 * sizeof(DWORD);
1682     if (pStgMedium->tymed != TYMED_NULL)
1683         size += sizeof(DWORD);
1684 
1685     switch (pStgMedium->tymed)
1686     {
1687     case TYMED_NULL:
1688         TRACE("TYMED_NULL\n");
1689         break;
1690     case TYMED_HGLOBAL:
1691         TRACE("TYMED_HGLOBAL\n");
1692         if (pStgMedium->u.hGlobal)
1693             size = HGLOBAL_UserSize(pFlags, size, &pStgMedium->u.hGlobal);
1694         break;
1695     case TYMED_FILE:
1696         TRACE("TYMED_FILE\n");
1697         if (pStgMedium->u.lpszFileName)
1698         {
1699             TRACE("file name is %s\n", debugstr_w(pStgMedium->u.lpszFileName));
1700             size += 3 * sizeof(DWORD) +
1701                 (strlenW(pStgMedium->u.lpszFileName) + 1) * sizeof(WCHAR);
1702         }
1703         break;
1704     case TYMED_ISTREAM:
1705         TRACE("TYMED_ISTREAM\n");
1706         if (pStgMedium->u.pstm)
1707         {
1708             IUnknown *unk;
1709             IStream_QueryInterface(pStgMedium->u.pstm, &IID_IUnknown, (void**)&unk);
1710             size = WdtpInterfacePointer_UserSize(pFlags, LOWORD(*pFlags), size, unk, &IID_IStream);
1711             IUnknown_Release(unk);
1712         }
1713         break;
1714     case TYMED_ISTORAGE:
1715         TRACE("TYMED_ISTORAGE\n");
1716         if (pStgMedium->u.pstg)
1717         {
1718             IUnknown *unk;
1719             IStorage_QueryInterface(pStgMedium->u.pstg, &IID_IUnknown, (void**)&unk);
1720             size = WdtpInterfacePointer_UserSize(pFlags, LOWORD(*pFlags), size, unk, &IID_IStorage);
1721             IUnknown_Release(unk);
1722         }
1723         break;
1724     case TYMED_GDI:
1725         TRACE("TYMED_GDI\n");
1726         if (pStgMedium->u.hBitmap)
1727             size = HBITMAP_UserSize(pFlags, size, &pStgMedium->u.hBitmap);
1728         break;
1729     case TYMED_MFPICT:
1730         TRACE("TYMED_MFPICT\n");
1731         if (pStgMedium->u.hMetaFilePict)
1732             size = HMETAFILEPICT_UserSize(pFlags, size, &pStgMedium->u.hMetaFilePict);
1733         break;
1734     case TYMED_ENHMF:
1735         TRACE("TYMED_ENHMF\n");
1736         if (pStgMedium->u.hEnhMetaFile)
1737             size = HENHMETAFILE_UserSize(pFlags, size, &pStgMedium->u.hEnhMetaFile);
1738         break;
1739     default:
1740         RaiseException(DV_E_TYMED, 0, 0, NULL);
1741     }
1742 
1743     if (pStgMedium->pUnkForRelease)
1744         size = WdtpInterfacePointer_UserSize(pFlags, LOWORD(*pFlags), size, pStgMedium->pUnkForRelease, &IID_IUnknown);
1745 
1746     return size;
1747 }
1748 
1749 /******************************************************************************
1750  *           STGMEDIUM_UserMarshal [OLE32.@]
1751  *
1752  * Marshals a STGMEDIUM into a buffer.
1753  *
1754  * PARAMS
1755  *  pFlags  [I] Flags. See notes.
1756  *  pBuffer [I] Buffer to marshal the clip format into.
1757  *  pCF     [I] STGMEDIUM to marshal.
1758  *
1759  * RETURNS
1760  *  The end of the marshaled data in the buffer.
1761  *
1762  * NOTES
1763  *  Even though the function is documented to take a pointer to a ULONG in
1764  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1765  *  the first parameter is a ULONG.
1766  *  This function is only intended to be called by the RPC runtime.
1767  */
1768 unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
1769 {
1770     TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pStgMedium);
1771 
1772     ALIGN_POINTER(pBuffer, 3);
1773 
1774     *(DWORD *)pBuffer = pStgMedium->tymed;
1775     pBuffer += sizeof(DWORD);
1776     if (pStgMedium->tymed != TYMED_NULL)
1777     {
1778         *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->u.pstg;
1779         pBuffer += sizeof(DWORD);
1780     }
1781     *(DWORD *)pBuffer = (DWORD)(DWORD_PTR)pStgMedium->pUnkForRelease;
1782     pBuffer += sizeof(DWORD);
1783 
1784     switch (pStgMedium->tymed)
1785     {
1786     case TYMED_NULL:
1787         TRACE("TYMED_NULL\n");
1788         break;
1789     case TYMED_HGLOBAL:
1790         TRACE("TYMED_HGLOBAL\n");
1791         if (pStgMedium->u.hGlobal)
1792             pBuffer = HGLOBAL_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
1793         break;
1794     case TYMED_FILE:
1795         TRACE("TYMED_FILE\n");
1796         if (pStgMedium->u.lpszFileName)
1797         {
1798             DWORD len;
1799             len = strlenW(pStgMedium->u.lpszFileName);
1800             /* conformance */
1801             *(DWORD *)pBuffer = len + 1;
1802             pBuffer += sizeof(DWORD);
1803             /* offset */
1804             *(DWORD *)pBuffer = 0;
1805             pBuffer += sizeof(DWORD);
1806             /* variance */
1807             *(DWORD *)pBuffer = len + 1;
1808             pBuffer += sizeof(DWORD);
1809 
1810             TRACE("file name is %s\n", debugstr_w(pStgMedium->u.lpszFileName));
1811             memcpy(pBuffer, pStgMedium->u.lpszFileName, (len + 1) * sizeof(WCHAR));
1812         }
1813         break;
1814     case TYMED_ISTREAM:
1815         TRACE("TYMED_ISTREAM\n");
1816         if (pStgMedium->u.pstm)
1817         {
1818             IUnknown *unk;
1819             IStream_QueryInterface(pStgMedium->u.pstm, &IID_IUnknown, (void**)&unk);
1820             pBuffer = WdtpInterfacePointer_UserMarshal(pFlags, LOWORD(*pFlags), pBuffer, unk, &IID_IStream);
1821             IUnknown_Release(unk);
1822         }
1823         break;
1824     case TYMED_ISTORAGE:
1825         TRACE("TYMED_ISTORAGE\n");
1826         if (pStgMedium->u.pstg)
1827         {
1828             IUnknown *unk;
1829             IStorage_QueryInterface(pStgMedium->u.pstg, &IID_IUnknown, (void**)&unk);
1830             pBuffer = WdtpInterfacePointer_UserMarshal(pFlags, LOWORD(*pFlags), pBuffer, unk, &IID_IStorage);
1831             IUnknown_Release(unk);
1832         }
1833         break;
1834     case TYMED_GDI:
1835         TRACE("TYMED_GDI\n");
1836         if (pStgMedium->u.hBitmap)
1837             pBuffer = HBITMAP_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hBitmap);
1838         break;
1839     case TYMED_MFPICT:
1840         TRACE("TYMED_MFPICT\n");
1841         if (pStgMedium->u.hMetaFilePict)
1842             pBuffer = HMETAFILEPICT_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hMetaFilePict);
1843         break;
1844     case TYMED_ENHMF:
1845         TRACE("TYMED_ENHMF\n");
1846         if (pStgMedium->u.hEnhMetaFile)
1847             pBuffer = HENHMETAFILE_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
1848         break;
1849     default:
1850         RaiseException(DV_E_TYMED, 0, 0, NULL);
1851     }
1852 
1853     if (pStgMedium->pUnkForRelease)
1854         pBuffer = WdtpInterfacePointer_UserMarshal(pFlags, LOWORD(*pFlags), pBuffer, pStgMedium->pUnkForRelease, &IID_IUnknown);
1855 
1856     return pBuffer;
1857 }
1858 
1859 /******************************************************************************
1860  *           STGMEDIUM_UserUnmarshal [OLE32.@]
1861  *
1862  * Unmarshals a STGMEDIUM from a buffer.
1863  *
1864  * PARAMS
1865  *  pFlags     [I] Flags. See notes.
1866  *  pBuffer    [I] Buffer to marshal the clip format from.
1867  *  pStgMedium [O] Address that receive the unmarshaled STGMEDIUM.
1868  *
1869  * RETURNS
1870  *  The end of the marshaled data in the buffer.
1871  *
1872  * NOTES
1873  *  Even though the function is documented to take a pointer to an ULONG in
1874  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
1875  *  the first parameter is an ULONG.
1876  *  This function is only intended to be called by the RPC runtime.
1877  */
1878 unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, STGMEDIUM *pStgMedium)
1879 {
1880     DWORD content = 0;
1881     DWORD releaseunk;
1882 
1883     ALIGN_POINTER(pBuffer, 3);
1884 
1885     TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pStgMedium);
1886 
1887     pStgMedium->tymed = *(DWORD *)pBuffer;
1888     pBuffer += sizeof(DWORD);
1889     if (pStgMedium->tymed != TYMED_NULL)
1890     {
1891         content = *(DWORD *)pBuffer;
1892         pBuffer += sizeof(DWORD);
1893     }
1894     releaseunk = *(DWORD *)pBuffer;
1895     pBuffer += sizeof(DWORD);
1896 
1897     switch (pStgMedium->tymed)
1898     {
1899     case TYMED_NULL:
1900         TRACE("TYMED_NULL\n");
1901         break;
1902     case TYMED_HGLOBAL:
1903         TRACE("TYMED_HGLOBAL\n");
1904         if (content)
1905             pBuffer = HGLOBAL_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hGlobal);
1906         break;
1907     case TYMED_FILE:
1908         TRACE("TYMED_FILE\n");
1909         if (content)
1910         {
1911             DWORD conformance;
1912             DWORD variance;
1913             conformance = *(DWORD *)pBuffer;
1914             pBuffer += sizeof(DWORD);
1915             if (*(DWORD *)pBuffer != 0)
1916             {
1917                 ERR("invalid offset %d\n", *(DWORD *)pBuffer);
1918                 RpcRaiseException(RPC_S_INVALID_BOUND);
1919                 return NULL;
1920             }
1921             pBuffer += sizeof(DWORD);
1922             variance = *(DWORD *)pBuffer;
1923             pBuffer += sizeof(DWORD);
1924             if (conformance != variance)
1925             {
1926                 ERR("conformance (%d) and variance (%d) should be equal\n",
1927                     conformance, variance);
1928                 RpcRaiseException(RPC_S_INVALID_BOUND);
1929                 return NULL;
1930             }
1931             if (conformance > 0x7fffffff)
1932             {
1933                 ERR("conformance 0x%x too large\n", conformance);
1934                 RpcRaiseException(RPC_S_INVALID_BOUND);
1935                 return NULL;
1936             }
1937             pStgMedium->u.lpszFileName = CoTaskMemAlloc(conformance * sizeof(WCHAR));
1938             if (!pStgMedium->u.lpszFileName) RpcRaiseException(ERROR_OUTOFMEMORY);
1939             TRACE("unmarshalled file name is %s\n", debugstr_wn((const WCHAR *)pBuffer, variance));
1940             memcpy(pStgMedium->u.lpszFileName, pBuffer, variance * sizeof(WCHAR));
1941             pBuffer += variance * sizeof(WCHAR);
1942         }
1943         else
1944             pStgMedium->u.lpszFileName = NULL;
1945         break;
1946     case TYMED_ISTREAM:
1947         TRACE("TYMED_ISTREAM\n");
1948         if (content)
1949         {
1950             pBuffer = WdtpInterfacePointer_UserUnmarshal(pFlags, pBuffer, (IUnknown**)&pStgMedium->u.pstm, &IID_IStream);
1951         }
1952         else
1953         {
1954             if (pStgMedium->u.pstm) IStream_Release( pStgMedium->u.pstm );
1955             pStgMedium->u.pstm = NULL;
1956         }
1957         break;
1958     case TYMED_ISTORAGE:
1959         TRACE("TYMED_ISTORAGE\n");
1960         if (content)
1961         {
1962             pBuffer = WdtpInterfacePointer_UserUnmarshal(pFlags, pBuffer, (IUnknown**)&pStgMedium->u.pstg, &IID_IStorage);
1963         }
1964         else
1965         {
1966             if (pStgMedium->u.pstg) IStorage_Release( pStgMedium->u.pstg );
1967             pStgMedium->u.pstg = NULL;
1968         }
1969         break;
1970     case TYMED_GDI:
1971         TRACE("TYMED_GDI\n");
1972         if (content)
1973             pBuffer = HBITMAP_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hBitmap);
1974         else
1975             pStgMedium->u.hBitmap = NULL;
1976         break;
1977     case TYMED_MFPICT:
1978         TRACE("TYMED_MFPICT\n");
1979         if (content)
1980             pBuffer = HMETAFILEPICT_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hMetaFilePict);
1981         else
1982             pStgMedium->u.hMetaFilePict = NULL;
1983         break;
1984     case TYMED_ENHMF:
1985         TRACE("TYMED_ENHMF\n");
1986         if (content)
1987             pBuffer = HENHMETAFILE_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hEnhMetaFile);
1988         else
1989             pStgMedium->u.hEnhMetaFile = NULL;
1990         break;
1991     default:
1992         RaiseException(DV_E_TYMED, 0, 0, NULL);
1993     }
1994 
1995     if (releaseunk)
1996         pBuffer = WdtpInterfacePointer_UserUnmarshal(pFlags, pBuffer, &pStgMedium->pUnkForRelease, &IID_IUnknown);
1997     /* Unlike the IStream / IStorage ifaces, the existing pUnkForRelease
1998        is left intact if a NULL ptr is unmarshalled - see the tests. */
1999 
2000     return pBuffer;
2001 }
2002 
2003 /******************************************************************************
2004  *           STGMEDIUM_UserFree [OLE32.@]
2005  *
2006  * Frees an unmarshaled STGMEDIUM.
2007  *
2008  * PARAMS
2009  *  pFlags     [I] Flags. See notes.
2010  *  pStgmedium [I] STGMEDIUM to free.
2011  *
2012  * RETURNS
2013  *  The end of the marshaled data in the buffer.
2014  *
2015  * NOTES
2016  *  Even though the function is documented to take a pointer to a ULONG in
2017  *  pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
2018  *  which the first parameter is a ULONG.
2019  *  This function is only intended to be called by the RPC runtime.
2020  */
2021 void __RPC_USER STGMEDIUM_UserFree(ULONG *pFlags, STGMEDIUM *pStgMedium)
2022 {
2023     TRACE("(%s, %p\n", debugstr_user_flags(pFlags), pStgMedium);
2024 
2025     ReleaseStgMedium(pStgMedium);
2026 }
2027 
2028 ULONG __RPC_USER ASYNC_STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, ASYNC_STGMEDIUM *pStgMedium)
2029 {
2030     TRACE("\n");
2031     return STGMEDIUM_UserSize(pFlags, StartingSize, pStgMedium);
2032 }
2033 
2034 unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserMarshal(  ULONG *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
2035 {
2036     TRACE("\n");
2037     return STGMEDIUM_UserMarshal(pFlags, pBuffer, pStgMedium);
2038 }
2039 
2040 unsigned char * __RPC_USER ASYNC_STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, ASYNC_STGMEDIUM *pStgMedium)
2041 {
2042     TRACE("\n");
2043     return STGMEDIUM_UserUnmarshal(pFlags, pBuffer, pStgMedium);
2044 }
2045 
2046 void __RPC_USER ASYNC_STGMEDIUM_UserFree(ULONG *pFlags, ASYNC_STGMEDIUM *pStgMedium)
2047 {
2048     TRACE("\n");
2049     STGMEDIUM_UserFree(pFlags, pStgMedium);
2050 }
2051 
2052 ULONG __RPC_USER FLAG_STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, FLAG_STGMEDIUM *pStgMedium)
2053 {
2054     FIXME(":stub\n");
2055     return StartingSize;
2056 }
2057 
2058 unsigned char * __RPC_USER FLAG_STGMEDIUM_UserMarshal(  ULONG *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
2059 {
2060     FIXME(":stub\n");
2061     return pBuffer;
2062 }
2063 
2064 unsigned char * __RPC_USER FLAG_STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, FLAG_STGMEDIUM *pStgMedium)
2065 {
2066     FIXME(":stub\n");
2067     return pBuffer;
2068 }
2069 
2070 void __RPC_USER FLAG_STGMEDIUM_UserFree(ULONG *pFlags, FLAG_STGMEDIUM *pStgMedium)
2071 {
2072     FIXME(":stub\n");
2073 }
2074 
2075 ULONG __RPC_USER SNB_UserSize(ULONG *pFlags, ULONG StartingSize, SNB *pSnb)
2076 {
2077     ULONG size = StartingSize;
2078 
2079     TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pSnb);
2080 
2081     ALIGN_LENGTH(size, 3);
2082 
2083     /* two counters from RemSNB header, plus one more ULONG */
2084     size += 3*sizeof(ULONG);
2085 
2086     /* now actual data length */
2087     if (*pSnb)
2088     {
2089         WCHAR **ptrW = *pSnb;
2090 
2091         while (*ptrW)
2092         {
2093             size += (strlenW(*ptrW) + 1)*sizeof(WCHAR);
2094             ptrW++;
2095         }
2096     }
2097 
2098     return size;
2099 }
2100 
2101 struct SNB_wire {
2102     ULONG charcnt;
2103     ULONG strcnt;
2104     ULONG datalen;
2105     WCHAR data[1];
2106 };
2107 
2108 unsigned char * __RPC_USER SNB_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
2109 {
2110     struct SNB_wire *wire;
2111     ULONG size;
2112 
2113     TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, pSnb);
2114 
2115     ALIGN_POINTER(pBuffer, 3);
2116 
2117     wire = (struct SNB_wire*)pBuffer;
2118     wire->charcnt = wire->strcnt = 0;
2119     size = 3*sizeof(ULONG);
2120 
2121     if (*pSnb)
2122     {
2123         WCHAR **ptrW = *pSnb;
2124         WCHAR *dataW = wire->data;
2125 
2126         while (*ptrW)
2127         {
2128             ULONG len = strlenW(*ptrW) + 1;
2129 
2130             wire->strcnt++;
2131             wire->charcnt += len;
2132             memcpy(dataW, *ptrW, len*sizeof(WCHAR));
2133             dataW += len;
2134 
2135             size += len*sizeof(WCHAR);
2136             ptrW++;
2137         }
2138     }
2139 
2140     wire->datalen = wire->charcnt;
2141     return pBuffer + size;
2142 }
2143 
2144 unsigned char * __RPC_USER SNB_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, SNB *pSnb)
2145 {
2146     USER_MARSHAL_CB *umcb = (USER_MARSHAL_CB*)pFlags;
2147     struct SNB_wire *wire;
2148 
2149     TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, pSnb);
2150 
2151     wire = (struct SNB_wire*)pBuffer;
2152 
2153     if (*pSnb)
2154         umcb->pStubMsg->pfnFree(*pSnb);
2155 
2156     if (wire->datalen == 0)
2157         *pSnb = NULL;
2158     else
2159     {
2160         WCHAR *src = wire->data, *dest;
2161         WCHAR **ptrW;
2162         ULONG i;
2163 
2164         ptrW = *pSnb = umcb->pStubMsg->pfnAllocate((wire->strcnt+1)*sizeof(WCHAR*) + wire->datalen*sizeof(WCHAR));
2165         dest = (WCHAR*)(*pSnb + wire->strcnt + 1);
2166 
2167         for (i = 0; i < wire->strcnt; i++)
2168         {
2169             ULONG len = strlenW(src);
2170             memcpy(dest, src, (len + 1)*sizeof(WCHAR));
2171             *ptrW = dest;
2172             src += len + 1;
2173             dest += len + 1;
2174             ptrW++;
2175         }
2176         *ptrW = NULL;
2177     }
2178 
2179     return pBuffer + 3*sizeof(ULONG) + wire->datalen*sizeof(WCHAR);
2180 }
2181 
2182 void __RPC_USER SNB_UserFree(ULONG *pFlags, SNB *pSnb)
2183 {
2184     USER_MARSHAL_CB *umcb = (USER_MARSHAL_CB*)pFlags;
2185     TRACE("(%p)\n", pSnb);
2186     if (*pSnb)
2187         umcb->pStubMsg->pfnFree(*pSnb);
2188 }
2189 
2190 /* call_as/local stubs for unknwn.idl */
2191 
2192 HRESULT CALLBACK IClassFactory_CreateInstance_Proxy(
2193     IClassFactory* This,
2194     IUnknown *pUnkOuter,
2195     REFIID riid,
2196     void **ppvObject)
2197 {
2198     TRACE("(%p, %s, %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject);
2199     *ppvObject = NULL;
2200     if (pUnkOuter)
2201     {
2202         ERR("aggregation is not allowed on remote objects\n");
2203         return CLASS_E_NOAGGREGATION;
2204     }
2205     return IClassFactory_RemoteCreateInstance_Proxy(This, riid,
2206                                                     (IUnknown **) ppvObject);
2207 }
2208 
2209 HRESULT __RPC_STUB IClassFactory_CreateInstance_Stub(
2210     IClassFactory* This,
2211     REFIID riid,
2212     IUnknown **ppvObject)
2213 {
2214     TRACE("(%s, %p)\n", debugstr_guid(riid), ppvObject);
2215     return IClassFactory_CreateInstance(This, NULL, riid, (void **) ppvObject);
2216 }
2217 
2218 HRESULT CALLBACK IClassFactory_LockServer_Proxy(
2219     IClassFactory* This,
2220     BOOL fLock)
2221 {
2222     FIXME(":stub\n");
2223     return E_NOTIMPL;
2224 }
2225 
2226 HRESULT __RPC_STUB IClassFactory_LockServer_Stub(
2227     IClassFactory* This,
2228     BOOL fLock)
2229 {
2230     FIXME(":stub\n");
2231     return E_NOTIMPL;
2232 }
2233 
2234 /* call_as/local stubs for objidl.idl */
2235 
2236 HRESULT CALLBACK IEnumUnknown_Next_Proxy(
2237     IEnumUnknown* This,
2238     ULONG celt,
2239     IUnknown **rgelt,
2240     ULONG *pceltFetched)
2241 {
2242     ULONG fetched;
2243     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2244     if (!pceltFetched) pceltFetched = &fetched;
2245     return IEnumUnknown_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
2246 }
2247 
2248 HRESULT __RPC_STUB IEnumUnknown_Next_Stub(
2249     IEnumUnknown* This,
2250     ULONG celt,
2251     IUnknown **rgelt,
2252     ULONG *pceltFetched)
2253 {
2254     HRESULT hr;
2255     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2256     *pceltFetched = 0;
2257     hr = IEnumUnknown_Next(This, celt, rgelt, pceltFetched);
2258     if (hr == S_OK) *pceltFetched = celt;
2259     return hr;
2260 }
2261 
2262 HRESULT CALLBACK IBindCtx_SetBindOptions_Proxy(
2263     IBindCtx* This,
2264     BIND_OPTS *pbindopts)
2265 {
2266     FIXME(":stub\n");
2267     return E_NOTIMPL;
2268 }
2269 
2270 HRESULT __RPC_STUB IBindCtx_SetBindOptions_Stub(
2271     IBindCtx* This,
2272     BIND_OPTS2 *pbindopts)
2273 {
2274     FIXME(":stub\n");
2275     return E_NOTIMPL;
2276 }
2277 
2278 HRESULT CALLBACK IBindCtx_GetBindOptions_Proxy(
2279     IBindCtx* This,
2280     BIND_OPTS *pbindopts)
2281 {
2282     FIXME(":stub\n");
2283     return E_NOTIMPL;
2284 }
2285 
2286 HRESULT __RPC_STUB IBindCtx_GetBindOptions_Stub(
2287     IBindCtx* This,
2288     BIND_OPTS2 *pbindopts)
2289 {
2290     FIXME(":stub\n");
2291     return E_NOTIMPL;
2292 }
2293 
2294 HRESULT CALLBACK IEnumMoniker_Next_Proxy(
2295     IEnumMoniker* This,
2296     ULONG celt,
2297     IMoniker **rgelt,
2298     ULONG *pceltFetched)
2299 {
2300     ULONG fetched;
2301     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2302     if (!pceltFetched) pceltFetched = &fetched;
2303     return IEnumMoniker_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
2304 }
2305 
2306 HRESULT __RPC_STUB IEnumMoniker_Next_Stub(
2307     IEnumMoniker* This,
2308     ULONG celt,
2309     IMoniker **rgelt,
2310     ULONG *pceltFetched)
2311 {
2312     HRESULT hr;
2313     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2314     *pceltFetched = 0;
2315     hr = IEnumMoniker_Next(This, celt, rgelt, pceltFetched);
2316     if (hr == S_OK) *pceltFetched = celt;
2317     return hr;
2318 }
2319 
2320 BOOL CALLBACK IRunnableObject_IsRunning_Proxy(
2321     IRunnableObject* This)
2322 {
2323     BOOL rv;
2324     FIXME(":stub\n");
2325     memset(&rv, 0, sizeof rv);
2326     return rv;
2327 }
2328 
2329 HRESULT __RPC_STUB IRunnableObject_IsRunning_Stub(
2330     IRunnableObject* This)
2331 {
2332     FIXME(":stub\n");
2333     return E_NOTIMPL;
2334 }
2335 
2336 HRESULT CALLBACK IMoniker_BindToObject_Proxy(
2337     IMoniker* This,
2338     IBindCtx *pbc,
2339     IMoniker *pmkToLeft,
2340     REFIID riidResult,
2341     void **ppvResult)
2342 {
2343     FIXME(":stub\n");
2344     return E_NOTIMPL;
2345 }
2346 
2347 HRESULT __RPC_STUB IMoniker_BindToObject_Stub(
2348     IMoniker* This,
2349     IBindCtx *pbc,
2350     IMoniker *pmkToLeft,
2351     REFIID riidResult,
2352     IUnknown **ppvResult)
2353 {
2354     FIXME(":stub\n");
2355     return E_NOTIMPL;
2356 }
2357 
2358 HRESULT CALLBACK IMoniker_BindToStorage_Proxy(
2359     IMoniker* This,
2360     IBindCtx *pbc,
2361     IMoniker *pmkToLeft,
2362     REFIID riid,
2363     void **ppvObj)
2364 {
2365     TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
2366     return IMoniker_RemoteBindToStorage_Proxy(This, pbc, pmkToLeft, riid, (IUnknown**)ppvObj);
2367 }
2368 
2369 HRESULT __RPC_STUB IMoniker_BindToStorage_Stub(
2370     IMoniker* This,
2371     IBindCtx *pbc,
2372     IMoniker *pmkToLeft,
2373     REFIID riid,
2374     IUnknown **ppvObj)
2375 {
2376     TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObj);
2377     return IMoniker_BindToStorage(This, pbc, pmkToLeft, riid, (void**)ppvObj);
2378 }
2379 
2380 HRESULT CALLBACK IEnumString_Next_Proxy(
2381     IEnumString* This,
2382     ULONG celt,
2383     LPOLESTR *rgelt,
2384     ULONG *pceltFetched)
2385 {
2386     ULONG fetched;
2387     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2388     if (!pceltFetched) pceltFetched = &fetched;
2389     return IEnumString_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
2390 }
2391 
2392 HRESULT __RPC_STUB IEnumString_Next_Stub(
2393     IEnumString* This,
2394     ULONG celt,
2395     LPOLESTR *rgelt,
2396     ULONG *pceltFetched)
2397 {
2398     HRESULT hr;
2399     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2400     *pceltFetched = 0;
2401     hr = IEnumString_Next(This, celt, rgelt, pceltFetched);
2402     if (hr == S_OK) *pceltFetched = celt;
2403     return hr;
2404 }
2405 
2406 HRESULT CALLBACK ISequentialStream_Read_Proxy(
2407     ISequentialStream* This,
2408     void *pv,
2409     ULONG cb,
2410     ULONG *pcbRead)
2411 {
2412     ULONG read;
2413     HRESULT hr;
2414 
2415     TRACE("(%p)->(%p, %d, %p)\n", This, pv, cb, pcbRead);
2416 
2417     hr = ISequentialStream_RemoteRead_Proxy(This, pv, cb, &read);
2418     if(pcbRead) *pcbRead = read;
2419 
2420     return hr;
2421 }
2422 
2423 HRESULT __RPC_STUB ISequentialStream_Read_Stub(
2424     ISequentialStream* This,
2425     byte *pv,
2426     ULONG cb,
2427     ULONG *pcbRead)
2428 {
2429     TRACE("(%p)->(%p, %d, %p)\n", This, pv, cb, pcbRead);
2430     return ISequentialStream_Read(This, pv, cb, pcbRead);
2431 }
2432 
2433 HRESULT CALLBACK ISequentialStream_Write_Proxy(
2434     ISequentialStream* This,
2435     const void *pv,
2436     ULONG cb,
2437     ULONG *pcbWritten)
2438 {
2439     ULONG written;
2440     HRESULT hr;
2441 
2442     TRACE("(%p)->(%p, %d, %p)\n", This, pv, cb, pcbWritten);
2443 
2444     hr = ISequentialStream_RemoteWrite_Proxy(This, pv, cb, &written);
2445     if(pcbWritten) *pcbWritten = written;
2446 
2447     return hr;
2448 }
2449 
2450 HRESULT __RPC_STUB ISequentialStream_Write_Stub(
2451     ISequentialStream* This,
2452     const byte *pv,
2453     ULONG cb,
2454     ULONG *pcbWritten)
2455 {
2456     TRACE("(%p)->(%p, %d, %p)\n", This, pv, cb, pcbWritten);
2457     return ISequentialStream_Write(This, pv, cb, pcbWritten);
2458 }
2459 
2460 HRESULT CALLBACK IStream_Seek_Proxy(
2461     IStream* This,
2462     LARGE_INTEGER dlibMove,
2463     DWORD dwOrigin,
2464     ULARGE_INTEGER *plibNewPosition)
2465 {
2466     ULARGE_INTEGER newpos;
2467     HRESULT hr;
2468 
2469     TRACE("(%p)->(%s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition);
2470 
2471     hr = IStream_RemoteSeek_Proxy(This, dlibMove, dwOrigin, &newpos);
2472     if(plibNewPosition) *plibNewPosition = newpos;
2473 
2474     return hr;
2475 }
2476 
2477 HRESULT __RPC_STUB IStream_Seek_Stub(
2478     IStream* This,
2479     LARGE_INTEGER dlibMove,
2480     DWORD dwOrigin,
2481     ULARGE_INTEGER *plibNewPosition)
2482 {
2483     TRACE("(%p)->(%s, %d, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), dwOrigin, plibNewPosition);
2484     return IStream_Seek(This, dlibMove, dwOrigin, plibNewPosition);
2485 }
2486 
2487 HRESULT CALLBACK IStream_CopyTo_Proxy(
2488     IStream* This,
2489     IStream *pstm,
2490     ULARGE_INTEGER cb,
2491     ULARGE_INTEGER *pcbRead,
2492     ULARGE_INTEGER *pcbWritten)
2493 {
2494     ULARGE_INTEGER read, written;
2495     HRESULT hr;
2496 
2497     TRACE("(%p)->(%p, %s, %p, %p)\n", This, pstm, wine_dbgstr_longlong(cb.QuadPart), pcbRead, pcbWritten);
2498 
2499     hr = IStream_RemoteCopyTo_Proxy(This, pstm, cb, &read, &written);
2500     if(pcbRead) *pcbRead = read;
2501     if(pcbWritten) *pcbWritten = written;
2502 
2503     return hr;
2504 }
2505 
2506 HRESULT __RPC_STUB IStream_CopyTo_Stub(
2507     IStream* This,
2508     IStream *pstm,
2509     ULARGE_INTEGER cb,
2510     ULARGE_INTEGER *pcbRead,
2511     ULARGE_INTEGER *pcbWritten)
2512 {
2513     TRACE("(%p)->(%p, %s, %p, %p)\n", This, pstm, wine_dbgstr_longlong(cb.QuadPart), pcbRead, pcbWritten);
2514 
2515     return IStream_CopyTo(This, pstm, cb, pcbRead, pcbWritten);
2516 }
2517 
2518 HRESULT CALLBACK IEnumSTATSTG_Next_Proxy(
2519     IEnumSTATSTG* This,
2520     ULONG celt,
2521     STATSTG *rgelt,
2522     ULONG *pceltFetched)
2523 {
2524     ULONG fetched;
2525     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2526     if (!pceltFetched) pceltFetched = &fetched;
2527     return IEnumSTATSTG_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
2528 }
2529 
2530 HRESULT __RPC_STUB IEnumSTATSTG_Next_Stub(
2531     IEnumSTATSTG* This,
2532     ULONG celt,
2533     STATSTG *rgelt,
2534     ULONG *pceltFetched)
2535 {
2536     HRESULT hr;
2537     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2538     *pceltFetched = 0;
2539     hr = IEnumSTATSTG_Next(This, celt, rgelt, pceltFetched);
2540     if (hr == S_OK) *pceltFetched = celt;
2541     return hr;
2542 }
2543 
2544 HRESULT CALLBACK IStorage_OpenStream_Proxy(
2545     IStorage* This,
2546     LPCOLESTR pwcsName,
2547     void *reserved1,
2548     DWORD grfMode,
2549     DWORD reserved2,
2550     IStream **ppstm)
2551 {
2552     TRACE("(%p)->(%s, %p, %08x, %d %p)\n", This, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
2553     if(reserved1) WARN("reserved1 %p\n", reserved1);
2554 
2555     return IStorage_RemoteOpenStream_Proxy(This, pwcsName, 0, NULL, grfMode, reserved2, ppstm);
2556 }
2557 
2558 HRESULT __RPC_STUB IStorage_OpenStream_Stub(
2559     IStorage* This,
2560     LPCOLESTR pwcsName,
2561     ULONG cbReserved1,
2562     byte *reserved1,
2563     DWORD grfMode,
2564     DWORD reserved2,
2565     IStream **ppstm)
2566 {
2567     TRACE("(%p)->(%s, %d, %p, %08x, %d %p)\n", This, debugstr_w(pwcsName), cbReserved1, reserved1, grfMode, reserved2, ppstm);
2568     if(cbReserved1 || reserved1) WARN("cbReserved1 %d reserved1 %p\n", cbReserved1, reserved1);
2569 
2570     return IStorage_OpenStream(This, pwcsName, NULL, grfMode, reserved2, ppstm);
2571 }
2572 
2573 HRESULT CALLBACK IStorage_EnumElements_Proxy(
2574     IStorage* This,
2575     DWORD reserved1,
2576     void *reserved2,
2577     DWORD reserved3,
2578     IEnumSTATSTG **ppenum)
2579 {
2580     TRACE("(%p)->(%d, %p, %d, %p)\n", This, reserved1, reserved2, reserved3, ppenum);
2581     if(reserved2) WARN("reserved2 %p\n", reserved2);
2582 
2583     return IStorage_RemoteEnumElements_Proxy(This, reserved1, 0, NULL, reserved3, ppenum);
2584 }
2585 
2586 HRESULT __RPC_STUB IStorage_EnumElements_Stub(
2587     IStorage* This,
2588     DWORD reserved1,
2589     ULONG cbReserved2,
2590     byte *reserved2,
2591     DWORD reserved3,
2592     IEnumSTATSTG **ppenum)
2593 {
2594     TRACE("(%p)->(%d, %d, %p, %d, %p)\n", This, reserved1, cbReserved2, reserved2, reserved3, ppenum);
2595     if(cbReserved2 || reserved2) WARN("cbReserved2 %d reserved2 %p\n", cbReserved2, reserved2);
2596 
2597     return IStorage_EnumElements(This, reserved1, NULL, reserved3, ppenum);
2598 }
2599 
2600 HRESULT CALLBACK ILockBytes_ReadAt_Proxy(
2601     ILockBytes* This,
2602     ULARGE_INTEGER ulOffset,
2603     void *pv,
2604     ULONG cb,
2605     ULONG *pcbRead)
2606 {
2607     ULONG read;
2608     HRESULT hr;
2609 
2610     TRACE("(%p)->(%s, %p, %d, %p)\n", This, wine_dbgstr_longlong(ulOffset.QuadPart), pv, cb, pcbRead);
2611 
2612     hr = ILockBytes_RemoteReadAt_Proxy(This, ulOffset, pv, cb, &read);
2613     if(pcbRead) *pcbRead = read;
2614 
2615     return hr;
2616 }
2617 
2618 HRESULT __RPC_STUB ILockBytes_ReadAt_Stub(
2619     ILockBytes* This,
2620     ULARGE_INTEGER ulOffset,
2621     byte *pv,
2622     ULONG cb,
2623     ULONG *pcbRead)
2624 {
2625     TRACE("(%p)->(%s, %p, %d, %p)\n", This, wine_dbgstr_longlong(ulOffset.QuadPart), pv, cb, pcbRead);
2626     return ILockBytes_ReadAt(This, ulOffset, pv, cb, pcbRead);
2627 }
2628 
2629 HRESULT CALLBACK ILockBytes_WriteAt_Proxy(
2630     ILockBytes* This,
2631     ULARGE_INTEGER ulOffset,
2632     const void *pv,
2633     ULONG cb,
2634     ULONG *pcbWritten)
2635 {
2636     ULONG written;
2637     HRESULT hr;
2638 
2639     TRACE("(%p)->(%s, %p, %d, %p)\n", This, wine_dbgstr_longlong(ulOffset.QuadPart), pv, cb, pcbWritten);
2640 
2641     hr = ILockBytes_RemoteWriteAt_Proxy(This, ulOffset, pv, cb, &written);
2642     if(pcbWritten) *pcbWritten = written;
2643 
2644     return hr;
2645 }
2646 
2647 HRESULT __RPC_STUB ILockBytes_WriteAt_Stub(
2648     ILockBytes* This,
2649     ULARGE_INTEGER ulOffset,
2650     const byte *pv,
2651     ULONG cb,
2652     ULONG *pcbWritten)
2653 {
2654     TRACE("(%p)->(%s, %p, %d, %p)\n", This, wine_dbgstr_longlong(ulOffset.QuadPart), pv, cb, pcbWritten);
2655     return ILockBytes_WriteAt(This, ulOffset, pv, cb, pcbWritten);
2656 }
2657 
2658 HRESULT CALLBACK IFillLockBytes_FillAppend_Proxy(
2659     IFillLockBytes* This,
2660     const void *pv,
2661     ULONG cb,
2662     ULONG *pcbWritten)
2663 {
2664     ULONG written;
2665     HRESULT hr;
2666 
2667     TRACE("(%p)->(%p, %d, %p)\n", This, pv, cb, pcbWritten);
2668 
2669     hr = IFillLockBytes_RemoteFillAppend_Proxy(This, pv, cb, &written);
2670     if(pcbWritten) *pcbWritten = written;
2671 
2672     return hr;
2673 }
2674 
2675 HRESULT __RPC_STUB IFillLockBytes_FillAppend_Stub(
2676     IFillLockBytes* This,
2677     const byte *pv,
2678     ULONG cb,
2679     ULONG *pcbWritten)
2680 {
2681     TRACE("(%p)->(%p, %d, %p)\n", This, pv, cb, pcbWritten);
2682     return IFillLockBytes_FillAppend(This, pv, cb, pcbWritten);
2683 }
2684 
2685 HRESULT CALLBACK IFillLockBytes_FillAt_Proxy(
2686     IFillLockBytes* This,
2687     ULARGE_INTEGER ulOffset,
2688     const void *pv,
2689     ULONG cb,
2690     ULONG *pcbWritten)
2691 {
2692     ULONG written;
2693     HRESULT hr;
2694 
2695     TRACE("(%p)->(%s, %p, %d, %p)\n", This, wine_dbgstr_longlong(ulOffset.QuadPart), pv, cb, pcbWritten);
2696 
2697     hr = IFillLockBytes_RemoteFillAt_Proxy(This, ulOffset, pv, cb, &written);
2698     if(pcbWritten) *pcbWritten = written;
2699 
2700     return hr;
2701 }
2702 
2703 HRESULT __RPC_STUB IFillLockBytes_FillAt_Stub(
2704     IFillLockBytes* This,
2705     ULARGE_INTEGER ulOffset,
2706     const byte *pv,
2707     ULONG cb,
2708     ULONG *pcbWritten)
2709 {
2710     TRACE("(%p)->(%s, %p, %d, %p)\n", This, wine_dbgstr_longlong(ulOffset.QuadPart), pv, cb, pcbWritten);
2711     return IFillLockBytes_FillAt(This, ulOffset, pv, cb, pcbWritten);
2712 }
2713 
2714 HRESULT CALLBACK IEnumFORMATETC_Next_Proxy(
2715     IEnumFORMATETC* This,
2716     ULONG celt,
2717     FORMATETC *rgelt,
2718     ULONG *pceltFetched)
2719 {
2720     ULONG fetched;
2721     if (!pceltFetched) pceltFetched = &fetched;
2722     return IEnumFORMATETC_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
2723 }
2724 
2725 HRESULT __RPC_STUB IEnumFORMATETC_Next_Stub(
2726     IEnumFORMATETC* This,
2727     ULONG celt,
2728     FORMATETC *rgelt,
2729     ULONG *pceltFetched)
2730 {
2731     HRESULT hr;
2732     *pceltFetched = 0;
2733     hr = IEnumFORMATETC_Next(This, celt, rgelt, pceltFetched);
2734     if (hr == S_OK) *pceltFetched = celt;
2735     return hr;
2736 }
2737 
2738 HRESULT CALLBACK IEnumSTATDATA_Next_Proxy(
2739     IEnumSTATDATA* This,
2740     ULONG celt,
2741     STATDATA *rgelt,
2742     ULONG *pceltFetched)
2743 {
2744     ULONG fetched;
2745     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2746     if (!pceltFetched) pceltFetched = &fetched;
2747     return IEnumSTATDATA_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
2748 }
2749 
2750 HRESULT __RPC_STUB IEnumSTATDATA_Next_Stub(
2751     IEnumSTATDATA* This,
2752     ULONG celt,
2753     STATDATA *rgelt,
2754     ULONG *pceltFetched)
2755 {
2756     HRESULT hr;
2757     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
2758     *pceltFetched = 0;
2759     hr = IEnumSTATDATA_Next(This, celt, rgelt, pceltFetched);
2760     if (hr == S_OK) *pceltFetched = celt;
2761     return hr;
2762 }
2763 
2764 void CALLBACK IAdviseSink_OnDataChange_Proxy(
2765     IAdviseSink* This,
2766     FORMATETC *pFormatetc,
2767     STGMEDIUM *pStgmed)
2768 {
2769     TRACE("(%p)->(%p, %p)\n", This, pFormatetc, pStgmed);
2770     IAdviseSink_RemoteOnDataChange_Proxy(This, pFormatetc, pStgmed);
2771 }
2772 
2773 HRESULT __RPC_STUB IAdviseSink_OnDataChange_Stub(
2774     IAdviseSink* This,
2775     FORMATETC *pFormatetc,
2776     ASYNC_STGMEDIUM *pStgmed)
2777 {
2778     TRACE("(%p)->(%p, %p)\n", This, pFormatetc, pStgmed);
2779     IAdviseSink_OnDataChange(This, pFormatetc, pStgmed);
2780     return S_OK;
2781 }
2782 
2783 void CALLBACK IAdviseSink_OnViewChange_Proxy(
2784     IAdviseSink* This,
2785     DWORD dwAspect,
2786     LONG lindex)
2787 {
2788     TRACE("(%p)->(%d, %d)\n", This, dwAspect, lindex);
2789     IAdviseSink_RemoteOnViewChange_Proxy(This, dwAspect, lindex);
2790 }
2791 
2792 HRESULT __RPC_STUB IAdviseSink_OnViewChange_Stub(
2793     IAdviseSink* This,
2794     DWORD dwAspect,
2795     LONG lindex)
2796 {
2797     TRACE("(%p)->(%d, %d)\n", This, dwAspect, lindex);
2798     IAdviseSink_OnViewChange(This, dwAspect, lindex);
2799     return S_OK;
2800 }
2801 
2802 void CALLBACK IAdviseSink_OnRename_Proxy(
2803     IAdviseSink* This,
2804     IMoniker *pmk)
2805 {
2806     TRACE("(%p)->(%p)\n", This, pmk);
2807     IAdviseSink_RemoteOnRename_Proxy(This, pmk);
2808 }
2809 
2810 HRESULT __RPC_STUB IAdviseSink_OnRename_Stub(
2811     IAdviseSink* This,
2812     IMoniker *pmk)
2813 {
2814     TRACE("(%p)->(%p)\n", This, pmk);
2815     IAdviseSink_OnRename(This, pmk);
2816     return S_OK;
2817 }
2818 
2819 void CALLBACK IAdviseSink_OnSave_Proxy(
2820     IAdviseSink* This)
2821 {
2822     TRACE("(%p)\n", This);
2823     IAdviseSink_RemoteOnSave_Proxy(This);
2824 }
2825 
2826 HRESULT __RPC_STUB IAdviseSink_OnSave_Stub(
2827     IAdviseSink* This)
2828 {
2829     TRACE("(%p)\n", This);
2830     IAdviseSink_OnSave(This);
2831     return S_OK;
2832 }
2833 
2834 void CALLBACK IAdviseSink_OnClose_Proxy(
2835     IAdviseSink* This)
2836 {
2837     TRACE("(%p)\n", This);
2838     IAdviseSink_RemoteOnClose_Proxy(This);
2839 }
2840 
2841 HRESULT __RPC_STUB IAdviseSink_OnClose_Stub(
2842     IAdviseSink* This)
2843 {
2844     TRACE("(%p)\n", This);
2845     IAdviseSink_OnClose(This);
2846     return S_OK;
2847 }
2848 
2849 void CALLBACK IAdviseSink2_OnLinkSrcChange_Proxy(
2850     IAdviseSink2* This,
2851     IMoniker *pmk)
2852 {
2853     TRACE("(%p)->(%p)\n", This, pmk);
2854     IAdviseSink2_RemoteOnLinkSrcChange_Proxy(This, pmk);
2855 }
2856 
2857 HRESULT __RPC_STUB IAdviseSink2_OnLinkSrcChange_Stub(
2858     IAdviseSink2* This,
2859     IMoniker *pmk)
2860 {
2861     TRACE("(%p)->(%p)\n", This, pmk);
2862     IAdviseSink2_OnLinkSrcChange(This, pmk);
2863     return S_OK;
2864 }
2865 
2866 HRESULT CALLBACK IDataObject_GetData_Proxy(
2867     IDataObject* This,
2868     FORMATETC *pformatetcIn,
2869     STGMEDIUM *pmedium)
2870 {
2871     TRACE("(%p)->(%p, %p)\n", This, pformatetcIn, pmedium);
2872     return IDataObject_RemoteGetData_Proxy(This, pformatetcIn, pmedium);
2873 }
2874 
2875 HRESULT __RPC_STUB IDataObject_GetData_Stub(
2876     IDataObject* This,
2877     FORMATETC *pformatetcIn,
2878     STGMEDIUM *pRemoteMedium)
2879 {
2880     TRACE("(%p)->(%p, %p)\n", This, pformatetcIn, pRemoteMedium);
2881     return IDataObject_GetData(This, pformatetcIn, pRemoteMedium);
2882 }
2883 
2884 HRESULT CALLBACK IDataObject_GetDataHere_Proxy(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med)
2885 {
2886     IUnknown *release;
2887     IStorage *stg = NULL;
2888     HRESULT hr;
2889 
2890     TRACE("(%p)->(%p, %p)\n", iface, fmt, med);
2891 
2892     if ((med->tymed & (TYMED_HGLOBAL | TYMED_FILE | TYMED_ISTREAM | TYMED_ISTORAGE)) == 0)
2893         return DV_E_TYMED;
2894     if (med->tymed != fmt->tymed)
2895         return DV_E_TYMED;
2896 
2897     release = med->pUnkForRelease;
2898     med->pUnkForRelease = NULL;
2899 
2900     if (med->tymed == TYMED_ISTREAM || med->tymed == TYMED_ISTORAGE)
2901     {
2902         stg = med->u.pstg; /* This may actually be a stream, but that's ok */
2903         if (stg) IStorage_AddRef( stg );
2904     }
2905 
2906     hr = IDataObject_RemoteGetDataHere_Proxy(iface, fmt, med);
2907 
2908     med->pUnkForRelease = release;
2909     if (stg)
2910     {
2911         if (med->u.pstg)
2912             IStorage_Release( med->u.pstg );
2913         med->u.pstg = stg;
2914     }
2915 
2916     return hr;
2917 }
2918 
2919 HRESULT __RPC_STUB IDataObject_GetDataHere_Stub(
2920     IDataObject* This,
2921     FORMATETC *pformatetc,
2922     STGMEDIUM *pRemoteMedium)
2923 {
2924     TRACE("(%p)->(%p, %p)\n", This, pformatetc, pRemoteMedium);
2925     return IDataObject_GetDataHere(This, pformatetc, pRemoteMedium);
2926 }
2927 
2928 HRESULT CALLBACK IDataObject_SetData_Proxy(
2929     IDataObject* This,
2930     FORMATETC *pformatetc,
2931     STGMEDIUM *pmedium,
2932     BOOL fRelease)
2933 {
2934     FIXME(":stub\n");
2935     return E_NOTIMPL;
2936 }
2937 
2938 HRESULT __RPC_STUB IDataObject_SetData_Stub(
2939     IDataObject* This,
2940     FORMATETC *pformatetc,
2941     FLAG_STGMEDIUM *pmedium,
2942     BOOL fRelease)
2943 {
2944     FIXME(":stub\n");
2945     return E_NOTIMPL;
2946 }
2947 
2948 /* call_as/local stubs for oleidl.idl */
2949 
2950 HRESULT CALLBACK IOleInPlaceActiveObject_TranslateAccelerator_Proxy(
2951     IOleInPlaceActiveObject* This,
2952     LPMSG lpmsg)
2953 {
2954     TRACE("(%p %p)\n", This, lpmsg);
2955     return IOleInPlaceActiveObject_RemoteTranslateAccelerator_Proxy(This);
2956 }
2957 
2958 HRESULT __RPC_STUB IOleInPlaceActiveObject_TranslateAccelerator_Stub(
2959     IOleInPlaceActiveObject* This)
2960 {
2961     TRACE("(%p)\n", This);
2962     return S_FALSE;
2963 }
2964 
2965 HRESULT CALLBACK IOleInPlaceActiveObject_ResizeBorder_Proxy(
2966     IOleInPlaceActiveObject* This,
2967     LPCRECT prcBorder,
2968     IOleInPlaceUIWindow *pUIWindow,
2969     BOOL fFrameWindow)
2970 {
2971     FIXME(":stub\n");
2972     return E_NOTIMPL;
2973 }
2974 
2975 HRESULT __RPC_STUB IOleInPlaceActiveObject_ResizeBorder_Stub(
2976     IOleInPlaceActiveObject* This,
2977     LPCRECT prcBorder,
2978     REFIID riid,
2979     IOleInPlaceUIWindow *pUIWindow,
2980     BOOL fFrameWindow)
2981 {
2982     FIXME(":stub\n");
2983     return E_NOTIMPL;
2984 }
2985 
2986 HRESULT CALLBACK IOleCache2_UpdateCache_Proxy(
2987     IOleCache2* This,
2988     LPDATAOBJECT pDataObject,
2989     DWORD grfUpdf,
2990     LPVOID pReserved)
2991 {
2992     TRACE("(%p, %p, 0x%08x, %p)\n", This, pDataObject, grfUpdf, pReserved);
2993     return IOleCache2_RemoteUpdateCache_Proxy(This, pDataObject, grfUpdf, (LONG_PTR)pReserved);
2994 }
2995 
2996 HRESULT __RPC_STUB IOleCache2_UpdateCache_Stub(
2997     IOleCache2* This,
2998     LPDATAOBJECT pDataObject,
2999     DWORD grfUpdf,
3000     LONG_PTR pReserved)
3001 {
3002     TRACE("(%p, %p, 0x%08x, %li)\n", This, pDataObject, grfUpdf, pReserved);
3003     return IOleCache2_UpdateCache(This, pDataObject, grfUpdf, (void*)pReserved);
3004 }
3005 
3006 HRESULT CALLBACK IEnumOLEVERB_Next_Proxy(
3007     IEnumOLEVERB* This,
3008     ULONG celt,
3009     LPOLEVERB rgelt,
3010     ULONG *pceltFetched)
3011 {
3012     ULONG fetched;
3013     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
3014     if (!pceltFetched) pceltFetched = &fetched;
3015     return IEnumOLEVERB_RemoteNext_Proxy(This, celt, rgelt, pceltFetched);
3016 }
3017 
3018 HRESULT __RPC_STUB IEnumOLEVERB_Next_Stub(
3019     IEnumOLEVERB* This,
3020     ULONG celt,
3021     LPOLEVERB rgelt,
3022     ULONG *pceltFetched)
3023 {
3024     HRESULT hr;
3025     TRACE("(%p)->(%d, %p, %p)\n", This, celt, rgelt, pceltFetched);
3026     *pceltFetched = 0;
3027     hr = IEnumOLEVERB_Next(This, celt, rgelt, pceltFetched);
3028     if (hr == S_OK) *pceltFetched = celt;
3029     return hr;
3030 }
3031 
3032 HRESULT CALLBACK IViewObject_Draw_Proxy(
3033     IViewObject* This,
3034     DWORD dwDrawAspect,
3035     LONG lindex,
3036     void *pvAspect,
3037     DVTARGETDEVICE *ptd,
3038     HDC hdcTargetDev,
3039     HDC hdcDraw,
3040     LPCRECTL lprcBounds,
3041     LPCRECTL lprcWBounds,
3042     BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue),
3043     ULONG_PTR dwContinue)
3044 {
3045     FIXME(":stub\n");
3046     return E_NOTIMPL;
3047 }
3048 
3049 HRESULT __RPC_STUB IViewObject_Draw_Stub(
3050     IViewObject* This,
3051     DWORD dwDrawAspect,
3052     LONG lindex,
3053     ULONG_PTR pvAspect,
3054     DVTARGETDEVICE *ptd,
3055     ULONG_PTR hdcTargetDev,
3056     ULONG_PTR hdcDraw,
3057     LPCRECTL lprcBounds,
3058     LPCRECTL lprcWBounds,
3059     IContinue *pContinue)
3060 {
3061     FIXME(":stub\n");
3062     return E_NOTIMPL;
3063 }
3064 
3065 HRESULT CALLBACK IViewObject_GetColorSet_Proxy(
3066     IViewObject* This,
3067     DWORD dwDrawAspect,
3068     LONG lindex,
3069     void *pvAspect,
3070     DVTARGETDEVICE *ptd,
3071     HDC hicTargetDev,
3072     LOGPALETTE **ppColorSet)
3073 {
3074     FIXME(":stub\n");
3075     return E_NOTIMPL;
3076 }
3077 
3078 HRESULT __RPC_STUB IViewObject_GetColorSet_Stub(
3079     IViewObject* This,
3080     DWORD dwDrawAspect,
3081     LONG lindex,
3082     ULONG_PTR pvAspect,
3083     DVTARGETDEVICE *ptd,
3084     ULONG_PTR hicTargetDev,
3085     LOGPALETTE **ppColorSet)
3086 {
3087     FIXME(":stub\n");
3088     return E_NOTIMPL;
3089 }
3090 
3091 HRESULT CALLBACK IViewObject_Freeze_Proxy(
3092     IViewObject* This,
3093     DWORD dwDrawAspect,
3094     LONG lindex,
3095     void *pvAspect,
3096     DWORD *pdwFreeze)
3097 {
3098     FIXME(":stub\n");
3099     return E_NOTIMPL;
3100 }
3101 
3102 HRESULT __RPC_STUB IViewObject_Freeze_Stub(
3103     IViewObject* This,
3104     DWORD dwDrawAspect,
3105     LONG lindex,
3106     ULONG_PTR pvAspect,
3107     DWORD *pdwFreeze)
3108 {
3109     FIXME(":stub\n");
3110     return E_NOTIMPL;
3111 }
3112 
3113 HRESULT CALLBACK IViewObject_GetAdvise_Proxy(
3114     IViewObject* This,
3115     DWORD *pAspects,
3116     DWORD *pAdvf,
3117     IAdviseSink **ppAdvSink)
3118 {
3119     FIXME(":stub\n");
3120     return E_NOTIMPL;
3121 }
3122 
3123 HRESULT __RPC_STUB IViewObject_GetAdvise_Stub(
3124     IViewObject* This,
3125     DWORD *pAspects,
3126     DWORD *pAdvf,
3127     IAdviseSink **ppAdvSink)
3128 {
3129     FIXME(":stub\n");
3130     return E_NOTIMPL;
3131 }
3132