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