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