ReactOS 0.4.16-dev-2320-ge1853c6
usrmarshal.c
Go to the documentation of this file.
1/*
2 * Marshaling Routines
3 *
4 * Copyright 2005 Robert Shearman
5 * Copyright 2009 Huw Davies
6 *
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.
11 *
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.
16 *
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
20 */
21
22#define COBJMACROS
23#include "ole2.h"
24
25#include "wine/debug.h"
26
28
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)
33
34static const char* debugstr_user_flags(ULONG *pFlags)
35{
36 char buf[12];
37 const char* loword;
38 switch (LOWORD(*pFlags))
39 {
40 case MSHCTX_LOCAL:
41 loword = "MSHCTX_LOCAL";
42 break;
43 case MSHCTX_NOSHAREDMEM:
44 loword = "MSHCTX_NOSHAREDMEM";
45 break;
46 case MSHCTX_DIFFERENTMACHINE:
47 loword = "MSHCTX_DIFFERENTMACHINE";
48 break;
49 case MSHCTX_INPROC:
50 loword = "MSHCTX_INPROC";
51 break;
52 default:
53 sprintf(buf, "%d", LOWORD(*pFlags));
54 loword=buf;
55 }
56
58 return wine_dbg_sprintf("MAKELONG(%s, NDR_LOCAL_DATA_REPRESENTATION)", loword);
59 else
60 return wine_dbg_sprintf("MAKELONG(%s, 0x%04x)", loword, HIWORD(*pFlags));
61}
62
63static ULONG handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle)
64{
65 if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
66 {
67 ERR("can't remote a local handle\n");
69 return StartingSize;
70 }
71
72 ALIGN_LENGTH(StartingSize, 3);
73 return StartingSize + sizeof(RemotableHandle);
74}
75
76static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
77{
78 RemotableHandle *remhandle;
79 if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
80 {
81 ERR("can't remote a local handle\n");
83 return pBuffer;
84 }
85
87 remhandle = (RemotableHandle *)pBuffer;
88 remhandle->fContext = WDT_INPROC_CALL;
89 remhandle->u.hInproc = (LONG_PTR)*handle;
90 return pBuffer + sizeof(RemotableHandle);
91}
92
93static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
94{
95 RemotableHandle *remhandle;
96
98 remhandle = (RemotableHandle *)pBuffer;
99 if (remhandle->fContext != WDT_INPROC_CALL)
101 *handle = (HANDLE)(LONG_PTR)remhandle->u.hInproc;
102 return pBuffer + sizeof(RemotableHandle);
103}
104
105static void handle_UserFree(ULONG *pFlags, HANDLE *handle)
106{
107 /* nothing to do */
108}
109
110#define IMPL_WIREM_HANDLE(type) \
111 ULONG __RPC_USER type##_UserSize(ULONG *pFlags, ULONG StartingSize, type *handle) \
112 { \
113 TRACE("%s, %lu, %p.\n", debugstr_user_flags(pFlags), StartingSize, handle); \
114 return handle_UserSize(pFlags, StartingSize, (HANDLE *)handle); \
115 } \
116 \
117 unsigned char * __RPC_USER type##_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
118 { \
119 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags), pBuffer, *handle); \
120 return handle_UserMarshal(pFlags, pBuffer, (HANDLE *)handle); \
121 } \
122 \
123 unsigned char * __RPC_USER type##_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, type *handle) \
124 { \
125 TRACE("%s, %p, %p.\n", debugstr_user_flags(pFlags), pBuffer, handle); \
126 return handle_UserUnmarshal(pFlags, pBuffer, (HANDLE *)handle); \
127 } \
128 \
129 void __RPC_USER type##_UserFree(ULONG *pFlags, type *handle) \
130 { \
131 TRACE("%s, &%p.\n", debugstr_user_flags(pFlags), *handle); \
132 handle_UserFree(pFlags, (HANDLE *)handle); \
133 }
134
135IMPL_WIREM_HANDLE(HACCEL)
136IMPL_WIREM_HANDLE(HBRUSH)
141
142/******************************************************************************
143 * CLIPFORMAT_UserSize (combase.@)
144 *
145 * Calculates the buffer size required to marshal a clip format.
146 *
147 * PARAMS
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.
152 *
153 * RETURNS
154 * The buffer size required to marshal a clip format plus the starting size.
155 *
156 * NOTES
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.
161 */
163{
164 TRACE("%s, %lu, %p.\n", debugstr_user_flags(pFlags), size, pCF);
165
166 ALIGN_LENGTH(size, 3);
167
168 size += 8;
169
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))
173 {
174 WCHAR format[255];
175 INT ret;
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 */
181 if (!ret)
183 size += (ret + 1) * sizeof(WCHAR);
184 }
185 return size;
186}
187
188/******************************************************************************
189 * CLIPFORMAT_UserMarshal (combase.@)
190 *
191 * Marshals a clip format into a buffer.
192 *
193 * PARAMS
194 * pFlags [I] Flags. See notes.
195 * pBuffer [I] Buffer to marshal the clip format into.
196 * pCF [I] Clip format to marshal.
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 */
207unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
208{
209 TRACE("%s, %p, &0x%04x.\n", debugstr_user_flags(pFlags), pBuffer, *pCF);
210
212
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))
216 {
217 WCHAR format[255];
218 UINT len;
219
220 *(DWORD *)pBuffer = WDT_REMOTE_CALL;
221 pBuffer += 4;
222 *(DWORD *)pBuffer = *pCF;
223 pBuffer += 4;
224
226 if (!len)
228 len += 1;
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);
238 }
239 else
240 {
241 *(DWORD *)pBuffer = WDT_INPROC_CALL;
242 pBuffer += 4;
243 *(DWORD *)pBuffer = *pCF;
244 pBuffer += 4;
245 }
246
247 return pBuffer;
248}
249
250/******************************************************************************
251 * CLIPFORMAT_UserUnmarshal (combase.@)
252 *
253 * Unmarshals a clip format from a buffer.
254 *
255 * PARAMS
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.
259 *
260 * RETURNS
261 * The end of the marshaled data in the buffer.
262 *
263 * NOTES
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.
268 */
269unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
270{
271 LONG fContext;
272
273 TRACE("%s, %p, %p.\n", debugstr_user_flags(pFlags), pBuffer, pCF);
274
276
277 fContext = *(DWORD *)pBuffer;
278 pBuffer += 4;
279
280 if (fContext == WDT_INPROC_CALL)
281 {
282 *pCF = *(CLIPFORMAT *)pBuffer;
283 pBuffer += 4;
284 }
285 else if (fContext == WDT_REMOTE_CALL)
286 {
287 CLIPFORMAT cf;
288 UINT len;
289
290 /* pointer ID for registered clip format string */
291 if (*(DWORD *)pBuffer == 0)
293 pBuffer += 4;
294
295 len = *(UINT *)pBuffer;
296 pBuffer += sizeof(UINT);
297 if (*(UINT *)pBuffer != 0)
299 pBuffer += sizeof(UINT);
300 if (*(UINT *)pBuffer != len)
302 pBuffer += sizeof(UINT);
303 if (((WCHAR *)pBuffer)[len - 1] != '\0')
305 TRACE("unmarshaling clip format %s\n", debugstr_w((LPCWSTR)pBuffer));
307 pBuffer += len * sizeof(WCHAR);
308 if (!cf)
310 *pCF = cf;
311 }
312 else
313 /* code not really appropriate, but nearest I can find */
315 return pBuffer;
316}
317
318/******************************************************************************
319 * CLIPFORMAT_UserFree (combase.@)
320 *
321 * Frees an unmarshaled clip format.
322 *
323 * PARAMS
324 * pFlags [I] Flags. See notes.
325 * pCF [I] Clip format to free.
326 *
327 * RETURNS
328 * The end of the marshaled data in the buffer.
329 *
330 * NOTES
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.
335 */
336void __RPC_USER CLIPFORMAT_UserFree(ULONG *pFlags, CLIPFORMAT *pCF)
337{
338 /* there is no inverse of the RegisterClipboardFormat function,
339 * so nothing to do */
340}
341
342/******************************************************************************
343 * HBITMAP_UserSize (combase.@)
344 *
345 * Calculates the buffer size required to marshal a bitmap.
346 *
347 * PARAMS
348 * pFlags [I] Flags. See notes.
349 * StartingSize [I] Starting size of the buffer. This value is added on to
350 * the buffer size required for the clip format.
351 * phBmp [I] Bitmap to size.
352 *
353 * RETURNS
354 * The buffer size required to marshal an bitmap plus the starting size.
355 *
356 * NOTES
357 * Even though the function is documented to take a pointer to a ULONG in
358 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of which
359 * the first parameter is a ULONG.
360 * This function is only intended to be called by the RPC runtime.
361 */
363{
364 TRACE("%s, %lu, %p.\n", debugstr_user_flags(flags), size, *bmp);
365
366 ALIGN_LENGTH(size, 3);
367
368 size += sizeof(ULONG);
369 if (LOWORD(*flags) == MSHCTX_INPROC)
370 size += sizeof(ULONG);
371 else
372 {
373 size += sizeof(ULONG);
374
375 if (*bmp)
376 {
377 size += sizeof(ULONG);
378 size += FIELD_OFFSET(userBITMAP, cbSize);
379 size += GetBitmapBits(*bmp, 0, NULL);
380 }
381 }
382
383 return size;
384}
385
386/******************************************************************************
387* HBITMAP_UserMarshal (combase.@)
388*
389* Marshals a bitmap into a buffer.
390*
391* PARAMS
392* pFlags [I] Flags. See notes.
393* pBuffer [I] Buffer to marshal the clip format into.
394* phBmp [I] Bitmap to marshal.
395*
396* RETURNS
397* The end of the marshaled data in the buffer.
398*
399* NOTES
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.
404*/
405unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
406{
407 TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, *bmp);
408
410
411 if (LOWORD(*flags) == MSHCTX_INPROC)
412 {
413 *(ULONG *)buffer = WDT_INPROC_CALL;
414 buffer += sizeof(ULONG);
415 *(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp;
416 buffer += sizeof(ULONG);
417 }
418 else
419 {
420 *(ULONG *)buffer = WDT_REMOTE_CALL;
421 buffer += sizeof(ULONG);
422 *(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp;
423 buffer += sizeof(ULONG);
424
425 if (*bmp)
426 {
427 static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
429 ULONG bitmap_size;
430
431 bitmap_size = GetBitmapBits(*bmp, 0, NULL);
432 *(ULONG *)buffer = bitmap_size;
433 buffer += sizeof(ULONG);
434
435 GetObjectW(*bmp, sizeof(BITMAP), &bitmap);
436 memcpy(buffer, &bitmap, header_size);
437 buffer += header_size;
438
439 GetBitmapBits(*bmp, bitmap_size, buffer);
440 buffer += bitmap_size;
441 }
442 }
443 return buffer;
444}
445
446/******************************************************************************
447 * HBITMAP_UserUnmarshal (combase.@)
448 *
449 * Unmarshals a bitmap from a buffer.
450 *
451 * PARAMS
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.
455 *
456 * RETURNS
457 * The end of the marshaled data in the buffer.
458 *
459 * NOTES
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.
464 */
465unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
466{
468
469 TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, bmp);
470
472
473 context = *(ULONG *)buffer;
474 buffer += sizeof(ULONG);
475
476 if (context == WDT_INPROC_CALL)
477 {
478 *bmp = *(HBITMAP *)buffer;
479 buffer += sizeof(*bmp);
480 }
481 else if (context == WDT_REMOTE_CALL)
482 {
483 ULONG handle = *(ULONG *)buffer;
484 buffer += sizeof(ULONG);
485
486 if (handle)
487 {
488 static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
490 ULONG bitmap_size;
491 unsigned char *bits;
492
493 bitmap_size = *(ULONG *)buffer;
494 buffer += sizeof(ULONG);
495 bits = malloc(bitmap_size);
496
497 memcpy(&bitmap, buffer, header_size);
498 buffer += header_size;
499
500 memcpy(bits, buffer, bitmap_size);
501 buffer += bitmap_size;
502
503 bitmap.bmBits = bits;
505
506 free(bits);
507 }
508 else
509 *bmp = NULL;
510 }
511 else
513
514 return buffer;
515}
516
517/******************************************************************************
518 * HBITMAP_UserFree (combase.@)
519 *
520 * Frees an unmarshaled bitmap.
521 *
522 * PARAMS
523 * pFlags [I] Flags. See notes.
524 * phBmp [I] Bitmap to free.
525 *
526 * RETURNS
527 * The end of the marshaled data in the buffer.
528 *
529 * NOTES
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.
534 */
536{
537 TRACE("(%s, %p)\n", debugstr_user_flags(flags), *bmp);
538
539 if (LOWORD(*flags) != MSHCTX_INPROC)
541}
542
543/******************************************************************************
544 * HPALETTE_UserSize (combase.@)
545 *
546 * Calculates the buffer size required to marshal a palette.
547 *
548 * PARAMS
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.
553 *
554 * RETURNS
555 * The buffer size required to marshal a palette plus the starting size.
556 *
557 * NOTES
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.
562 */
563ULONG __RPC_USER HPALETTE_UserSize(ULONG *pFlags, ULONG StartingSize, HPALETTE *phPal)
564{
565 FIXME(":stub\n");
566 return StartingSize;
567}
568
569/******************************************************************************
570 * HPALETTE_UserMarshal (combase.@)
571 *
572 * Marshals a palette into a buffer.
573 *
574 * PARAMS
575 * pFlags [I] Flags. See notes.
576 * pBuffer [I] Buffer to marshal the clip format into.
577 * phPal [I] Palette to marshal.
578 *
579 * RETURNS
580 * The end of the marshaled data in the buffer.
581 *
582 * NOTES
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.
587 */
588unsigned char * __RPC_USER HPALETTE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
589{
590 FIXME(":stub\n");
591 return pBuffer;
592}
593
594/******************************************************************************
595 * HPALETTE_UserUnmarshal (combase.@)
596 *
597 * Unmarshals a palette from a buffer.
598 *
599 * PARAMS
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.
603 *
604 * RETURNS
605 * The end of the marshaled data in the buffer.
606 *
607 * NOTES
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.
612 */
613unsigned char * __RPC_USER HPALETTE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
614{
615 FIXME(":stub\n");
616 return pBuffer;
617}
618
619/******************************************************************************
620 * HGLOBAL_UserSize (combase.@)
621 *
622 * Calculates the buffer size required to marshal an HGLOBAL.
623 *
624 * PARAMS
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.
629 *
630 * RETURNS
631 * The buffer size required to marshal an HGLOBAL plus the starting size.
632 *
633 * NOTES
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.
638 */
639ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal)
640{
641 ULONG size = StartingSize;
642
643 TRACE("%s, %lu, %p.\n", debugstr_user_flags(pFlags), StartingSize, phGlobal);
644
645 ALIGN_LENGTH(size, 3);
646
647 size += sizeof(ULONG);
648
649 if (LOWORD(*pFlags) == MSHCTX_INPROC)
650 size += sizeof(HGLOBAL);
651 else
652 {
653 size += sizeof(ULONG);
654 if (*phGlobal)
655 {
656 SIZE_T ret;
657 size += 3 * sizeof(ULONG);
658 ret = GlobalSize(*phGlobal);
659 size += (ULONG)ret;
660 }
661 }
662
663 return size;
664}
665
666/******************************************************************************
667 * HGLOBAL_UserMarshal (combase.@)
668 *
669 * Marshals an HGLOBAL into a buffer.
670 *
671 * PARAMS
672 * pFlags [I] Flags. See notes.
673 * pBuffer [I] Buffer to marshal the clip format into.
674 * phGlobal [I] HGLOBAL to marshal.
675 *
676 * RETURNS
677 * The end of the marshaled data in the buffer.
678 *
679 * NOTES
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.
684 */
685unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
686{
687 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal);
688
690
691 if (LOWORD(*pFlags) == MSHCTX_INPROC)
692 {
693 if (sizeof(*phGlobal) == 8)
694 *(ULONG *)pBuffer = WDT_INPROC64_CALL;
695 else
696 *(ULONG *)pBuffer = WDT_INPROC_CALL;
697 pBuffer += sizeof(ULONG);
698 *(HGLOBAL *)pBuffer = *phGlobal;
699 pBuffer += sizeof(HGLOBAL);
700 }
701 else
702 {
703 *(ULONG *)pBuffer = WDT_REMOTE_CALL;
704 pBuffer += sizeof(ULONG);
705 *(ULONG *)pBuffer = HandleToULong(*phGlobal);
706 pBuffer += sizeof(ULONG);
707 if (*phGlobal)
708 {
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);
717
718 memory = GlobalLock(*phGlobal);
720 pBuffer += size;
721 GlobalUnlock(*phGlobal);
722 }
723 }
724
725 return pBuffer;
726}
727
728/******************************************************************************
729 * HGLOBAL_UserUnmarshal (combase.@)
730 *
731 * Unmarshals an HGLOBAL from a buffer.
732 *
733 * PARAMS
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.
737 *
738 * RETURNS
739 * The end of the marshaled data in the buffer.
740 *
741 * NOTES
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.
746 */
747unsigned char * __RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
748{
749 ULONG fContext;
750
751 TRACE("%s, %p, &%p.\n", debugstr_user_flags(pFlags), pBuffer, *phGlobal);
752
754
755 fContext = *(ULONG *)pBuffer;
756 pBuffer += sizeof(ULONG);
757
758 if (((fContext == WDT_INPROC_CALL) && (sizeof(*phGlobal) < 8)) ||
759 ((fContext == WDT_INPROC64_CALL) && (sizeof(*phGlobal) == 8)))
760 {
761 *phGlobal = *(HGLOBAL *)pBuffer;
762 pBuffer += sizeof(*phGlobal);
763 }
764 else if (fContext == WDT_REMOTE_CALL)
765 {
767
768 handle = *(ULONG *)pBuffer;
769 pBuffer += sizeof(ULONG);
770
771 if (handle)
772 {
773 ULONG size;
774 void *memory;
775
776 size = *(ULONG *)pBuffer;
777 pBuffer += sizeof(ULONG);
778 /* redundancy is bad - it means you have to check consistency like
779 * this: */
780 if (*(ULONG *)pBuffer != handle)
781 {
783 return pBuffer;
784 }
785 pBuffer += sizeof(ULONG);
786 /* redundancy is bad - it means you have to check consistency like
787 * this: */
788 if (*(ULONG *)pBuffer != size)
789 {
791 return pBuffer;
792 }
793 pBuffer += sizeof(ULONG);
794
795 /* FIXME: check size is not too big */
796
797 *phGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
798 memory = GlobalLock(*phGlobal);
800 pBuffer += size;
801 GlobalUnlock(*phGlobal);
802 }
803 else
804 *phGlobal = NULL;
805 }
806 else
808
809 return pBuffer;
810}
811
812/******************************************************************************
813 * HGLOBAL_UserFree (combase.@)
814 *
815 * Frees an unmarshaled HGLOBAL.
816 *
817 * PARAMS
818 * pFlags [I] Flags. See notes.
819 * phGlobal [I] HGLOBAL to free.
820 *
821 * RETURNS
822 * The end of the marshaled data in the buffer.
823 *
824 * NOTES
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.
829 */
830void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
831{
832 TRACE("%s, &%p.\n", debugstr_user_flags(pFlags), *phGlobal);
833
834 if (LOWORD(*pFlags) != MSHCTX_INPROC && *phGlobal)
835 GlobalFree(*phGlobal);
836}
837
838/******************************************************************************
839 * HPALETTE_UserFree (combase.@)
840 *
841 * Frees an unmarshaled palette.
842 *
843 * PARAMS
844 * pFlags [I] Flags. See notes.
845 * phPal [I] Palette to free.
846 *
847 * RETURNS
848 * The end of the marshaled data in the buffer.
849 *
850 * NOTES
851 * Even though the function is documented to take a pointer to a ULONG in
852 * pFlags, it actually takes a pointer to a USER_MARSHAL_CB structure, of
853 * which the first parameter is a ULONG.
854 * This function is only intended to be called by the RPC runtime.
855 */
856void __RPC_USER HPALETTE_UserFree(ULONG *pFlags, HPALETTE *phPal)
857{
858 FIXME(":stub\n");
859}
860
861/******************************************************************************
862 * WdtpInterfacePointer_UserSize (combase.@)
863 *
864 * Calculates the buffer size required to marshal an interface pointer.
865 *
866 * PARAMS
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.
873 *
874 * RETURNS
875 * The buffer size required to marshal an interface pointer plus the starting size.
876 *
877 * NOTES
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.
881 */
883{
884 DWORD marshal_size = 0;
885 HRESULT hr;
886
887 TRACE("%s, %#lx, %lu, %p, %s.\n", debugstr_user_flags(pFlags), RealFlags, StartingSize, punk, debugstr_guid(riid));
888
889 hr = CoGetMarshalSizeMax(&marshal_size, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL);
890 if (FAILED(hr)) return StartingSize;
891
892 ALIGN_LENGTH(StartingSize, 3);
893 StartingSize += 2 * sizeof(DWORD);
894 return StartingSize + marshal_size;
895}
896
897/******************************************************************************
898 * WdtpInterfacePointer_UserMarshal (combase.@)
899 *
900 * Marshals an interface pointer into a buffer.
901 *
902 * PARAMS
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.
908 *
909 * RETURNS
910 * The end of the marshaled data in the buffer.
911 *
912 * NOTES
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.
916 */
917unsigned char * WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
918{
920 IStream *stm;
921 DWORD size;
922 void *ptr;
923
924 TRACE("%s, %#lx, %p, &%p, %s.\n", debugstr_user_flags(pFlags), RealFlags, pBuffer, punk, debugstr_guid(riid));
925
926 if (!h) return NULL;
927 if (CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
928 {
929 GlobalFree(h);
930 return NULL;
931 }
932
933 if (CoMarshalInterface(stm, riid, punk, LOWORD(RealFlags), NULL, MSHLFLAGS_NORMAL) != S_OK)
934 {
935 IStream_Release(stm);
936 return pBuffer;
937 }
938
940 size = GlobalSize(h);
941
942 *(DWORD *)pBuffer = size;
943 pBuffer += sizeof(DWORD);
944 *(DWORD *)pBuffer = size;
945 pBuffer += sizeof(DWORD);
946
947 ptr = GlobalLock(h);
950
951 IStream_Release(stm);
952 return pBuffer + size;
953}
954
955/******************************************************************************
956 * WdtpInterfacePointer_UserUnmarshal (combase.@)
957 *
958 * Unmarshals an interface pointer from a buffer.
959 *
960 * PARAMS
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.
965 *
966 * RETURNS
967 * The end of the marshaled data in the buffer.
968 *
969 * NOTES
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.
973 */
974unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
975{
976 HRESULT hr;
977 HGLOBAL h;
978 IStream *stm;
979 DWORD size;
980 void *ptr;
981 IUnknown *orig;
982
983 TRACE("%s, %p, %p, %s.\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
984
986
987 size = *(DWORD *)pBuffer;
988 pBuffer += sizeof(DWORD);
989 if (size != *(DWORD *)pBuffer)
991
992 pBuffer += sizeof(DWORD);
993
994 /* FIXME: sanity check on size */
995
997 if (!h) RaiseException(RPC_X_NO_MEMORY, 0, 0, NULL);
998
999 if (CreateStreamOnHGlobal(h, TRUE, &stm) != S_OK)
1000 {
1001 GlobalFree(h);
1003 }
1004
1005 ptr = GlobalLock(h);
1007 GlobalUnlock(h);
1008
1009 orig = *ppunk;
1010 hr = CoUnmarshalInterface(stm, riid, (void**)ppunk);
1011 IStream_Release(stm);
1012
1013 if (hr != S_OK) RaiseException(hr, 0, 0, NULL);
1014
1015 if (orig) IUnknown_Release(orig);
1016
1017 return pBuffer + size;
1018}
1019
1020/******************************************************************************
1021 * WdtpInterfacePointer_UserFree (combase.@)
1022 */
1024{
1025 TRACE("%p.\n", punk);
1026 if (punk) IUnknown_Release(punk);
1027}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define HandleToULong(h)
Definition: basetsd.h:89
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
HRESULT WINAPI CoMarshalInterface(IStream *stream, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:483
HRESULT WINAPI CoUnmarshalInterface(IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:793
HRESULT WINAPI CoGetMarshalSizeMax(ULONG *size, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:440
#define ALIGN_LENGTH(_Len, _Align)
Definition: usrmarshal.c:31
void __RPC_USER HBITMAP_UserFree(ULONG *flags, HBITMAP *bmp)
Definition: usrmarshal.c:535
unsigned char *__RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
Definition: usrmarshal.c:207
static ULONG handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle)
Definition: usrmarshal.c:63
#define ALIGN_POINTER(_Ptr, _Align)
Definition: usrmarshal.c:32
#define IMPL_WIREM_HANDLE(type)
Definition: usrmarshal.c:110
void WINAPI WdtpInterfacePointer_UserFree(IUnknown *punk)
Definition: usrmarshal.c:1023
void __RPC_USER HPALETTE_UserFree(ULONG *pFlags, HPALETTE *phPal)
Definition: usrmarshal.c:856
unsigned char *WINAPI WdtpInterfacePointer_UserMarshal(ULONG *pFlags, ULONG RealFlags, unsigned char *pBuffer, IUnknown *punk, REFIID riid)
Definition: usrmarshal.c:917
ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF)
Definition: usrmarshal.c:162
static const char * debugstr_user_flags(ULONG *pFlags)
Definition: usrmarshal.c:34
ULONG __RPC_USER HBITMAP_UserSize(ULONG *flags, ULONG size, HBITMAP *bmp)
Definition: usrmarshal.c:362
static void handle_UserFree(ULONG *pFlags, HANDLE *handle)
Definition: usrmarshal.c:105
unsigned char *__RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
Definition: usrmarshal.c:685
unsigned char *__RPC_USER HPALETTE_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
Definition: usrmarshal.c:588
ULONG __RPC_USER HPALETTE_UserSize(ULONG *pFlags, ULONG StartingSize, HPALETTE *phPal)
Definition: usrmarshal.c:563
unsigned char *__RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
Definition: usrmarshal.c:405
static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
Definition: usrmarshal.c:93
ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *phGlobal)
Definition: usrmarshal.c:639
unsigned char *__RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
Definition: usrmarshal.c:465
static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
Definition: usrmarshal.c:76
void __RPC_USER CLIPFORMAT_UserFree(ULONG *pFlags, CLIPFORMAT *pCF)
Definition: usrmarshal.c:336
unsigned char *WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, IUnknown **ppunk, REFIID riid)
Definition: usrmarshal.c:974
unsigned char *__RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, CLIPFORMAT *pCF)
Definition: usrmarshal.c:269
unsigned char *__RPC_USER HPALETTE_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HPALETTE *phPal)
Definition: usrmarshal.c:613
unsigned char *__RPC_USER HGLOBAL_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HGLOBAL *phGlobal)
Definition: usrmarshal.c:747
void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
Definition: usrmarshal.c:830
ULONG __RPC_USER WdtpInterfacePointer_UserSize(ULONG *pFlags, ULONG RealFlags, ULONG StartingSize, IUnknown *punk, REFIID riid)
Definition: usrmarshal.c:882
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
return ret
Definition: mutex.c:146
#define ULONG_PTR
Definition: config.h:101
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
REFIID riid
Definition: atlbase.h:39
#define bits
Definition: infblock.c:15
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
BITMAP bmp
Definition: alphablend.c:62
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static char memory[1024 *256]
Definition: process.c:122
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
#define HGLOBAL
Definition: ole.h:15
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define REFIID
Definition: guiddef.h:118
_In_opt_ IUnknown * punk
Definition: shlwapi.h:158
PVOID pBuffer
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:68
#define RPC_X_NO_MEMORY
Definition: rpcnterr.h:35
#define __RPC_USER
Definition: rpc.h:61
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: uimain.c:89
Definition: http.c:7252
Definition: format.c:58
#define LONG_PTR
Definition: treelist.c:79
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define GMEM_MOVEABLE
Definition: winbase.h:318
#define WINAPI
Definition: msvc.h:6
#define RPC_S_INVALID_BOUND
Definition: winerror.h:1400
#define RPC_S_INVALID_TAG
Definition: winerror.h:1399
#define RPC_X_BAD_STUB_DATA
Definition: winerror.h:1447
#define DV_E_CLIPFORMAT
Definition: winerror.h:3750
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmapIndirect(_In_ const BITMAP *pbm)
LONG WINAPI GetBitmapBits(_In_ HBITMAP hbit, _In_ LONG cb, _Out_writes_bytes_(cb) LPVOID lpvBits)
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
int WINAPI GetClipboardFormatNameW(_In_ UINT format, _Out_writes_(cchMaxCount) LPWSTR lpszFormatName, _In_ int cchMaxCount)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180