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