59ea8166f0d683408eb7add31b101f016c45e31f
[reactos.git] / dll / win32 / rpcrt4 / ndr_es.c
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 }