2 * NDR Serialization Services
4 * Copyright (c) 2007 Robert Shearman for CodeWeavers
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.
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.
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
32 #include "ndr_stubless.h"
34 #include "wine/debug.h"
35 #include "wine/rpcfc.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
39 static inline void init_MIDL_ES_MESSAGE(MIDL_ES_MESSAGE
*pEsMsg
)
41 memset(pEsMsg
, 0, sizeof(*pEsMsg
));
42 /* even if we are unmarshalling, as we don't want pointers to be pointed
44 pEsMsg
->StubMsg
.IsClient
= TRUE
;
45 pEsMsg
->MesVersion
= 1;
48 /***********************************************************************
49 * MesEncodeIncrementalHandleCreate [RPCRT4.@]
51 RPC_STATUS WINAPI
MesEncodeIncrementalHandleCreate(
52 void *UserState
, MIDL_ES_ALLOC AllocFn
, MIDL_ES_WRITE WriteFn
,
55 MIDL_ES_MESSAGE
*pEsMsg
;
57 TRACE("(%p, %p, %p, %p)\n", UserState
, AllocFn
, WriteFn
, pHandle
);
59 pEsMsg
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg
));
61 return RPC_S_OUT_OF_MEMORY
;
63 init_MIDL_ES_MESSAGE(pEsMsg
);
65 pEsMsg
->Operation
= MES_ENCODE
;
66 pEsMsg
->UserState
= UserState
;
67 pEsMsg
->HandleStyle
= MES_INCREMENTAL_HANDLE
;
68 pEsMsg
->Alloc
= AllocFn
;
69 pEsMsg
->Write
= WriteFn
;
71 *pHandle
= (handle_t
)pEsMsg
;
76 /***********************************************************************
77 * MesDecodeIncrementalHandleCreate [RPCRT4.@]
79 RPC_STATUS WINAPI
MesDecodeIncrementalHandleCreate(
80 void *UserState
, MIDL_ES_READ ReadFn
, handle_t
*pHandle
)
82 MIDL_ES_MESSAGE
*pEsMsg
;
84 TRACE("(%p, %p, %p)\n", UserState
, ReadFn
, pHandle
);
86 pEsMsg
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg
));
88 return RPC_S_OUT_OF_MEMORY
;
90 init_MIDL_ES_MESSAGE(pEsMsg
);
92 pEsMsg
->Operation
= MES_DECODE
;
93 pEsMsg
->UserState
= UserState
;
94 pEsMsg
->HandleStyle
= MES_INCREMENTAL_HANDLE
;
95 pEsMsg
->Read
= ReadFn
;
97 *pHandle
= (handle_t
)pEsMsg
;
102 /***********************************************************************
103 * MesIncrementalHandleReset [RPCRT4.@]
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
)
109 MIDL_ES_MESSAGE
*pEsMsg
= Handle
;
111 TRACE("(%p, %p, %p, %p, %p, %d)\n", Handle
, UserState
, AllocFn
,
112 WriteFn
, ReadFn
, Operation
);
114 init_MIDL_ES_MESSAGE(pEsMsg
);
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
;
126 /***********************************************************************
127 * MesBufferHandleReset [RPCRT4.@]
129 RPC_STATUS WINAPI
MesBufferHandleReset(handle_t Handle
, ULONG HandleStyle
,
130 MIDL_ES_CODE Operation
, char **Buffer
, ULONG BufferSize
, ULONG
*EncodedSize
)
132 MIDL_ES_MESSAGE
*pEsMsg
= (MIDL_ES_MESSAGE
*)Handle
;
134 TRACE("(%p, %u, %d, %p, %u, %p)\n", Handle
, HandleStyle
, Operation
, Buffer
,
135 BufferSize
, EncodedSize
);
137 if (!Handle
|| !Buffer
|| !EncodedSize
)
138 return RPC_S_INVALID_ARG
;
140 if (Operation
!= MES_ENCODE
&& Operation
!= MES_DECODE
&& Operation
!= MES_ENCODE_NDR64
)
141 return RPC_S_INVALID_ARG
;
143 if (HandleStyle
!= MES_FIXED_BUFFER_HANDLE
&& HandleStyle
!= MES_DYNAMIC_BUFFER_HANDLE
)
144 return RPC_S_INVALID_ARG
;
146 init_MIDL_ES_MESSAGE(pEsMsg
);
148 pEsMsg
->Operation
= Operation
;
149 pEsMsg
->HandleStyle
= HandleStyle
;
150 if (HandleStyle
== MES_FIXED_BUFFER_HANDLE
)
151 pEsMsg
->Buffer
= (unsigned char*)*Buffer
;
153 pEsMsg
->pDynBuffer
= (unsigned char**)Buffer
;
154 pEsMsg
->BufferSize
= BufferSize
;
155 pEsMsg
->pEncodedSize
= EncodedSize
;
160 /***********************************************************************
161 * MesHandleFree [RPCRT4.@]
163 RPC_STATUS WINAPI
MesHandleFree(handle_t Handle
)
165 TRACE("(%p)\n", Handle
);
166 HeapFree(GetProcessHeap(), 0, Handle
);
170 static RPC_STATUS
validate_mes_buffer_pointer(const char *Buffer
)
173 return RPC_S_INVALID_ARG
;
175 if (((ULONG_PTR
)Buffer
& 7) != 0)
176 return RPC_X_INVALID_BUFFER
;
181 /***********************************************************************
182 * MesEncodeFixedBufferHandleCreate [RPCRT4.@]
184 RPC_STATUS RPC_ENTRY
MesEncodeFixedBufferHandleCreate(
185 char *Buffer
, ULONG BufferSize
, ULONG
*pEncodedSize
, handle_t
*pHandle
)
187 MIDL_ES_MESSAGE
*pEsMsg
;
190 TRACE("(%p, %d, %p, %p)\n", Buffer
, BufferSize
, pEncodedSize
, pHandle
);
192 if ((status
= validate_mes_buffer_pointer(Buffer
)))
196 return RPC_S_INVALID_ARG
;
198 /* FIXME: check BufferSize too */
200 pEsMsg
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg
));
202 return RPC_S_OUT_OF_MEMORY
;
204 init_MIDL_ES_MESSAGE(pEsMsg
);
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
;
212 *pHandle
= (handle_t
)pEsMsg
;
217 /***********************************************************************
218 * MesEncodeDynBufferHandleCreate [RPCRT4.@]
220 RPC_STATUS RPC_ENTRY
MesEncodeDynBufferHandleCreate(char **Buffer
,
221 ULONG
*pEncodedSize
, handle_t
*pHandle
)
223 MIDL_ES_MESSAGE
*pEsMsg
;
225 TRACE("(%p, %p, %p)\n", Buffer
, pEncodedSize
, pHandle
);
228 return RPC_S_INVALID_ARG
;
230 pEsMsg
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg
));
232 return RPC_S_OUT_OF_MEMORY
;
234 init_MIDL_ES_MESSAGE(pEsMsg
);
236 pEsMsg
->Operation
= MES_ENCODE
;
237 pEsMsg
->HandleStyle
= MES_DYNAMIC_BUFFER_HANDLE
;
238 pEsMsg
->pDynBuffer
= (unsigned char **)Buffer
;
239 pEsMsg
->pEncodedSize
= pEncodedSize
;
241 *pHandle
= (handle_t
)pEsMsg
;
246 /***********************************************************************
247 * MesDecodeBufferHandleCreate [RPCRT4.@]
249 RPC_STATUS RPC_ENTRY
MesDecodeBufferHandleCreate(
250 char *Buffer
, ULONG BufferSize
, handle_t
*pHandle
)
252 MIDL_ES_MESSAGE
*pEsMsg
;
255 TRACE("(%p, %d, %p)\n", Buffer
, BufferSize
, pHandle
);
257 if ((status
= validate_mes_buffer_pointer(Buffer
)))
260 pEsMsg
= HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg
));
262 return RPC_S_OUT_OF_MEMORY
;
264 init_MIDL_ES_MESSAGE(pEsMsg
);
266 pEsMsg
->Operation
= MES_DECODE
;
267 pEsMsg
->HandleStyle
= MES_FIXED_BUFFER_HANDLE
;
268 pEsMsg
->Buffer
= (unsigned char *)Buffer
;
269 pEsMsg
->BufferSize
= BufferSize
;
271 *pHandle
= (handle_t
)pEsMsg
;
276 static void es_data_alloc(MIDL_ES_MESSAGE
*pEsMsg
, ULONG size
)
278 if (pEsMsg
->HandleStyle
== MES_INCREMENTAL_HANDLE
)
280 unsigned int tmpsize
= size
;
281 TRACE("%d with incremental handle\n", size
);
282 pEsMsg
->Alloc(pEsMsg
->UserState
, (char **)&pEsMsg
->StubMsg
.Buffer
, &tmpsize
);
285 ERR("not enough bytes allocated - requested %d, got %d\n", size
, tmpsize
);
286 RpcRaiseException(RPC_S_OUT_OF_MEMORY
);
289 else if (pEsMsg
->HandleStyle
== MES_FIXED_BUFFER_HANDLE
)
291 TRACE("%d with fixed buffer handle\n", size
);
292 pEsMsg
->StubMsg
.Buffer
= pEsMsg
->Buffer
;
294 pEsMsg
->StubMsg
.RpcMsg
->Buffer
= pEsMsg
->StubMsg
.BufferStart
= pEsMsg
->StubMsg
.Buffer
;
297 static void es_data_read(MIDL_ES_MESSAGE
*pEsMsg
, ULONG size
)
299 if (pEsMsg
->HandleStyle
== MES_INCREMENTAL_HANDLE
)
301 unsigned int tmpsize
= size
;
302 TRACE("%d from incremental handle\n", size
);
303 pEsMsg
->Read(pEsMsg
->UserState
, (char **)&pEsMsg
->StubMsg
.Buffer
, &tmpsize
);
306 ERR("not enough bytes read - requested %d, got %d\n", size
, tmpsize
);
307 RpcRaiseException(RPC_S_OUT_OF_MEMORY
);
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
;
318 pEsMsg
->StubMsg
.BufferLength
= size
;
319 pEsMsg
->StubMsg
.RpcMsg
->Buffer
= pEsMsg
->StubMsg
.BufferStart
= pEsMsg
->StubMsg
.Buffer
;
320 pEsMsg
->StubMsg
.BufferEnd
= pEsMsg
->StubMsg
.Buffer
+ size
;
323 static void es_data_write(MIDL_ES_MESSAGE
*pEsMsg
, ULONG size
)
325 if (pEsMsg
->HandleStyle
== MES_INCREMENTAL_HANDLE
)
327 TRACE("%d to incremental handle\n", size
);
328 pEsMsg
->Write(pEsMsg
->UserState
, (char *)pEsMsg
->StubMsg
.BufferStart
, size
);
332 TRACE("%d to dynamic or fixed buffer handle\n", size
);
333 *pEsMsg
->pEncodedSize
+= size
;
337 static inline ULONG
mes_proc_header_buffer_size(void)
339 return 4 + 2*sizeof(RPC_SYNTAX_IDENTIFIER
) + 12;
342 static void mes_proc_header_marshal(MIDL_ES_MESSAGE
*pEsMsg
)
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;
361 static void mes_proc_header_unmarshal(MIDL_ES_MESSAGE
*pEsMsg
)
363 const RPC_CLIENT_INTERFACE
*client_interface
= pEsMsg
->StubMsg
.StubDesc
->RpcInterfaceInformation
;
365 es_data_read(pEsMsg
, mes_proc_header_buffer_size());
367 if (*(WORD
*)pEsMsg
->StubMsg
.Buffer
!= 0x0101)
369 FIXME("unknown value at Buffer[0] 0x%04x\n", *(WORD
*)pEsMsg
->StubMsg
.Buffer
);
370 RpcRaiseException(RPC_X_WRONG_ES_VERSION
);
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
)))
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
);
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
);
398 /***********************************************************************
399 * NdrMesProcEncodeDecode [RPCRT4.@]
401 void WINAPIV
NdrMesProcEncodeDecode(handle_t Handle
, const MIDL_STUB_DESC
* pStubDesc
, PFORMAT_STRING pFormat
, ...)
403 /* pointer to start of stack where arguments start */
405 MIDL_ES_MESSAGE
*pEsMsg
= Handle
;
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
;
412 unsigned int number_of_params
;
413 ULONG_PTR arg_buffer
[256];
415 TRACE("Handle %p, pStubDesc %p, pFormat %p, ...\n", Handle
, pStubDesc
, pFormat
);
417 /* Later NDR language versions probably won't be backwards compatible */
418 if (pStubDesc
->Version
> 0x50002)
420 FIXME("Incompatible stub description version: 0x%x\n", pStubDesc
->Version
);
421 RpcRaiseException(RPC_X_WRONG_STUB_VERSION
);
424 client_interface
= pStubDesc
->RpcInterfaceInformation
;
425 pEsMsg
->InterfaceId
= client_interface
->InterfaceId
;
427 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCFLAGS
)
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
);
436 stack_size
= pProcHeader
->stack_size
;
437 pEsMsg
->ProcNumber
= pProcHeader
->proc_num
;
438 pFormat
+= sizeof(NDR_PROC_HEADER
);
441 if (pProcHeader
->handle_type
== RPC_FC_BIND_EXPLICIT
)
443 switch (*pFormat
) /* handle_type */
445 case RPC_FC_BIND_PRIMITIVE
: /* explicit primitive */
446 pFormat
+= sizeof(NDR_EHD_PRIMITIVE
);
448 case RPC_FC_BIND_GENERIC
: /* explicit generic */
449 pFormat
+= sizeof(NDR_EHD_GENERIC
);
451 case RPC_FC_BIND_CONTEXT
: /* explicit context */
452 pFormat
+= sizeof(NDR_EHD_CONTEXT
);
455 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader
->handle_type
);
456 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
460 TRACE("stack size: 0x%x\n", stack_size
);
461 TRACE("proc num: %d\n", pEsMsg
->ProcNumber
);
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
;
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
);
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
);
477 /* needed for conformance of top-level objects */
478 __ms_va_start( args
, pFormat
);
479 pEsMsg
->StubMsg
.StackTop
= va_arg( args
, unsigned char * );
482 pFormat
= convert_old_args( &pEsMsg
->StubMsg
, pFormat
, stack_size
, FALSE
,
483 arg_buffer
, sizeof(arg_buffer
), &number_of_params
);
485 switch (pEsMsg
->Operation
)
488 pEsMsg
->StubMsg
.BufferLength
= mes_proc_header_buffer_size();
490 client_do_args( &pEsMsg
->StubMsg
, pFormat
, STUBLESS_CALCSIZE
, NULL
, number_of_params
, NULL
);
492 pEsMsg
->ByteCount
= pEsMsg
->StubMsg
.BufferLength
- mes_proc_header_buffer_size();
493 es_data_alloc(pEsMsg
, pEsMsg
->StubMsg
.BufferLength
);
495 mes_proc_header_marshal(pEsMsg
);
497 client_do_args( &pEsMsg
->StubMsg
, pFormat
, STUBLESS_MARSHAL
, NULL
, number_of_params
, NULL
);
499 es_data_write(pEsMsg
, pEsMsg
->ByteCount
);
502 mes_proc_header_unmarshal(pEsMsg
);
504 es_data_read(pEsMsg
, pEsMsg
->ByteCount
);
506 client_do_args( &pEsMsg
->StubMsg
, pFormat
, STUBLESS_UNMARSHAL
, NULL
, number_of_params
, NULL
);
509 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
512 /* free the full pointer translation tables */
513 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_FULLPTR
)
514 NdrFullPointerXlatFree(pEsMsg
->StubMsg
.FullPtrXlatTables
);
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
)
520 FIXME("(%p, %p, %p, %p, %p)\n", Handle
, pPicklingInfo
, pStubDesc
, pFormatString
, pObject
);
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
)
526 FIXME("(%p, %p, %p, %p, %p)\n", Handle
, pPicklingInfo
, pStubDesc
, pFormatString
, pObject
);
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
)
532 FIXME("(%p, %p, %p, %p, %p)\n", Handle
, pPicklingInfo
, pStubDesc
, pFormatString
, pObject
);