4 * Copyright 2005 Robert Shearman
5 * Copyright 2009 Huw Davies
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
29 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
30 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
31 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
32 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
34 static const char* debugstr_user_flags(ULONG
*pFlags
)
38 switch (LOWORD(*pFlags
))
41 loword
= "MSHCTX_LOCAL";
43 case MSHCTX_NOSHAREDMEM
:
44 loword
= "MSHCTX_NOSHAREDMEM";
46 case MSHCTX_DIFFERENTMACHINE
:
47 loword
= "MSHCTX_DIFFERENTMACHINE";
50 loword
= "MSHCTX_INPROC";
53 sprintf(buf
, "%d", LOWORD(*pFlags
));
57 if (HIWORD(*pFlags
) == NDR_LOCAL_DATA_REPRESENTATION
)
58 return wine_dbg_sprintf("MAKELONG(%s, NDR_LOCAL_DATA_REPRESENTATION)", loword
);
60 return wine_dbg_sprintf("MAKELONG(%s, 0x%04x)", loword
, HIWORD(*pFlags
));
63 static ULONG
handle_UserSize(ULONG
*pFlags
, ULONG StartingSize
, HANDLE
*handle
)
65 if (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
)
67 ERR("can't remote a local handle\n");
68 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
72 ALIGN_LENGTH(StartingSize
, 3);
73 return StartingSize
+ sizeof(RemotableHandle
);
76 static unsigned char * handle_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HANDLE
*handle
)
78 RemotableHandle
*remhandle
;
79 if (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
)
81 ERR("can't remote a local handle\n");
82 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
86 ALIGN_POINTER(pBuffer
, 3);
87 remhandle
= (RemotableHandle
*)pBuffer
;
88 remhandle
->fContext
= WDT_INPROC_CALL
;
89 remhandle
->u
.hInproc
= (LONG_PTR
)*handle
;
90 return pBuffer
+ sizeof(RemotableHandle
);
93 static unsigned char * handle_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HANDLE
*handle
)
95 RemotableHandle
*remhandle
;
97 ALIGN_POINTER(pBuffer
, 3);
98 remhandle
= (RemotableHandle
*)pBuffer
;
99 if (remhandle
->fContext
!= WDT_INPROC_CALL
)
100 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
101 *handle
= (HANDLE
)(LONG_PTR
)remhandle
->u
.hInproc
;
102 return pBuffer
+ sizeof(RemotableHandle
);
105 static void handle_UserFree(ULONG
*pFlags
, HANDLE
*handle
)
110 #define IMPL_WIREM_HANDLE(type) \
111 ULONG __RPC_USER type##_UserSize(ULONG *pFlags, ULONG StartingSize, type *handle) \
113 TRACE("%s, %lu, %p.\n", debugstr_user_flags(pFlags), StartingSize, handle); \
114 return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \
117 unsigned char * __RPC_USER type##_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
119 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags), pBuffer, *handle); \
120 return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \
123 unsigned char * __RPC_USER type##_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
125 TRACE("%s, %p, %p.\n", debugstr_user_flags(pFlags), pBuffer, handle); \
126 return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \
129 void __RPC_USER type##_UserFree(ULONG *pFlags, type *handle) \
131 TRACE("%s, &%p.\n", debugstr_user_flags(pFlags), *handle); \
132 handle_UserFree(pFlags, (HANDLE *)handle); \
135 IMPL_WIREM_HANDLE(HACCEL
)
136 IMPL_WIREM_HANDLE(HBRUSH
)
137 IMPL_WIREM_HANDLE(HDC
)
138 IMPL_WIREM_HANDLE(HICON
)
139 IMPL_WIREM_HANDLE(HMENU
)
140 IMPL_WIREM_HANDLE(HWND
)
142 /******************************************************************************
143 * CLIPFORMAT_UserSize (combase.@)
145 * Calculates the buffer size required to marshal a clip format.
148 * pFlags [I] Flags. See notes.
149 * StartingSize [I] Starting size of the buffer. This value is added on to
150 * the buffer size required for the clip format.
151 * pCF [I] Clip format to size.
154 * The buffer size required to marshal a clip format plus the starting size.
157 * Even though the function is documented to take a pointer to an unsigned
158 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
159 * the first parameter is an unsigned long.
160 * This function is only intended to be called by the RPC runtime.
162 ULONG __RPC_USER
CLIPFORMAT_UserSize(ULONG
*pFlags
, ULONG size
, CLIPFORMAT
*pCF
)
164 TRACE("%s, %lu, %p.\n", debugstr_user_flags(pFlags
), size
, pCF
);
166 ALIGN_LENGTH(size
, 3);
170 /* only need to marshal the name if it is not a pre-defined type and
171 * we are going remote */
172 if ((*pCF
>= 0xc000) && (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
))
176 size
+= 3 * sizeof(UINT
);
177 /* urg! this function is badly designed because it won't tell us how
178 * much space is needed without doing a dummy run of storing the
179 * name into a buffer */
180 ret
= GetClipboardFormatNameW(*pCF
, format
, ARRAY_SIZE(format
)-1);
182 RaiseException(DV_E_CLIPFORMAT
, 0, 0, NULL
);
183 size
+= (ret
+ 1) * sizeof(WCHAR
);
188 /******************************************************************************
189 * CLIPFORMAT_UserMarshal (combase.@)
191 * Marshals a clip format into a buffer.
194 * pFlags [I] Flags. See notes.
195 * pBuffer [I] Buffer to marshal the clip format into.
196 * pCF [I] Clip format to marshal.
199 * The end of the marshaled data in the buffer.
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.
207 unsigned char * __RPC_USER
CLIPFORMAT_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, CLIPFORMAT
*pCF
)
209 TRACE("%s, %p, &0x%04x.\n", debugstr_user_flags(pFlags
), pBuffer
, *pCF
);
211 ALIGN_POINTER(pBuffer
, 3);
213 /* only need to marshal the name if it is not a pre-defined type and
214 * we are going remote */
215 if ((*pCF
>= 0xc000) && (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
))
220 *(DWORD
*)pBuffer
= WDT_REMOTE_CALL
;
222 *(DWORD
*)pBuffer
= *pCF
;
225 len
= GetClipboardFormatNameW(*pCF
, format
, ARRAY_SIZE(format
)-1);
227 RaiseException(DV_E_CLIPFORMAT
, 0, 0, NULL
);
229 *(UINT
*)pBuffer
= len
;
230 pBuffer
+= sizeof(UINT
);
231 *(UINT
*)pBuffer
= 0;
232 pBuffer
+= sizeof(UINT
);
233 *(UINT
*)pBuffer
= len
;
234 pBuffer
+= sizeof(UINT
);
235 TRACE("marshaling format name %s\n", debugstr_w(format
));
236 memcpy(pBuffer
, format
, len
* sizeof(WCHAR
));
237 pBuffer
+= len
* sizeof(WCHAR
);
241 *(DWORD
*)pBuffer
= WDT_INPROC_CALL
;
243 *(DWORD
*)pBuffer
= *pCF
;
250 /******************************************************************************
251 * CLIPFORMAT_UserUnmarshal (combase.@)
253 * Unmarshals a clip format from a buffer.
256 * pFlags [I] Flags. See notes.
257 * pBuffer [I] Buffer to marshal the clip format from.
258 * pCF [O] Address that receive the unmarshaled clip format.
261 * The end of the marshaled data in the buffer.
264 * Even though the function is documented to take a pointer to an unsigned
265 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
266 * the first parameter is an unsigned long.
267 * This function is only intended to be called by the RPC runtime.
269 unsigned char * __RPC_USER
CLIPFORMAT_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, CLIPFORMAT
*pCF
)
273 TRACE("%s, %p, %p.\n", debugstr_user_flags(pFlags
), pBuffer
, pCF
);
275 ALIGN_POINTER(pBuffer
, 3);
277 fContext
= *(DWORD
*)pBuffer
;
280 if (fContext
== WDT_INPROC_CALL
)
282 *pCF
= *(CLIPFORMAT
*)pBuffer
;
285 else if (fContext
== WDT_REMOTE_CALL
)
290 /* pointer ID for registered clip format string */
291 if (*(DWORD
*)pBuffer
== 0)
292 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
295 len
= *(UINT
*)pBuffer
;
296 pBuffer
+= sizeof(UINT
);
297 if (*(UINT
*)pBuffer
!= 0)
298 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
299 pBuffer
+= sizeof(UINT
);
300 if (*(UINT
*)pBuffer
!= len
)
301 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
302 pBuffer
+= sizeof(UINT
);
303 if (((WCHAR
*)pBuffer
)[len
- 1] != '\0')
304 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
305 TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR
)pBuffer
));
306 cf
= RegisterClipboardFormatW((LPCWSTR
)pBuffer
);
307 pBuffer
+= len
* sizeof(WCHAR
);
309 RaiseException(DV_E_CLIPFORMAT
, 0, 0, NULL
);
313 /* code not really appropriate, but nearest I can find */
314 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
318 /******************************************************************************
319 * CLIPFORMAT_UserFree (combase.@)
321 * Frees an unmarshaled clip format.
324 * pFlags [I] Flags. See notes.
325 * pCF [I] Clip format to free.
328 * The end of the marshaled data in the buffer.
331 * Even though the function is documented to take a pointer to an unsigned
332 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB
333 * structure, of which the first parameter is an unsigned long.
334 * This function is only intended to be called by the RPC runtime.
336 void __RPC_USER
CLIPFORMAT_UserFree(ULONG
*pFlags
, CLIPFORMAT
*pCF
)
338 /* there is no inverse of the RegisterClipboardFormat function,
339 * so nothing to do */
342 /******************************************************************************
343 * HBITMAP_UserSize (combase.@)
345 * Calculates the buffer size required to marshal a bitmap.
348 * pFlags [I] Flags. See notes.
349 * StartingSize [I] Starting size of the buffer. This value is added on to
350 * the buffer size required for the clip format.
351 * phBmp [I] Bitmap to size.
354 * The buffer size required to marshal an bitmap plus the starting size.
357 * Even though the function is documented to take a pointer to a ULONG in
358 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
359 * the first parameter is a ULONG.
360 * This function is only intended to be called by the RPC runtime.
362 ULONG __RPC_USER
HBITMAP_UserSize(ULONG
*flags
, ULONG size
, HBITMAP
*bmp
)
364 TRACE("%s, %lu, %p.\n", debugstr_user_flags(flags
), size
, *bmp
);
366 ALIGN_LENGTH(size
, 3);
368 size
+= sizeof(ULONG
);
369 if (LOWORD(*flags
) == MSHCTX_INPROC
)
370 size
+= sizeof(ULONG
);
373 size
+= sizeof(ULONG
);
377 size
+= sizeof(ULONG
);
378 size
+= FIELD_OFFSET(userBITMAP
, cbSize
);
379 size
+= GetBitmapBits(*bmp
, 0, NULL
);
386 /******************************************************************************
387 * HBITMAP_UserMarshal (combase.@)
389 * Marshals a bitmap into a buffer.
392 * pFlags [I] Flags. See notes.
393 * pBuffer [I] Buffer to marshal the clip format into.
394 * phBmp [I] Bitmap to marshal.
397 * The end of the marshaled data in the buffer.
400 * Even though the function is documented to take a pointer to a ULONG in
401 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
402 * the first parameter is a ULONG.
403 * This function is only intended to be called by the RPC runtime.
405 unsigned char * __RPC_USER
HBITMAP_UserMarshal(ULONG
*flags
, unsigned char *buffer
, HBITMAP
*bmp
)
407 TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags
), buffer
, *bmp
);
409 ALIGN_POINTER(buffer
, 3);
411 if (LOWORD(*flags
) == MSHCTX_INPROC
)
413 *(ULONG
*)buffer
= WDT_INPROC_CALL
;
414 buffer
+= sizeof(ULONG
);
415 *(ULONG
*)buffer
= (ULONG
)(ULONG_PTR
)*bmp
;
416 buffer
+= sizeof(ULONG
);
420 *(ULONG
*)buffer
= WDT_REMOTE_CALL
;
421 buffer
+= sizeof(ULONG
);
422 *(ULONG
*)buffer
= (ULONG
)(ULONG_PTR
)*bmp
;
423 buffer
+= sizeof(ULONG
);
427 static const ULONG header_size
= FIELD_OFFSET(userBITMAP
, cbSize
);
431 bitmap_size
= GetBitmapBits(*bmp
, 0, NULL
);
432 *(ULONG
*)buffer
= bitmap_size
;
433 buffer
+= sizeof(ULONG
);
435 GetObjectW(*bmp
, sizeof(BITMAP
), &bitmap
);
436 memcpy(buffer
, &bitmap
, header_size
);
437 buffer
+= header_size
;
439 GetBitmapBits(*bmp
, bitmap_size
, buffer
);
440 buffer
+= bitmap_size
;
446 /******************************************************************************
447 * HBITMAP_UserUnmarshal (combase.@)
449 * Unmarshals a bitmap from a buffer.
452 * pFlags [I] Flags. See notes.
453 * pBuffer [I] Buffer to marshal the clip format from.
454 * phBmp [O] Address that receive the unmarshaled bitmap.
457 * The end of the marshaled data in the buffer.
460 * Even though the function is documented to take a pointer to an ULONG in
461 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
462 * the first parameter is an ULONG.
463 * This function is only intended to be called by the RPC runtime.
465 unsigned char * __RPC_USER
HBITMAP_UserUnmarshal(ULONG
*flags
, unsigned char *buffer
, HBITMAP
*bmp
)
469 TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags
), buffer
, bmp
);
471 ALIGN_POINTER(buffer
, 3);
473 context
= *(ULONG
*)buffer
;
474 buffer
+= sizeof(ULONG
);
476 if (context
== WDT_INPROC_CALL
)
478 *bmp
= *(HBITMAP
*)buffer
;
479 buffer
+= sizeof(*bmp
);
481 else if (context
== WDT_REMOTE_CALL
)
483 ULONG handle
= *(ULONG
*)buffer
;
484 buffer
+= sizeof(ULONG
);
488 static const ULONG header_size
= FIELD_OFFSET(userBITMAP
, cbSize
);
493 bitmap_size
= *(ULONG
*)buffer
;
494 buffer
+= sizeof(ULONG
);
495 bits
= malloc(bitmap_size
);
497 memcpy(&bitmap
, buffer
, header_size
);
498 buffer
+= header_size
;
500 memcpy(bits
, buffer
, bitmap_size
);
501 buffer
+= bitmap_size
;
503 bitmap
.bmBits
= bits
;
504 *bmp
= CreateBitmapIndirect(&bitmap
);
512 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
517 /******************************************************************************
518 * HBITMAP_UserFree (combase.@)
520 * Frees an unmarshaled bitmap.
523 * pFlags [I] Flags. See notes.
524 * phBmp [I] Bitmap to free.
527 * The end of the marshaled data in the buffer.
530 * Even though the function is documented to take a pointer to a ULONG in
531 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
532 * which the first parameter is a ULONG.
533 * This function is only intended to be called by the RPC runtime.
535 void __RPC_USER
HBITMAP_UserFree(ULONG
*flags
, HBITMAP
*bmp
)
537 TRACE("(%s, %p)\n", debugstr_user_flags(flags
), *bmp
);
539 if (LOWORD(*flags
) != MSHCTX_INPROC
)
543 /******************************************************************************
544 * HPALETTE_UserSize (combase.@)
546 * Calculates the buffer size required to marshal a palette.
549 * pFlags [I] Flags. See notes.
550 * StartingSize [I] Starting size of the buffer. This value is added on to
551 * the buffer size required for the clip format.
552 * phPal [I] Palette to size.
555 * The buffer size required to marshal a palette plus the starting size.
558 * Even though the function is documented to take a pointer to a ULONG in
559 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
560 * the first parameter is a ULONG.
561 * This function is only intended to be called by the RPC runtime.
563 ULONG __RPC_USER
HPALETTE_UserSize(ULONG
*pFlags
, ULONG StartingSize
, HPALETTE
*phPal
)
569 /******************************************************************************
570 * HPALETTE_UserMarshal (combase.@)
572 * Marshals a palette into a buffer.
575 * pFlags [I] Flags. See notes.
576 * pBuffer [I] Buffer to marshal the clip format into.
577 * phPal [I] Palette to marshal.
580 * The end of the marshaled data in the buffer.
583 * Even though the function is documented to take a pointer to a ULONG in
584 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
585 * the first parameter is a ULONG.
586 * This function is only intended to be called by the RPC runtime.
588 unsigned char * __RPC_USER
HPALETTE_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HPALETTE
*phPal
)
594 /******************************************************************************
595 * HPALETTE_UserUnmarshal (combase.@)
597 * Unmarshals a palette from a buffer.
600 * pFlags [I] Flags. See notes.
601 * pBuffer [I] Buffer to marshal the clip format from.
602 * phPal [O] Address that receive the unmarshaled palette.
605 * The end of the marshaled data in the buffer.
608 * Even though the function is documented to take a pointer to an ULONG in
609 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
610 * the first parameter is an ULONG.
611 * This function is only intended to be called by the RPC runtime.
613 unsigned char * __RPC_USER
HPALETTE_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HPALETTE
*phPal
)
619 /******************************************************************************
620 * HGLOBAL_UserSize (combase.@)
622 * Calculates the buffer size required to marshal an HGLOBAL.
625 * pFlags [I] Flags. See notes.
626 * StartingSize [I] Starting size of the buffer. This value is added on to
627 * the buffer size required for the clip format.
628 * phGlobal [I] HGLOBAL to size.
631 * The buffer size required to marshal an HGLOBAL plus the starting size.
634 * Even though the function is documented to take a pointer to a ULONG in
635 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
636 * the first parameter is a ULONG.
637 * This function is only intended to be called by the RPC runtime.
639 ULONG __RPC_USER
HGLOBAL_UserSize(ULONG
*pFlags
, ULONG StartingSize
, HGLOBAL
*phGlobal
)
641 ULONG size
= StartingSize
;
643 TRACE("%s, %lu, %p.\n", debugstr_user_flags(pFlags
), StartingSize
, phGlobal
);
645 ALIGN_LENGTH(size
, 3);
647 size
+= sizeof(ULONG
);
649 if (LOWORD(*pFlags
) == MSHCTX_INPROC
)
650 size
+= sizeof(HGLOBAL
);
653 size
+= sizeof(ULONG
);
657 size
+= 3 * sizeof(ULONG
);
658 ret
= GlobalSize(*phGlobal
);
666 /******************************************************************************
667 * HGLOBAL_UserMarshal (combase.@)
669 * Marshals an HGLOBAL into a buffer.
672 * pFlags [I] Flags. See notes.
673 * pBuffer [I] Buffer to marshal the clip format into.
674 * phGlobal [I] HGLOBAL to marshal.
677 * The end of the marshaled data in the buffer.
680 * Even though the function is documented to take a pointer to a ULONG in
681 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
682 * the first parameter is a ULONG.
683 * This function is only intended to be called by the RPC runtime.
685 unsigned char * __RPC_USER
HGLOBAL_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HGLOBAL
*phGlobal
)
687 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags
), pBuffer
, *phGlobal
);
689 ALIGN_POINTER(pBuffer
, 3);
691 if (LOWORD(*pFlags
) == MSHCTX_INPROC
)
693 if (sizeof(*phGlobal
) == 8)
694 *(ULONG
*)pBuffer
= WDT_INPROC64_CALL
;
696 *(ULONG
*)pBuffer
= WDT_INPROC_CALL
;
697 pBuffer
+= sizeof(ULONG
);
698 *(HGLOBAL
*)pBuffer
= *phGlobal
;
699 pBuffer
+= sizeof(HGLOBAL
);
703 *(ULONG
*)pBuffer
= WDT_REMOTE_CALL
;
704 pBuffer
+= sizeof(ULONG
);
705 *(ULONG
*)pBuffer
= HandleToULong(*phGlobal
);
706 pBuffer
+= sizeof(ULONG
);
709 const unsigned char *memory
;
710 SIZE_T size
= GlobalSize(*phGlobal
);
711 *(ULONG
*)pBuffer
= (ULONG
)size
;
712 pBuffer
+= sizeof(ULONG
);
713 *(ULONG
*)pBuffer
= HandleToULong(*phGlobal
);
714 pBuffer
+= sizeof(ULONG
);
715 *(ULONG
*)pBuffer
= (ULONG
)size
;
716 pBuffer
+= sizeof(ULONG
);
718 memory
= GlobalLock(*phGlobal
);
719 memcpy(pBuffer
, memory
, size
);
721 GlobalUnlock(*phGlobal
);
728 /******************************************************************************
729 * HGLOBAL_UserUnmarshal (combase.@)
731 * Unmarshals an HGLOBAL from a buffer.
734 * pFlags [I] Flags. See notes.
735 * pBuffer [I] Buffer to marshal the clip format from.
736 * phGlobal [O] Address that receive the unmarshaled HGLOBAL.
739 * The end of the marshaled data in the buffer.
742 * Even though the function is documented to take a pointer to an ULONG in
743 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
744 * the first parameter is an ULONG.
745 * This function is only intended to be called by the RPC runtime.
747 unsigned char * __RPC_USER
HGLOBAL_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HGLOBAL
*phGlobal
)
751 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags
), pBuffer
, *phGlobal
);
753 ALIGN_POINTER(pBuffer
, 3);
755 fContext
= *(ULONG
*)pBuffer
;
756 pBuffer
+= sizeof(ULONG
);
758 if (((fContext
== WDT_INPROC_CALL
) && (sizeof(*phGlobal
) < 8)) ||
759 ((fContext
== WDT_INPROC64_CALL
) && (sizeof(*phGlobal
) == 8)))
761 *phGlobal
= *(HGLOBAL
*)pBuffer
;
762 pBuffer
+= sizeof(*phGlobal
);
764 else if (fContext
== WDT_REMOTE_CALL
)
768 handle
= *(ULONG
*)pBuffer
;
769 pBuffer
+= sizeof(ULONG
);
776 size
= *(ULONG
*)pBuffer
;
777 pBuffer
+= sizeof(ULONG
);
778 /* redundancy is bad - it means you have to check consistency like
780 if (*(ULONG
*)pBuffer
!= handle
)
782 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
785 pBuffer
+= sizeof(ULONG
);
786 /* redundancy is bad - it means you have to check consistency like
788 if (*(ULONG
*)pBuffer
!= size
)
790 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
793 pBuffer
+= sizeof(ULONG
);
795 /* FIXME: check size is not too big */
797 *phGlobal
= GlobalAlloc(GMEM_MOVEABLE
, size
);
798 memory
= GlobalLock(*phGlobal
);
799 memcpy(memory
, pBuffer
, size
);
801 GlobalUnlock(*phGlobal
);
807 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
812 /******************************************************************************
813 * HGLOBAL_UserFree (combase.@)
815 * Frees an unmarshaled HGLOBAL.
818 * pFlags [I] Flags. See notes.
819 * phGlobal [I] HGLOBAL to free.
822 * The end of the marshaled data in the buffer.
825 * Even though the function is documented to take a pointer to a ULONG in
826 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
827 * which the first parameter is a ULONG.
828 * This function is only intended to be called by the RPC runtime.
830 void __RPC_USER
HGLOBAL_UserFree(ULONG
*pFlags
, HGLOBAL
*phGlobal
)
832 TRACE("%s, &%p.\n", debugstr_user_flags(pFlags
), *phGlobal
);
834 if (LOWORD(*pFlags
) != MSHCTX_INPROC
&& *phGlobal
)
835 GlobalFree(*phGlobal
);
838 /******************************************************************************
839 * HPALETTE_UserFree (combase.@)
841 * Frees an unmarshaled palette.
844 * pFlags [I] Flags. See notes.
845 * phPal [I] Palette to free.
848 * The end of the marshaled data in the buffer.
851 * Even though the function is documented to take a pointer to a ULONG in
852 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
853 * which the first parameter is a ULONG.
854 * This function is only intended to be called by the RPC runtime.
856 void __RPC_USER
HPALETTE_UserFree(ULONG
*pFlags
, HPALETTE
*phPal
)
861 /******************************************************************************
862 * WdtpInterfacePointer_UserSize (combase.@)
864 * Calculates the buffer size required to marshal an interface pointer.
867 * pFlags [I] Flags. See notes.
868 * RealFlags [I] The MSHCTX to use when marshaling the interface.
869 * punk [I] Interface pointer to size.
870 * StartingSize [I] Starting size of the buffer. This value is added on to
871 * the buffer size required for the clip format.
872 * riid [I] ID of interface to size.
875 * The buffer size required to marshal an interface pointer plus the starting size.
878 * Even though the function is documented to take a pointer to a ULONG in
879 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
880 * the first parameter is a ULONG.
882 ULONG __RPC_USER
WdtpInterfacePointer_UserSize(ULONG
*pFlags
, ULONG RealFlags
, ULONG StartingSize
, IUnknown
*punk
, REFIID riid
)
884 DWORD marshal_size
= 0;
887 TRACE("%s, %#lx, %lu, %p, %s.\n", debugstr_user_flags(pFlags
), RealFlags
, StartingSize
, punk
, debugstr_guid(riid
));
889 hr
= CoGetMarshalSizeMax(&marshal_size
, riid
, punk
, LOWORD(RealFlags
), NULL
, MSHLFLAGS_NORMAL
);
890 if (FAILED(hr
)) return StartingSize
;
892 ALIGN_LENGTH(StartingSize
, 3);
893 StartingSize
+= 2 * sizeof(DWORD
);
894 return StartingSize
+ marshal_size
;
897 /******************************************************************************
898 * WdtpInterfacePointer_UserMarshal (combase.@)
900 * Marshals an interface pointer into a buffer.
903 * pFlags [I] Flags. See notes.
904 * RealFlags [I] The MSHCTX to use when marshaling the interface.
905 * pBuffer [I] Buffer to marshal the clip format into.
906 * punk [I] Interface pointer to marshal.
907 * riid [I] ID of interface to marshal.
910 * The end of the marshaled data in the buffer.
913 * Even though the function is documented to take a pointer to a ULONG in
914 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
915 * the first parameter is a ULONG.
917 unsigned char * WINAPI
WdtpInterfacePointer_UserMarshal(ULONG
*pFlags
, ULONG RealFlags
, unsigned char *pBuffer
, IUnknown
*punk
, REFIID riid
)
919 HGLOBAL h
= GlobalAlloc(GMEM_MOVEABLE
, 0);
924 TRACE("%s, %#lx, %p, &%p, %s.\n", debugstr_user_flags(pFlags
), RealFlags
, pBuffer
, punk
, debugstr_guid(riid
));
927 if (CreateStreamOnHGlobal(h
, TRUE
, &stm
) != S_OK
)
933 if (CoMarshalInterface(stm
, riid
, punk
, LOWORD(RealFlags
), NULL
, MSHLFLAGS_NORMAL
) != S_OK
)
935 IStream_Release(stm
);
939 ALIGN_POINTER(pBuffer
, 3);
940 size
= GlobalSize(h
);
942 *(DWORD
*)pBuffer
= size
;
943 pBuffer
+= sizeof(DWORD
);
944 *(DWORD
*)pBuffer
= size
;
945 pBuffer
+= sizeof(DWORD
);
948 memcpy(pBuffer
, ptr
, size
);
951 IStream_Release(stm
);
952 return pBuffer
+ size
;
955 /******************************************************************************
956 * WdtpInterfacePointer_UserUnmarshal (combase.@)
958 * Unmarshals an interface pointer from a buffer.
961 * pFlags [I] Flags. See notes.
962 * pBuffer [I] Buffer to marshal the clip format from.
963 * ppunk [I/O] Address that receives the unmarshaled interface pointer.
964 * riid [I] ID of interface to unmarshal.
967 * The end of the marshaled data in the buffer.
970 * Even though the function is documented to take a pointer to an ULONG in
971 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
972 * the first parameter is an ULONG.
974 unsigned char * WINAPI
WdtpInterfacePointer_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, IUnknown
**ppunk
, REFIID riid
)
983 TRACE("%s, %p, %p, %s.\n", debugstr_user_flags(pFlags
), pBuffer
, ppunk
, debugstr_guid(riid
));
985 ALIGN_POINTER(pBuffer
, 3);
987 size
= *(DWORD
*)pBuffer
;
988 pBuffer
+= sizeof(DWORD
);
989 if (size
!= *(DWORD
*)pBuffer
)
990 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
992 pBuffer
+= sizeof(DWORD
);
994 /* FIXME: sanity check on size */
996 h
= GlobalAlloc(GMEM_MOVEABLE
, size
);
997 if (!h
) RaiseException(RPC_X_NO_MEMORY
, 0, 0, NULL
);
999 if (CreateStreamOnHGlobal(h
, TRUE
, &stm
) != S_OK
)
1002 RaiseException(RPC_X_NO_MEMORY
, 0, 0, NULL
);
1005 ptr
= GlobalLock(h
);
1006 memcpy(ptr
, pBuffer
, size
);
1010 hr
= CoUnmarshalInterface(stm
, riid
, (void**)ppunk
);
1011 IStream_Release(stm
);
1013 if (hr
!= S_OK
) RaiseException(hr
, 0, 0, NULL
);
1015 if (orig
) IUnknown_Release(orig
);
1017 return pBuffer
+ size
;
1020 /******************************************************************************
1021 * WdtpInterfacePointer_UserFree (combase.@)
1023 void WINAPI
WdtpInterfacePointer_UserFree(IUnknown
*punk
)
1025 TRACE("%p.\n", punk
);
1026 if (punk
) IUnknown_Release(punk
);