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
23 #define NONAMELESSUNION
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
31 #define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
32 #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
33 #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
34 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
36 static const char* debugstr_user_flags(ULONG
*pFlags
)
40 switch (LOWORD(*pFlags
))
43 loword
= "MSHCTX_LOCAL";
45 case MSHCTX_NOSHAREDMEM
:
46 loword
= "MSHCTX_NOSHAREDMEM";
48 case MSHCTX_DIFFERENTMACHINE
:
49 loword
= "MSHCTX_DIFFERENTMACHINE";
52 loword
= "MSHCTX_INPROC";
55 sprintf(buf
, "%d", LOWORD(*pFlags
));
59 if (HIWORD(*pFlags
) == NDR_LOCAL_DATA_REPRESENTATION
)
60 return wine_dbg_sprintf("MAKELONG(%s, NDR_LOCAL_DATA_REPRESENTATION)", loword
);
62 return wine_dbg_sprintf("MAKELONG(%s, 0x%04x)", loword
, HIWORD(*pFlags
));
65 static ULONG
handle_UserSize(ULONG
*pFlags
, ULONG StartingSize
, HANDLE
*handle
)
67 if (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
)
69 ERR("can't remote a local handle\n");
70 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
74 ALIGN_LENGTH(StartingSize
, 3);
75 return StartingSize
+ sizeof(RemotableHandle
);
78 static unsigned char * handle_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HANDLE
*handle
)
80 RemotableHandle
*remhandle
;
81 if (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
)
83 ERR("can't remote a local handle\n");
84 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
88 ALIGN_POINTER(pBuffer
, 3);
89 remhandle
= (RemotableHandle
*)pBuffer
;
90 remhandle
->fContext
= WDT_INPROC_CALL
;
91 remhandle
->u
.hInproc
= (LONG_PTR
)*handle
;
92 return pBuffer
+ sizeof(RemotableHandle
);
95 static unsigned char * handle_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HANDLE
*handle
)
97 RemotableHandle
*remhandle
;
99 ALIGN_POINTER(pBuffer
, 3);
100 remhandle
= (RemotableHandle
*)pBuffer
;
101 if (remhandle
->fContext
!= WDT_INPROC_CALL
)
102 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
103 *handle
= (HANDLE
)(LONG_PTR
)remhandle
->u
.hInproc
;
104 return pBuffer
+ sizeof(RemotableHandle
);
107 static void handle_UserFree(ULONG
*pFlags
, HANDLE
*handle
)
112 #define IMPL_WIREM_HANDLE(type) \
113 ULONG __RPC_USER type##_UserSize(ULONG *pFlags, ULONG StartingSize, type *handle) \
115 TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, handle); \
116 return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \
119 unsigned char * __RPC_USER type##_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
121 TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *handle); \
122 return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \
125 unsigned char * __RPC_USER type##_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
127 TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, handle); \
128 return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \
131 void __RPC_USER type##_UserFree(ULONG *pFlags, type *handle) \
133 TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *handle); \
134 handle_UserFree(pFlags, (HANDLE *)handle); \
137 IMPL_WIREM_HANDLE(HACCEL
)
138 IMPL_WIREM_HANDLE(HBRUSH
)
139 IMPL_WIREM_HANDLE(HDC
)
140 IMPL_WIREM_HANDLE(HICON
)
141 IMPL_WIREM_HANDLE(HMENU
)
142 IMPL_WIREM_HANDLE(HWND
)
144 /******************************************************************************
145 * CLIPFORMAT_UserSize (combase.@)
147 * Calculates the buffer size required to marshal a clip format.
150 * pFlags [I] Flags. See notes.
151 * StartingSize [I] Starting size of the buffer. This value is added on to
152 * the buffer size required for the clip format.
153 * pCF [I] Clip format to size.
156 * The buffer size required to marshal a clip format plus the starting size.
159 * Even though the function is documented to take a pointer to an unsigned
160 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
161 * the first parameter is an unsigned long.
162 * This function is only intended to be called by the RPC runtime.
164 ULONG __RPC_USER
CLIPFORMAT_UserSize(ULONG
*pFlags
, ULONG size
, CLIPFORMAT
*pCF
)
166 TRACE("%s, %u, %p\n", debugstr_user_flags(pFlags
), size
, pCF
);
168 ALIGN_LENGTH(size
, 3);
172 /* only need to marshal the name if it is not a pre-defined type and
173 * we are going remote */
174 if ((*pCF
>= 0xc000) && (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
))
178 size
+= 3 * sizeof(UINT
);
179 /* urg! this function is badly designed because it won't tell us how
180 * much space is needed without doing a dummy run of storing the
181 * name into a buffer */
182 ret
= GetClipboardFormatNameW(*pCF
, format
, ARRAY_SIZE(format
)-1);
184 RaiseException(DV_E_CLIPFORMAT
, 0, 0, NULL
);
185 size
+= (ret
+ 1) * sizeof(WCHAR
);
190 /******************************************************************************
191 * CLIPFORMAT_UserMarshal (combase.@)
193 * Marshals a clip format into a buffer.
196 * pFlags [I] Flags. See notes.
197 * pBuffer [I] Buffer to marshal the clip format into.
198 * pCF [I] Clip format to marshal.
201 * The end of the marshaled data in the buffer.
204 * Even though the function is documented to take a pointer to an unsigned
205 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
206 * the first parameter is an unsigned long.
207 * This function is only intended to be called by the RPC runtime.
209 unsigned char * __RPC_USER
CLIPFORMAT_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, CLIPFORMAT
*pCF
)
211 TRACE("%s, %p, &0x%04x.\n", debugstr_user_flags(pFlags
), pBuffer
, *pCF
);
213 ALIGN_POINTER(pBuffer
, 3);
215 /* only need to marshal the name if it is not a pre-defined type and
216 * we are going remote */
217 if ((*pCF
>= 0xc000) && (LOWORD(*pFlags
) == MSHCTX_DIFFERENTMACHINE
))
222 *(DWORD
*)pBuffer
= WDT_REMOTE_CALL
;
224 *(DWORD
*)pBuffer
= *pCF
;
227 len
= GetClipboardFormatNameW(*pCF
, format
, ARRAY_SIZE(format
)-1);
229 RaiseException(DV_E_CLIPFORMAT
, 0, 0, NULL
);
231 *(UINT
*)pBuffer
= len
;
232 pBuffer
+= sizeof(UINT
);
233 *(UINT
*)pBuffer
= 0;
234 pBuffer
+= sizeof(UINT
);
235 *(UINT
*)pBuffer
= len
;
236 pBuffer
+= sizeof(UINT
);
237 TRACE("marshaling format name %s\n", debugstr_w(format
));
238 memcpy(pBuffer
, format
, len
* sizeof(WCHAR
));
239 pBuffer
+= len
* sizeof(WCHAR
);
243 *(DWORD
*)pBuffer
= WDT_INPROC_CALL
;
245 *(DWORD
*)pBuffer
= *pCF
;
252 /******************************************************************************
253 * CLIPFORMAT_UserUnmarshal (combase.@)
255 * Unmarshals a clip format from a buffer.
258 * pFlags [I] Flags. See notes.
259 * pBuffer [I] Buffer to marshal the clip format from.
260 * pCF [O] Address that receive the unmarshaled clip format.
263 * The end of the marshaled data in the buffer.
266 * Even though the function is documented to take a pointer to an unsigned
267 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
268 * the first parameter is an unsigned long.
269 * This function is only intended to be called by the RPC runtime.
271 unsigned char * __RPC_USER
CLIPFORMAT_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, CLIPFORMAT
*pCF
)
275 TRACE("%s, %p, %p.\n", debugstr_user_flags(pFlags
), pBuffer
, pCF
);
277 ALIGN_POINTER(pBuffer
, 3);
279 fContext
= *(DWORD
*)pBuffer
;
282 if (fContext
== WDT_INPROC_CALL
)
284 *pCF
= *(CLIPFORMAT
*)pBuffer
;
287 else if (fContext
== WDT_REMOTE_CALL
)
292 /* pointer ID for registered clip format string */
293 if (*(DWORD
*)pBuffer
== 0)
294 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
297 len
= *(UINT
*)pBuffer
;
298 pBuffer
+= sizeof(UINT
);
299 if (*(UINT
*)pBuffer
!= 0)
300 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
301 pBuffer
+= sizeof(UINT
);
302 if (*(UINT
*)pBuffer
!= len
)
303 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
304 pBuffer
+= sizeof(UINT
);
305 if (((WCHAR
*)pBuffer
)[len
- 1] != '\0')
306 RaiseException(RPC_S_INVALID_BOUND
, 0, 0, NULL
);
307 TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR
)pBuffer
));
308 cf
= RegisterClipboardFormatW((LPCWSTR
)pBuffer
);
309 pBuffer
+= len
* sizeof(WCHAR
);
311 RaiseException(DV_E_CLIPFORMAT
, 0, 0, NULL
);
315 /* code not really appropriate, but nearest I can find */
316 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
320 /******************************************************************************
321 * CLIPFORMAT_UserFree (combase.@)
323 * Frees an unmarshaled clip format.
326 * pFlags [I] Flags. See notes.
327 * pCF [I] Clip format to free.
330 * The end of the marshaled data in the buffer.
333 * Even though the function is documented to take a pointer to an unsigned
334 * long in pFlags, it actually takes a pointer to a USER_MARSHAL_CB
335 * structure, of which the first parameter is an unsigned long.
336 * This function is only intended to be called by the RPC runtime.
338 void __RPC_USER
CLIPFORMAT_UserFree(ULONG
*pFlags
, CLIPFORMAT
*pCF
)
340 /* there is no inverse of the RegisterClipboardFormat function,
341 * so nothing to do */
344 /******************************************************************************
345 * HBITMAP_UserSize (combase.@)
347 * Calculates the buffer size required to marshal a bitmap.
350 * pFlags [I] Flags. See notes.
351 * StartingSize [I] Starting size of the buffer. This value is added on to
352 * the buffer size required for the clip format.
353 * phBmp [I] Bitmap to size.
356 * The buffer size required to marshal an bitmap plus the starting size.
359 * Even though the function is documented to take a pointer to a ULONG in
360 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
361 * the first parameter is a ULONG.
362 * This function is only intended to be called by the RPC runtime.
364 ULONG __RPC_USER
HBITMAP_UserSize(ULONG
*flags
, ULONG size
, HBITMAP
*bmp
)
366 TRACE("(%s, %d, %p)\n", debugstr_user_flags(flags
), size
, *bmp
);
368 ALIGN_LENGTH(size
, 3);
370 size
+= sizeof(ULONG
);
371 if (LOWORD(*flags
) == MSHCTX_INPROC
)
372 size
+= sizeof(ULONG
);
375 size
+= sizeof(ULONG
);
379 size
+= sizeof(ULONG
);
380 size
+= FIELD_OFFSET(userBITMAP
, cbSize
);
381 size
+= GetBitmapBits(*bmp
, 0, NULL
);
388 /******************************************************************************
389 * HBITMAP_UserMarshal (combase.@)
391 * Marshals a bitmap into a buffer.
394 * pFlags [I] Flags. See notes.
395 * pBuffer [I] Buffer to marshal the clip format into.
396 * phBmp [I] Bitmap to marshal.
399 * The end of the marshaled data in the buffer.
402 * Even though the function is documented to take a pointer to a ULONG in
403 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
404 * the first parameter is a ULONG.
405 * This function is only intended to be called by the RPC runtime.
407 unsigned char * __RPC_USER
HBITMAP_UserMarshal(ULONG
*flags
, unsigned char *buffer
, HBITMAP
*bmp
)
409 TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags
), buffer
, *bmp
);
411 ALIGN_POINTER(buffer
, 3);
413 if (LOWORD(*flags
) == MSHCTX_INPROC
)
415 *(ULONG
*)buffer
= WDT_INPROC_CALL
;
416 buffer
+= sizeof(ULONG
);
417 *(ULONG
*)buffer
= (ULONG
)(ULONG_PTR
)*bmp
;
418 buffer
+= sizeof(ULONG
);
422 *(ULONG
*)buffer
= WDT_REMOTE_CALL
;
423 buffer
+= sizeof(ULONG
);
424 *(ULONG
*)buffer
= (ULONG
)(ULONG_PTR
)*bmp
;
425 buffer
+= sizeof(ULONG
);
429 static const ULONG header_size
= FIELD_OFFSET(userBITMAP
, cbSize
);
433 bitmap_size
= GetBitmapBits(*bmp
, 0, NULL
);
434 *(ULONG
*)buffer
= bitmap_size
;
435 buffer
+= sizeof(ULONG
);
437 GetObjectW(*bmp
, sizeof(BITMAP
), &bitmap
);
438 memcpy(buffer
, &bitmap
, header_size
);
439 buffer
+= header_size
;
441 GetBitmapBits(*bmp
, bitmap_size
, buffer
);
442 buffer
+= bitmap_size
;
448 /******************************************************************************
449 * HBITMAP_UserUnmarshal (combase.@)
451 * Unmarshals a bitmap from a buffer.
454 * pFlags [I] Flags. See notes.
455 * pBuffer [I] Buffer to marshal the clip format from.
456 * phBmp [O] Address that receive the unmarshaled bitmap.
459 * The end of the marshaled data in the buffer.
462 * Even though the function is documented to take a pointer to an ULONG in
463 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
464 * the first parameter is an ULONG.
465 * This function is only intended to be called by the RPC runtime.
467 unsigned char * __RPC_USER
HBITMAP_UserUnmarshal(ULONG
*flags
, unsigned char *buffer
, HBITMAP
*bmp
)
471 TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags
), buffer
, bmp
);
473 ALIGN_POINTER(buffer
, 3);
475 context
= *(ULONG
*)buffer
;
476 buffer
+= sizeof(ULONG
);
478 if (context
== WDT_INPROC_CALL
)
480 *bmp
= *(HBITMAP
*)buffer
;
481 buffer
+= sizeof(*bmp
);
483 else if (context
== WDT_REMOTE_CALL
)
485 ULONG handle
= *(ULONG
*)buffer
;
486 buffer
+= sizeof(ULONG
);
490 static const ULONG header_size
= FIELD_OFFSET(userBITMAP
, cbSize
);
495 bitmap_size
= *(ULONG
*)buffer
;
496 buffer
+= sizeof(ULONG
);
497 bits
= HeapAlloc(GetProcessHeap(), 0, bitmap_size
);
499 memcpy(&bitmap
, buffer
, header_size
);
500 buffer
+= header_size
;
502 memcpy(bits
, buffer
, bitmap_size
);
503 buffer
+= bitmap_size
;
505 bitmap
.bmBits
= bits
;
506 *bmp
= CreateBitmapIndirect(&bitmap
);
508 HeapFree(GetProcessHeap(), 0, bits
);
514 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
519 /******************************************************************************
520 * HBITMAP_UserFree (combase.@)
522 * Frees an unmarshaled bitmap.
525 * pFlags [I] Flags. See notes.
526 * phBmp [I] Bitmap to free.
529 * The end of the marshaled data in the buffer.
532 * Even though the function is documented to take a pointer to a ULONG in
533 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
534 * which the first parameter is a ULONG.
535 * This function is only intended to be called by the RPC runtime.
537 void __RPC_USER
HBITMAP_UserFree(ULONG
*flags
, HBITMAP
*bmp
)
539 TRACE("(%s, %p)\n", debugstr_user_flags(flags
), *bmp
);
541 if (LOWORD(*flags
) != MSHCTX_INPROC
)
545 /******************************************************************************
546 * HPALETTE_UserSize (combase.@)
548 * Calculates the buffer size required to marshal a palette.
551 * pFlags [I] Flags. See notes.
552 * StartingSize [I] Starting size of the buffer. This value is added on to
553 * the buffer size required for the clip format.
554 * phPal [I] Palette to size.
557 * The buffer size required to marshal a palette plus the starting size.
560 * Even though the function is documented to take a pointer to a ULONG in
561 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
562 * the first parameter is a ULONG.
563 * This function is only intended to be called by the RPC runtime.
565 ULONG __RPC_USER
HPALETTE_UserSize(ULONG
*pFlags
, ULONG StartingSize
, HPALETTE
*phPal
)
571 /******************************************************************************
572 * HPALETTE_UserMarshal (combase.@)
574 * Marshals a palette into a buffer.
577 * pFlags [I] Flags. See notes.
578 * pBuffer [I] Buffer to marshal the clip format into.
579 * phPal [I] Palette to marshal.
582 * The end of the marshaled data in the buffer.
585 * Even though the function is documented to take a pointer to a ULONG in
586 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
587 * the first parameter is a ULONG.
588 * This function is only intended to be called by the RPC runtime.
590 unsigned char * __RPC_USER
HPALETTE_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HPALETTE
*phPal
)
596 /******************************************************************************
597 * HPALETTE_UserUnmarshal (combase.@)
599 * Unmarshals a palette from a buffer.
602 * pFlags [I] Flags. See notes.
603 * pBuffer [I] Buffer to marshal the clip format from.
604 * phPal [O] Address that receive the unmarshaled palette.
607 * The end of the marshaled data in the buffer.
610 * Even though the function is documented to take a pointer to an ULONG in
611 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
612 * the first parameter is an ULONG.
613 * This function is only intended to be called by the RPC runtime.
615 unsigned char * __RPC_USER
HPALETTE_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HPALETTE
*phPal
)
621 /******************************************************************************
622 * HGLOBAL_UserSize (combase.@)
624 * Calculates the buffer size required to marshal an HGLOBAL.
627 * pFlags [I] Flags. See notes.
628 * StartingSize [I] Starting size of the buffer. This value is added on to
629 * the buffer size required for the clip format.
630 * phGlobal [I] HGLOBAL to size.
633 * The buffer size required to marshal an HGLOBAL plus the starting size.
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.
641 ULONG __RPC_USER
HGLOBAL_UserSize(ULONG
*pFlags
, ULONG StartingSize
, HGLOBAL
*phGlobal
)
643 ULONG size
= StartingSize
;
645 TRACE("%s, %u, %p.\n", debugstr_user_flags(pFlags
), StartingSize
, phGlobal
);
647 ALIGN_LENGTH(size
, 3);
649 size
+= sizeof(ULONG
);
651 if (LOWORD(*pFlags
) == MSHCTX_INPROC
)
652 size
+= sizeof(HGLOBAL
);
655 size
+= sizeof(ULONG
);
659 size
+= 3 * sizeof(ULONG
);
660 ret
= GlobalSize(*phGlobal
);
668 /******************************************************************************
669 * HGLOBAL_UserMarshal (combase.@)
671 * Marshals an HGLOBAL into a buffer.
674 * pFlags [I] Flags. See notes.
675 * pBuffer [I] Buffer to marshal the clip format into.
676 * phGlobal [I] HGLOBAL to marshal.
679 * The end of the marshaled data in the buffer.
682 * Even though the function is documented to take a pointer to a ULONG in
683 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
684 * the first parameter is a ULONG.
685 * This function is only intended to be called by the RPC runtime.
687 unsigned char * __RPC_USER
HGLOBAL_UserMarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HGLOBAL
*phGlobal
)
689 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags
), pBuffer
, *phGlobal
);
691 ALIGN_POINTER(pBuffer
, 3);
693 if (LOWORD(*pFlags
) == MSHCTX_INPROC
)
695 if (sizeof(*phGlobal
) == 8)
696 *(ULONG
*)pBuffer
= WDT_INPROC64_CALL
;
698 *(ULONG
*)pBuffer
= WDT_INPROC_CALL
;
699 pBuffer
+= sizeof(ULONG
);
700 *(HGLOBAL
*)pBuffer
= *phGlobal
;
701 pBuffer
+= sizeof(HGLOBAL
);
705 *(ULONG
*)pBuffer
= WDT_REMOTE_CALL
;
706 pBuffer
+= sizeof(ULONG
);
707 *(ULONG
*)pBuffer
= HandleToULong(*phGlobal
);
708 pBuffer
+= sizeof(ULONG
);
711 const unsigned char *memory
;
712 SIZE_T size
= GlobalSize(*phGlobal
);
713 *(ULONG
*)pBuffer
= (ULONG
)size
;
714 pBuffer
+= sizeof(ULONG
);
715 *(ULONG
*)pBuffer
= HandleToULong(*phGlobal
);
716 pBuffer
+= sizeof(ULONG
);
717 *(ULONG
*)pBuffer
= (ULONG
)size
;
718 pBuffer
+= sizeof(ULONG
);
720 memory
= GlobalLock(*phGlobal
);
721 memcpy(pBuffer
, memory
, size
);
723 GlobalUnlock(*phGlobal
);
730 /******************************************************************************
731 * HGLOBAL_UserUnmarshal (combase.@)
733 * Unmarshals an HGLOBAL from a buffer.
736 * pFlags [I] Flags. See notes.
737 * pBuffer [I] Buffer to marshal the clip format from.
738 * phGlobal [O] Address that receive the unmarshaled HGLOBAL.
741 * The end of the marshaled data in the buffer.
744 * Even though the function is documented to take a pointer to an ULONG in
745 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
746 * the first parameter is an ULONG.
747 * This function is only intended to be called by the RPC runtime.
749 unsigned char * __RPC_USER
HGLOBAL_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, HGLOBAL
*phGlobal
)
753 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags
), pBuffer
, *phGlobal
);
755 ALIGN_POINTER(pBuffer
, 3);
757 fContext
= *(ULONG
*)pBuffer
;
758 pBuffer
+= sizeof(ULONG
);
760 if (((fContext
== WDT_INPROC_CALL
) && (sizeof(*phGlobal
) < 8)) ||
761 ((fContext
== WDT_INPROC64_CALL
) && (sizeof(*phGlobal
) == 8)))
763 *phGlobal
= *(HGLOBAL
*)pBuffer
;
764 pBuffer
+= sizeof(*phGlobal
);
766 else if (fContext
== WDT_REMOTE_CALL
)
770 handle
= *(ULONG
*)pBuffer
;
771 pBuffer
+= sizeof(ULONG
);
778 size
= *(ULONG
*)pBuffer
;
779 pBuffer
+= sizeof(ULONG
);
780 /* redundancy is bad - it means you have to check consistency like
782 if (*(ULONG
*)pBuffer
!= handle
)
784 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
787 pBuffer
+= sizeof(ULONG
);
788 /* redundancy is bad - it means you have to check consistency like
790 if (*(ULONG
*)pBuffer
!= size
)
792 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
795 pBuffer
+= sizeof(ULONG
);
797 /* FIXME: check size is not too big */
799 *phGlobal
= GlobalAlloc(GMEM_MOVEABLE
, size
);
800 memory
= GlobalLock(*phGlobal
);
801 memcpy(memory
, pBuffer
, size
);
803 GlobalUnlock(*phGlobal
);
809 RaiseException(RPC_S_INVALID_TAG
, 0, 0, NULL
);
814 /******************************************************************************
815 * HGLOBAL_UserFree (combase.@)
817 * Frees an unmarshaled HGLOBAL.
820 * pFlags [I] Flags. See notes.
821 * phGlobal [I] HGLOBAL to free.
824 * The end of the marshaled data in the buffer.
827 * Even though the function is documented to take a pointer to a ULONG in
828 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
829 * which the first parameter is a ULONG.
830 * This function is only intended to be called by the RPC runtime.
832 void __RPC_USER
HGLOBAL_UserFree(ULONG
*pFlags
, HGLOBAL
*phGlobal
)
834 TRACE("%s, &%p.\n", debugstr_user_flags(pFlags
), *phGlobal
);
836 if (LOWORD(*pFlags
) != MSHCTX_INPROC
&& *phGlobal
)
837 GlobalFree(*phGlobal
);
840 /******************************************************************************
841 * HPALETTE_UserFree (combase.@)
843 * Frees an unmarshaled palette.
846 * pFlags [I] Flags. See notes.
847 * phPal [I] Palette to free.
850 * The end of the marshaled data in the buffer.
853 * Even though the function is documented to take a pointer to a ULONG in
854 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
855 * which the first parameter is a ULONG.
856 * This function is only intended to be called by the RPC runtime.
858 void __RPC_USER
HPALETTE_UserFree(ULONG
*pFlags
, HPALETTE
*phPal
)
863 /******************************************************************************
864 * WdtpInterfacePointer_UserSize (combase.@)
866 * Calculates the buffer size required to marshal an interface pointer.
869 * pFlags [I] Flags. See notes.
870 * RealFlags [I] The MSHCTX to use when marshaling the interface.
871 * punk [I] Interface pointer to size.
872 * StartingSize [I] Starting size of the buffer. This value is added on to
873 * the buffer size required for the clip format.
874 * riid [I] ID of interface to size.
877 * The buffer size required to marshal an interface pointer plus the starting size.
880 * Even though the function is documented to take a pointer to a ULONG in
881 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
882 * the first parameter is a ULONG.
884 ULONG __RPC_USER
WdtpInterfacePointer_UserSize(ULONG
*pFlags
, ULONG RealFlags
, ULONG StartingSize
, IUnknown
*punk
, REFIID riid
)
886 DWORD marshal_size
= 0;
889 TRACE("%s, %#x, %u, %p, %s.\n", debugstr_user_flags(pFlags
), RealFlags
, StartingSize
, punk
, debugstr_guid(riid
));
891 hr
= CoGetMarshalSizeMax(&marshal_size
, riid
, punk
, LOWORD(RealFlags
), NULL
, MSHLFLAGS_NORMAL
);
892 if (FAILED(hr
)) return StartingSize
;
894 ALIGN_LENGTH(StartingSize
, 3);
895 StartingSize
+= 2 * sizeof(DWORD
);
896 return StartingSize
+ marshal_size
;
899 /******************************************************************************
900 * WdtpInterfacePointer_UserMarshal (combase.@)
902 * Marshals an interface pointer into a buffer.
905 * pFlags [I] Flags. See notes.
906 * RealFlags [I] The MSHCTX to use when marshaling the interface.
907 * pBuffer [I] Buffer to marshal the clip format into.
908 * punk [I] Interface pointer to marshal.
909 * riid [I] ID of interface to marshal.
912 * The end of the marshaled data in the buffer.
915 * Even though the function is documented to take a pointer to a ULONG in
916 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
917 * the first parameter is a ULONG.
919 unsigned char * WINAPI
WdtpInterfacePointer_UserMarshal(ULONG
*pFlags
, ULONG RealFlags
, unsigned char *pBuffer
, IUnknown
*punk
, REFIID riid
)
921 HGLOBAL h
= GlobalAlloc(GMEM_MOVEABLE
, 0);
926 TRACE("%s, %#x, %p, &%p, %s.\n", debugstr_user_flags(pFlags
), RealFlags
, pBuffer
, punk
, debugstr_guid(riid
));
929 if (CreateStreamOnHGlobal(h
, TRUE
, &stm
) != S_OK
)
935 if (CoMarshalInterface(stm
, riid
, punk
, LOWORD(RealFlags
), NULL
, MSHLFLAGS_NORMAL
) != S_OK
)
937 IStream_Release(stm
);
941 ALIGN_POINTER(pBuffer
, 3);
942 size
= GlobalSize(h
);
944 *(DWORD
*)pBuffer
= size
;
945 pBuffer
+= sizeof(DWORD
);
946 *(DWORD
*)pBuffer
= size
;
947 pBuffer
+= sizeof(DWORD
);
950 memcpy(pBuffer
, ptr
, size
);
953 IStream_Release(stm
);
954 return pBuffer
+ size
;
957 /******************************************************************************
958 * WdtpInterfacePointer_UserUnmarshal (combase.@)
960 * Unmarshals an interface pointer from a buffer.
963 * pFlags [I] Flags. See notes.
964 * pBuffer [I] Buffer to marshal the clip format from.
965 * ppunk [I/O] Address that receives the unmarshaled interface pointer.
966 * riid [I] ID of interface to unmarshal.
969 * The end of the marshaled data in the buffer.
972 * Even though the function is documented to take a pointer to an ULONG in
973 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
974 * the first parameter is an ULONG.
976 unsigned char * WINAPI
WdtpInterfacePointer_UserUnmarshal(ULONG
*pFlags
, unsigned char *pBuffer
, IUnknown
**ppunk
, REFIID riid
)
985 TRACE("%s, %p, %p, %s.\n", debugstr_user_flags(pFlags
), pBuffer
, ppunk
, debugstr_guid(riid
));
987 ALIGN_POINTER(pBuffer
, 3);
989 size
= *(DWORD
*)pBuffer
;
990 pBuffer
+= sizeof(DWORD
);
991 if (size
!= *(DWORD
*)pBuffer
)
992 RaiseException(RPC_X_BAD_STUB_DATA
, 0, 0, NULL
);
994 pBuffer
+= sizeof(DWORD
);
996 /* FIXME: sanity check on size */
998 h
= GlobalAlloc(GMEM_MOVEABLE
, size
);
999 if (!h
) RaiseException(RPC_X_NO_MEMORY
, 0, 0, NULL
);
1001 if (CreateStreamOnHGlobal(h
, TRUE
, &stm
) != S_OK
)
1004 RaiseException(RPC_X_NO_MEMORY
, 0, 0, NULL
);
1007 ptr
= GlobalLock(h
);
1008 memcpy(ptr
, pBuffer
, size
);
1012 hr
= CoUnmarshalInterface(stm
, riid
, (void**)ppunk
);
1013 IStream_Release(stm
);
1015 if (hr
!= S_OK
) RaiseException(hr
, 0, 0, NULL
);
1017 if (orig
) IUnknown_Release(orig
);
1019 return pBuffer
+ size
;
1022 /******************************************************************************
1023 * WdtpInterfacePointer_UserFree (combase.@)
1025 void WINAPI
WdtpInterfacePointer_UserFree(IUnknown
*punk
)
1027 TRACE("%p.\n", punk
);
1028 if (punk
) IUnknown_Release(punk
);