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