1 /* 2 * NDR Serialization Services 3 * 4 * Copyright (c) 2007 Robert Shearman for CodeWeavers 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 <stdarg.h> 22 #include <stdio.h> 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "winerror.h" 27 #include "rpc.h" 28 #include "midles.h" 29 #include "ndrtypes.h" 30 31 #include "ndr_misc.h" 32 #include "ndr_stubless.h" 33 34 #include "wine/debug.h" 35 36 WINE_DEFAULT_DEBUG_CHANNEL(ole); 37 38 static inline void init_MIDL_ES_MESSAGE(MIDL_ES_MESSAGE *pEsMsg) 39 { 40 memset(pEsMsg, 0, sizeof(*pEsMsg)); 41 /* even if we are unmarshalling, as we don't want pointers to be pointed 42 * to buffer memory */ 43 pEsMsg->StubMsg.IsClient = TRUE; 44 pEsMsg->MesVersion = 1; 45 } 46 47 /*********************************************************************** 48 * MesEncodeIncrementalHandleCreate [RPCRT4.@] 49 */ 50 RPC_STATUS WINAPI MesEncodeIncrementalHandleCreate( 51 void *UserState, MIDL_ES_ALLOC AllocFn, MIDL_ES_WRITE WriteFn, 52 handle_t *pHandle) 53 { 54 MIDL_ES_MESSAGE *pEsMsg; 55 56 TRACE("(%p, %p, %p, %p)\n", UserState, AllocFn, WriteFn, pHandle); 57 58 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 59 if (!pEsMsg) 60 return RPC_S_OUT_OF_MEMORY; 61 62 init_MIDL_ES_MESSAGE(pEsMsg); 63 64 pEsMsg->Operation = MES_ENCODE; 65 pEsMsg->UserState = UserState; 66 pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; 67 pEsMsg->Alloc = AllocFn; 68 pEsMsg->Write = WriteFn; 69 70 *pHandle = (handle_t)pEsMsg; 71 72 return RPC_S_OK; 73 } 74 75 /*********************************************************************** 76 * MesDecodeIncrementalHandleCreate [RPCRT4.@] 77 */ 78 RPC_STATUS WINAPI MesDecodeIncrementalHandleCreate( 79 void *UserState, MIDL_ES_READ ReadFn, handle_t *pHandle) 80 { 81 MIDL_ES_MESSAGE *pEsMsg; 82 83 TRACE("(%p, %p, %p)\n", UserState, ReadFn, pHandle); 84 85 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 86 if (!pEsMsg) 87 return RPC_S_OUT_OF_MEMORY; 88 89 init_MIDL_ES_MESSAGE(pEsMsg); 90 91 pEsMsg->Operation = MES_DECODE; 92 pEsMsg->UserState = UserState; 93 pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; 94 pEsMsg->Read = ReadFn; 95 96 *pHandle = (handle_t)pEsMsg; 97 98 return RPC_S_OK; 99 } 100 101 /*********************************************************************** 102 * MesIncrementalHandleReset [RPCRT4.@] 103 */ 104 RPC_STATUS WINAPI MesIncrementalHandleReset( 105 handle_t Handle, void *UserState, MIDL_ES_ALLOC AllocFn, 106 MIDL_ES_WRITE WriteFn, MIDL_ES_READ ReadFn, MIDL_ES_CODE Operation) 107 { 108 MIDL_ES_MESSAGE *pEsMsg = Handle; 109 110 TRACE("(%p, %p, %p, %p, %p, %d)\n", Handle, UserState, AllocFn, 111 WriteFn, ReadFn, Operation); 112 113 init_MIDL_ES_MESSAGE(pEsMsg); 114 115 pEsMsg->Operation = Operation; 116 pEsMsg->UserState = UserState; 117 pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; 118 pEsMsg->Alloc = AllocFn; 119 pEsMsg->Write = WriteFn; 120 pEsMsg->Read = ReadFn; 121 122 return RPC_S_OK; 123 } 124 125 /*********************************************************************** 126 * MesBufferHandleReset [RPCRT4.@] 127 */ 128 RPC_STATUS WINAPI MesBufferHandleReset(handle_t Handle, ULONG HandleStyle, 129 MIDL_ES_CODE Operation, char **Buffer, ULONG BufferSize, ULONG *EncodedSize) 130 { 131 MIDL_ES_MESSAGE *pEsMsg = (MIDL_ES_MESSAGE *)Handle; 132 133 TRACE("(%p, %u, %d, %p, %u, %p)\n", Handle, HandleStyle, Operation, Buffer, 134 BufferSize, EncodedSize); 135 136 if (!Handle || !Buffer || !EncodedSize) 137 return RPC_S_INVALID_ARG; 138 139 if (Operation != MES_ENCODE && Operation != MES_DECODE && Operation != MES_ENCODE_NDR64) 140 return RPC_S_INVALID_ARG; 141 142 if (HandleStyle != MES_FIXED_BUFFER_HANDLE && HandleStyle != MES_DYNAMIC_BUFFER_HANDLE) 143 return RPC_S_INVALID_ARG; 144 145 init_MIDL_ES_MESSAGE(pEsMsg); 146 147 pEsMsg->Operation = Operation; 148 pEsMsg->HandleStyle = HandleStyle; 149 if (HandleStyle == MES_FIXED_BUFFER_HANDLE) 150 pEsMsg->Buffer = (unsigned char*)*Buffer; 151 else 152 pEsMsg->pDynBuffer = (unsigned char**)Buffer; 153 pEsMsg->BufferSize = BufferSize; 154 pEsMsg->pEncodedSize = EncodedSize; 155 156 return RPC_S_OK; 157 } 158 159 /*********************************************************************** 160 * MesHandleFree [RPCRT4.@] 161 */ 162 RPC_STATUS WINAPI MesHandleFree(handle_t Handle) 163 { 164 TRACE("(%p)\n", Handle); 165 HeapFree(GetProcessHeap(), 0, Handle); 166 return RPC_S_OK; 167 } 168 169 static RPC_STATUS validate_mes_buffer_pointer(const char *Buffer) 170 { 171 if (!Buffer) 172 return RPC_S_INVALID_ARG; 173 174 if (((ULONG_PTR)Buffer & 7) != 0) 175 return RPC_X_INVALID_BUFFER; 176 177 return RPC_S_OK; 178 } 179 180 /*********************************************************************** 181 * MesEncodeFixedBufferHandleCreate [RPCRT4.@] 182 */ 183 RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate( 184 char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle) 185 { 186 MIDL_ES_MESSAGE *pEsMsg; 187 RPC_STATUS status; 188 189 TRACE("(%p, %d, %p, %p)\n", Buffer, BufferSize, pEncodedSize, pHandle); 190 191 if ((status = validate_mes_buffer_pointer(Buffer))) 192 return status; 193 194 if (!pEncodedSize) 195 return RPC_S_INVALID_ARG; 196 197 /* FIXME: check BufferSize too */ 198 199 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 200 if (!pEsMsg) 201 return RPC_S_OUT_OF_MEMORY; 202 203 init_MIDL_ES_MESSAGE(pEsMsg); 204 205 pEsMsg->Operation = MES_ENCODE; 206 pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE; 207 pEsMsg->Buffer = (unsigned char *)Buffer; 208 pEsMsg->BufferSize = BufferSize; 209 pEsMsg->pEncodedSize = pEncodedSize; 210 211 *pHandle = (handle_t)pEsMsg; 212 213 return RPC_S_OK; 214 } 215 216 /*********************************************************************** 217 * MesEncodeDynBufferHandleCreate [RPCRT4.@] 218 */ 219 RPC_STATUS RPC_ENTRY MesEncodeDynBufferHandleCreate(char **Buffer, 220 ULONG *pEncodedSize, handle_t *pHandle) 221 { 222 MIDL_ES_MESSAGE *pEsMsg; 223 224 TRACE("(%p, %p, %p)\n", Buffer, pEncodedSize, pHandle); 225 226 if (!pEncodedSize) 227 return RPC_S_INVALID_ARG; 228 229 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 230 if (!pEsMsg) 231 return RPC_S_OUT_OF_MEMORY; 232 233 init_MIDL_ES_MESSAGE(pEsMsg); 234 235 pEsMsg->Operation = MES_ENCODE; 236 pEsMsg->HandleStyle = MES_DYNAMIC_BUFFER_HANDLE; 237 pEsMsg->pDynBuffer = (unsigned char **)Buffer; 238 pEsMsg->pEncodedSize = pEncodedSize; 239 240 *pHandle = (handle_t)pEsMsg; 241 242 return RPC_S_OK; 243 } 244 245 /*********************************************************************** 246 * MesDecodeBufferHandleCreate [RPCRT4.@] 247 */ 248 RPC_STATUS RPC_ENTRY MesDecodeBufferHandleCreate( 249 char *Buffer, ULONG BufferSize, handle_t *pHandle) 250 { 251 MIDL_ES_MESSAGE *pEsMsg; 252 RPC_STATUS status; 253 254 TRACE("(%p, %d, %p)\n", Buffer, BufferSize, pHandle); 255 256 if ((status = validate_mes_buffer_pointer(Buffer))) 257 return status; 258 259 pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); 260 if (!pEsMsg) 261 return RPC_S_OUT_OF_MEMORY; 262 263 init_MIDL_ES_MESSAGE(pEsMsg); 264 265 pEsMsg->Operation = MES_DECODE; 266 pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE; 267 pEsMsg->Buffer = (unsigned char *)Buffer; 268 pEsMsg->BufferSize = BufferSize; 269 270 *pHandle = (handle_t)pEsMsg; 271 272 return RPC_S_OK; 273 } 274 275 static void es_data_alloc(MIDL_ES_MESSAGE *pEsMsg, ULONG size) 276 { 277 if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) 278 { 279 unsigned int tmpsize = size; 280 TRACE("%d with incremental handle\n", size); 281 pEsMsg->Alloc(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize); 282 if (tmpsize < size) 283 { 284 ERR("not enough bytes allocated - requested %d, got %d\n", size, tmpsize); 285 RpcRaiseException(RPC_S_OUT_OF_MEMORY); 286 } 287 } 288 else if (pEsMsg->HandleStyle == MES_FIXED_BUFFER_HANDLE) 289 { 290 TRACE("%d with fixed buffer handle\n", size); 291 pEsMsg->StubMsg.Buffer = pEsMsg->Buffer; 292 } 293 pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer; 294 } 295 296 static void es_data_read(MIDL_ES_MESSAGE *pEsMsg, ULONG size) 297 { 298 if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) 299 { 300 unsigned int tmpsize = size; 301 TRACE("%d from incremental handle\n", size); 302 pEsMsg->Read(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize); 303 if (tmpsize < size) 304 { 305 ERR("not enough bytes read - requested %d, got %d\n", size, tmpsize); 306 RpcRaiseException(RPC_S_OUT_OF_MEMORY); 307 } 308 } 309 else 310 { 311 TRACE("%d from fixed or dynamic buffer handle\n", size); 312 /* FIXME: validate BufferSize? */ 313 pEsMsg->StubMsg.Buffer = pEsMsg->Buffer; 314 pEsMsg->Buffer += size; 315 pEsMsg->BufferSize -= size; 316 } 317 pEsMsg->StubMsg.BufferLength = size; 318 pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer; 319 pEsMsg->StubMsg.BufferEnd = pEsMsg->StubMsg.Buffer + size; 320 } 321 322 static void es_data_write(MIDL_ES_MESSAGE *pEsMsg, ULONG size) 323 { 324 if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) 325 { 326 TRACE("%d to incremental handle\n", size); 327 pEsMsg->Write(pEsMsg->UserState, (char *)pEsMsg->StubMsg.BufferStart, size); 328 } 329 else 330 { 331 TRACE("%d to dynamic or fixed buffer handle\n", size); 332 *pEsMsg->pEncodedSize += size; 333 } 334 } 335 336 static inline ULONG mes_proc_header_buffer_size(void) 337 { 338 return 4 + 2*sizeof(RPC_SYNTAX_IDENTIFIER) + 12; 339 } 340 341 static void mes_proc_header_marshal(MIDL_ES_MESSAGE *pEsMsg) 342 { 343 const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation; 344 *(WORD *)pEsMsg->StubMsg.Buffer = 0x0101; 345 pEsMsg->StubMsg.Buffer += 2; 346 *(WORD *)pEsMsg->StubMsg.Buffer = 0xcccc; 347 pEsMsg->StubMsg.Buffer += 2; 348 memcpy(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER)); 349 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 350 memcpy(pEsMsg->StubMsg.Buffer, &pEsMsg->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)); 351 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 352 *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ProcNumber; 353 pEsMsg->StubMsg.Buffer += 4; 354 *(DWORD *)pEsMsg->StubMsg.Buffer = 0x00000001; 355 pEsMsg->StubMsg.Buffer += 4; 356 *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ByteCount; 357 pEsMsg->StubMsg.Buffer += 4; 358 } 359 360 static void mes_proc_header_unmarshal(MIDL_ES_MESSAGE *pEsMsg) 361 { 362 const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation; 363 364 es_data_read(pEsMsg, mes_proc_header_buffer_size()); 365 366 if (*(WORD *)pEsMsg->StubMsg.Buffer != 0x0101) 367 { 368 FIXME("unknown value at Buffer[0] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer); 369 RpcRaiseException(RPC_X_WRONG_ES_VERSION); 370 } 371 pEsMsg->StubMsg.Buffer += 2; 372 if (*(WORD *)pEsMsg->StubMsg.Buffer != 0xcccc) 373 FIXME("unknown value at Buffer[2] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer); 374 pEsMsg->StubMsg.Buffer += 2; 375 if (memcmp(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER))) 376 { 377 const RPC_SYNTAX_IDENTIFIER *AlienTransferSyntax = (const RPC_SYNTAX_IDENTIFIER *)pEsMsg->StubMsg.Buffer; 378 ERR("bad transfer syntax %s {%d.%d}\n", debugstr_guid(&AlienTransferSyntax->SyntaxGUID), 379 AlienTransferSyntax->SyntaxVersion.MajorVersion, 380 AlienTransferSyntax->SyntaxVersion.MinorVersion); 381 RpcRaiseException(RPC_S_UNSUPPORTED_TRANS_SYN); 382 } 383 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 384 memcpy(&pEsMsg->InterfaceId, pEsMsg->StubMsg.Buffer, sizeof(RPC_SYNTAX_IDENTIFIER)); 385 pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); 386 pEsMsg->ProcNumber = *(DWORD *)pEsMsg->StubMsg.Buffer; 387 pEsMsg->StubMsg.Buffer += 4; 388 if (*(DWORD *)pEsMsg->StubMsg.Buffer != 0x00000001) 389 FIXME("unknown value 0x%08x, expected 0x00000001\n", *(DWORD *)pEsMsg->StubMsg.Buffer); 390 pEsMsg->StubMsg.Buffer += 4; 391 pEsMsg->ByteCount = *(DWORD *)pEsMsg->StubMsg.Buffer; 392 pEsMsg->StubMsg.Buffer += 4; 393 if (pEsMsg->ByteCount + mes_proc_header_buffer_size() < pEsMsg->ByteCount) 394 RpcRaiseException(RPC_S_INVALID_BOUND); 395 } 396 397 /*********************************************************************** 398 * NdrMesProcEncodeDecode [RPCRT4.@] 399 */ 400 void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStubDesc, PFORMAT_STRING pFormat, ...) 401 { 402 /* pointer to start of stack where arguments start */ 403 RPC_MESSAGE rpcMsg; 404 MIDL_ES_MESSAGE *pEsMsg = Handle; 405 /* size of stack */ 406 unsigned short stack_size; 407 /* header for procedure string */ 408 const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; 409 const RPC_CLIENT_INTERFACE *client_interface; 410 __ms_va_list args; 411 unsigned int number_of_params; 412 ULONG_PTR arg_buffer[256]; 413 414 TRACE("Handle %p, pStubDesc %p, pFormat %p, ...\n", Handle, pStubDesc, pFormat); 415 416 /* Later NDR language versions probably won't be backwards compatible */ 417 if (pStubDesc->Version > 0x50002) 418 { 419 FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); 420 RpcRaiseException(RPC_X_WRONG_STUB_VERSION); 421 } 422 423 client_interface = pStubDesc->RpcInterfaceInformation; 424 pEsMsg->InterfaceId = client_interface->InterfaceId; 425 426 if (pProcHeader->Oi_flags & Oi_HAS_RPCFLAGS) 427 { 428 const NDR_PROC_HEADER_RPC *header_rpc = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; 429 stack_size = header_rpc->stack_size; 430 pEsMsg->ProcNumber = header_rpc->proc_num; 431 pFormat += sizeof(NDR_PROC_HEADER_RPC); 432 } 433 else 434 { 435 stack_size = pProcHeader->stack_size; 436 pEsMsg->ProcNumber = pProcHeader->proc_num; 437 pFormat += sizeof(NDR_PROC_HEADER); 438 } 439 440 if (pProcHeader->handle_type == 0) 441 { 442 switch (*pFormat) /* handle_type */ 443 { 444 case FC_BIND_PRIMITIVE: /* explicit primitive */ 445 pFormat += sizeof(NDR_EHD_PRIMITIVE); 446 break; 447 case FC_BIND_GENERIC: /* explicit generic */ 448 pFormat += sizeof(NDR_EHD_GENERIC); 449 break; 450 case FC_BIND_CONTEXT: /* explicit context */ 451 pFormat += sizeof(NDR_EHD_CONTEXT); 452 break; 453 default: 454 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); 455 RpcRaiseException(RPC_X_BAD_STUB_DATA); 456 } 457 } 458 459 TRACE("stack size: 0x%x\n", stack_size); 460 TRACE("proc num: %d\n", pEsMsg->ProcNumber); 461 462 memset(&rpcMsg, 0, sizeof(rpcMsg)); 463 pEsMsg->StubMsg.RpcMsg = &rpcMsg; 464 pEsMsg->StubMsg.StubDesc = pStubDesc; 465 pEsMsg->StubMsg.pfnAllocate = pStubDesc->pfnAllocate; 466 pEsMsg->StubMsg.pfnFree = pStubDesc->pfnFree; 467 468 /* create the full pointer translation tables, if requested */ 469 if (pProcHeader->Oi_flags & Oi_FULL_PTR_USED) 470 pEsMsg->StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); 471 472 TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); 473 TRACE("stubdesc version = 0x%x\n", pStubDesc->Version); 474 TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); 475 476 /* needed for conformance of top-level objects */ 477 __ms_va_start( args, pFormat ); 478 pEsMsg->StubMsg.StackTop = va_arg( args, unsigned char * ); 479 __ms_va_end( args ); 480 481 pFormat = convert_old_args( &pEsMsg->StubMsg, pFormat, stack_size, FALSE, 482 arg_buffer, sizeof(arg_buffer), &number_of_params ); 483 484 switch (pEsMsg->Operation) 485 { 486 case MES_ENCODE: 487 pEsMsg->StubMsg.BufferLength = mes_proc_header_buffer_size(); 488 489 client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_CALCSIZE, NULL, number_of_params, NULL ); 490 491 pEsMsg->ByteCount = pEsMsg->StubMsg.BufferLength - mes_proc_header_buffer_size(); 492 es_data_alloc(pEsMsg, pEsMsg->StubMsg.BufferLength); 493 494 mes_proc_header_marshal(pEsMsg); 495 496 client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_MARSHAL, NULL, number_of_params, NULL ); 497 498 es_data_write(pEsMsg, pEsMsg->ByteCount); 499 break; 500 case MES_DECODE: 501 mes_proc_header_unmarshal(pEsMsg); 502 503 es_data_read(pEsMsg, pEsMsg->ByteCount); 504 505 client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_UNMARSHAL, NULL, number_of_params, NULL ); 506 break; 507 default: 508 RpcRaiseException(RPC_S_INTERNAL_ERROR); 509 return; 510 } 511 /* free the full pointer translation tables */ 512 if (pProcHeader->Oi_flags & Oi_FULL_PTR_USED) 513 NdrFullPointerXlatFree(pEsMsg->StubMsg.FullPtrXlatTables); 514 } 515 516 void RPC_ENTRY NdrMesTypeDecode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, 517 const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject) 518 { 519 FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); 520 } 521 522 void RPC_ENTRY NdrMesTypeEncode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, 523 const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, const void *pObject) 524 { 525 FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); 526 } 527 528 void RPC_ENTRY NdrMesTypeFree2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, 529 const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject) 530 { 531 FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); 532 } 533