| /* |
| * NDR Serialization Services |
| * |
| * Copyright (c) 2007 Robert Shearman for CodeWeavers |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include <stdarg.h> |
| #include <stdio.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "rpc.h" |
| #include "midles.h" |
| #include "ndrtypes.h" |
| |
| #include "ndr_misc.h" |
| #include "ndr_stubless.h" |
| |
| #include "wine/debug.h" |
| #include "wine/rpcfc.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| static inline void init_MIDL_ES_MESSAGE(MIDL_ES_MESSAGE *pEsMsg) |
| { |
| memset(pEsMsg, 0, sizeof(*pEsMsg)); |
| /* even if we are unmarshalling, as we don't want pointers to be pointed |
| * to buffer memory */ |
| pEsMsg->StubMsg.IsClient = TRUE; |
| pEsMsg->MesVersion = 1; |
| } |
| |
| /*********************************************************************** |
| * MesEncodeIncrementalHandleCreate [RPCRT4.@] |
| */ |
| RPC_STATUS WINAPI MesEncodeIncrementalHandleCreate( |
| void *UserState, MIDL_ES_ALLOC AllocFn, MIDL_ES_WRITE WriteFn, |
| handle_t *pHandle) |
| { |
| MIDL_ES_MESSAGE *pEsMsg; |
| |
| TRACE("(%p, %p, %p, %p)\n", UserState, AllocFn, WriteFn, pHandle); |
| |
| pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); |
| if (!pEsMsg) |
| return RPC_S_OUT_OF_MEMORY; |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = MES_ENCODE; |
| pEsMsg->UserState = UserState; |
| pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; |
| pEsMsg->Alloc = AllocFn; |
| pEsMsg->Write = WriteFn; |
| |
| *pHandle = (handle_t)pEsMsg; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesDecodeIncrementalHandleCreate [RPCRT4.@] |
| */ |
| RPC_STATUS WINAPI MesDecodeIncrementalHandleCreate( |
| void *UserState, MIDL_ES_READ ReadFn, handle_t *pHandle) |
| { |
| MIDL_ES_MESSAGE *pEsMsg; |
| |
| TRACE("(%p, %p, %p)\n", UserState, ReadFn, pHandle); |
| |
| pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); |
| if (!pEsMsg) |
| return RPC_S_OUT_OF_MEMORY; |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = MES_DECODE; |
| pEsMsg->UserState = UserState; |
| pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; |
| pEsMsg->Read = ReadFn; |
| |
| *pHandle = (handle_t)pEsMsg; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesIncrementalHandleReset [RPCRT4.@] |
| */ |
| RPC_STATUS WINAPI MesIncrementalHandleReset( |
| handle_t Handle, void *UserState, MIDL_ES_ALLOC AllocFn, |
| MIDL_ES_WRITE WriteFn, MIDL_ES_READ ReadFn, MIDL_ES_CODE Operation) |
| { |
| MIDL_ES_MESSAGE *pEsMsg = Handle; |
| |
| TRACE("(%p, %p, %p, %p, %p, %d)\n", Handle, UserState, AllocFn, |
| WriteFn, ReadFn, Operation); |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = Operation; |
| pEsMsg->UserState = UserState; |
| pEsMsg->HandleStyle = MES_INCREMENTAL_HANDLE; |
| pEsMsg->Alloc = AllocFn; |
| pEsMsg->Write = WriteFn; |
| pEsMsg->Read = ReadFn; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesBufferHandleReset [RPCRT4.@] |
| */ |
| RPC_STATUS WINAPI MesBufferHandleReset(handle_t Handle, ULONG HandleStyle, |
| MIDL_ES_CODE Operation, char **Buffer, ULONG BufferSize, ULONG *EncodedSize) |
| { |
| MIDL_ES_MESSAGE *pEsMsg = (MIDL_ES_MESSAGE *)Handle; |
| |
| TRACE("(%p, %u, %d, %p, %u, %p)\n", Handle, HandleStyle, Operation, Buffer, |
| BufferSize, EncodedSize); |
| |
| if (!Handle || !Buffer || !EncodedSize) |
| return RPC_S_INVALID_ARG; |
| |
| if (Operation != MES_ENCODE && Operation != MES_DECODE && Operation != MES_ENCODE_NDR64) |
| return RPC_S_INVALID_ARG; |
| |
| if (HandleStyle != MES_FIXED_BUFFER_HANDLE && HandleStyle != MES_DYNAMIC_BUFFER_HANDLE) |
| return RPC_S_INVALID_ARG; |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = Operation; |
| pEsMsg->HandleStyle = HandleStyle; |
| if (HandleStyle == MES_FIXED_BUFFER_HANDLE) |
| pEsMsg->Buffer = (unsigned char*)*Buffer; |
| else |
| pEsMsg->pDynBuffer = (unsigned char**)Buffer; |
| pEsMsg->BufferSize = BufferSize; |
| pEsMsg->pEncodedSize = EncodedSize; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesHandleFree [RPCRT4.@] |
| */ |
| RPC_STATUS WINAPI MesHandleFree(handle_t Handle) |
| { |
| TRACE("(%p)\n", Handle); |
| HeapFree(GetProcessHeap(), 0, Handle); |
| return RPC_S_OK; |
| } |
| |
| static RPC_STATUS validate_mes_buffer_pointer(const char *Buffer) |
| { |
| if (!Buffer) |
| return RPC_S_INVALID_ARG; |
| |
| if (((ULONG_PTR)Buffer & 7) != 0) |
| return RPC_X_INVALID_BUFFER; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesEncodeFixedBufferHandleCreate [RPCRT4.@] |
| */ |
| RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate( |
| char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle) |
| { |
| MIDL_ES_MESSAGE *pEsMsg; |
| RPC_STATUS status; |
| |
| TRACE("(%p, %d, %p, %p)\n", Buffer, BufferSize, pEncodedSize, pHandle); |
| |
| if ((status = validate_mes_buffer_pointer(Buffer))) |
| return status; |
| |
| if (!pEncodedSize) |
| return RPC_S_INVALID_ARG; |
| |
| /* FIXME: check BufferSize too */ |
| |
| pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); |
| if (!pEsMsg) |
| return RPC_S_OUT_OF_MEMORY; |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = MES_ENCODE; |
| pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE; |
| pEsMsg->Buffer = (unsigned char *)Buffer; |
| pEsMsg->BufferSize = BufferSize; |
| pEsMsg->pEncodedSize = pEncodedSize; |
| |
| *pHandle = (handle_t)pEsMsg; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesEncodeDynBufferHandleCreate [RPCRT4.@] |
| */ |
| RPC_STATUS RPC_ENTRY MesEncodeDynBufferHandleCreate(char **Buffer, |
| ULONG *pEncodedSize, handle_t *pHandle) |
| { |
| MIDL_ES_MESSAGE *pEsMsg; |
| |
| TRACE("(%p, %p, %p)\n", Buffer, pEncodedSize, pHandle); |
| |
| if (!pEncodedSize) |
| return RPC_S_INVALID_ARG; |
| |
| pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); |
| if (!pEsMsg) |
| return RPC_S_OUT_OF_MEMORY; |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = MES_ENCODE; |
| pEsMsg->HandleStyle = MES_DYNAMIC_BUFFER_HANDLE; |
| pEsMsg->pDynBuffer = (unsigned char **)Buffer; |
| pEsMsg->pEncodedSize = pEncodedSize; |
| |
| *pHandle = (handle_t)pEsMsg; |
| |
| return RPC_S_OK; |
| } |
| |
| /*********************************************************************** |
| * MesDecodeBufferHandleCreate [RPCRT4.@] |
| */ |
| RPC_STATUS RPC_ENTRY MesDecodeBufferHandleCreate( |
| char *Buffer, ULONG BufferSize, handle_t *pHandle) |
| { |
| MIDL_ES_MESSAGE *pEsMsg; |
| RPC_STATUS status; |
| |
| TRACE("(%p, %d, %p)\n", Buffer, BufferSize, pHandle); |
| |
| if ((status = validate_mes_buffer_pointer(Buffer))) |
| return status; |
| |
| pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); |
| if (!pEsMsg) |
| return RPC_S_OUT_OF_MEMORY; |
| |
| init_MIDL_ES_MESSAGE(pEsMsg); |
| |
| pEsMsg->Operation = MES_DECODE; |
| pEsMsg->HandleStyle = MES_FIXED_BUFFER_HANDLE; |
| pEsMsg->Buffer = (unsigned char *)Buffer; |
| pEsMsg->BufferSize = BufferSize; |
| |
| *pHandle = (handle_t)pEsMsg; |
| |
| return RPC_S_OK; |
| } |
| |
| static void es_data_alloc(MIDL_ES_MESSAGE *pEsMsg, ULONG size) |
| { |
| if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) |
| { |
| unsigned int tmpsize = size; |
| TRACE("%d with incremental handle\n", size); |
| pEsMsg->Alloc(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize); |
| if (tmpsize < size) |
| { |
| ERR("not enough bytes allocated - requested %d, got %d\n", size, tmpsize); |
| RpcRaiseException(RPC_S_OUT_OF_MEMORY); |
| } |
| } |
| else if (pEsMsg->HandleStyle == MES_FIXED_BUFFER_HANDLE) |
| { |
| TRACE("%d with fixed buffer handle\n", size); |
| pEsMsg->StubMsg.Buffer = pEsMsg->Buffer; |
| } |
| pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer; |
| } |
| |
| static void es_data_read(MIDL_ES_MESSAGE *pEsMsg, ULONG size) |
| { |
| if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) |
| { |
| unsigned int tmpsize = size; |
| TRACE("%d from incremental handle\n", size); |
| pEsMsg->Read(pEsMsg->UserState, (char **)&pEsMsg->StubMsg.Buffer, &tmpsize); |
| if (tmpsize < size) |
| { |
| ERR("not enough bytes read - requested %d, got %d\n", size, tmpsize); |
| RpcRaiseException(RPC_S_OUT_OF_MEMORY); |
| } |
| } |
| else |
| { |
| TRACE("%d from fixed or dynamic buffer handle\n", size); |
| /* FIXME: validate BufferSize? */ |
| pEsMsg->StubMsg.Buffer = pEsMsg->Buffer; |
| pEsMsg->Buffer += size; |
| pEsMsg->BufferSize -= size; |
| } |
| pEsMsg->StubMsg.BufferLength = size; |
| pEsMsg->StubMsg.RpcMsg->Buffer = pEsMsg->StubMsg.BufferStart = pEsMsg->StubMsg.Buffer; |
| pEsMsg->StubMsg.BufferEnd = pEsMsg->StubMsg.Buffer + size; |
| } |
| |
| static void es_data_write(MIDL_ES_MESSAGE *pEsMsg, ULONG size) |
| { |
| if (pEsMsg->HandleStyle == MES_INCREMENTAL_HANDLE) |
| { |
| TRACE("%d to incremental handle\n", size); |
| pEsMsg->Write(pEsMsg->UserState, (char *)pEsMsg->StubMsg.BufferStart, size); |
| } |
| else |
| { |
| TRACE("%d to dynamic or fixed buffer handle\n", size); |
| *pEsMsg->pEncodedSize += size; |
| } |
| } |
| |
| static inline ULONG mes_proc_header_buffer_size(void) |
| { |
| return 4 + 2*sizeof(RPC_SYNTAX_IDENTIFIER) + 12; |
| } |
| |
| static void mes_proc_header_marshal(MIDL_ES_MESSAGE *pEsMsg) |
| { |
| const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation; |
| *(WORD *)pEsMsg->StubMsg.Buffer = 0x0101; |
| pEsMsg->StubMsg.Buffer += 2; |
| *(WORD *)pEsMsg->StubMsg.Buffer = 0xcccc; |
| pEsMsg->StubMsg.Buffer += 2; |
| memcpy(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER)); |
| pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); |
| memcpy(pEsMsg->StubMsg.Buffer, &pEsMsg->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)); |
| pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); |
| *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ProcNumber; |
| pEsMsg->StubMsg.Buffer += 4; |
| *(DWORD *)pEsMsg->StubMsg.Buffer = 0x00000001; |
| pEsMsg->StubMsg.Buffer += 4; |
| *(DWORD *)pEsMsg->StubMsg.Buffer = pEsMsg->ByteCount; |
| pEsMsg->StubMsg.Buffer += 4; |
| } |
| |
| static void mes_proc_header_unmarshal(MIDL_ES_MESSAGE *pEsMsg) |
| { |
| const RPC_CLIENT_INTERFACE *client_interface = pEsMsg->StubMsg.StubDesc->RpcInterfaceInformation; |
| |
| es_data_read(pEsMsg, mes_proc_header_buffer_size()); |
| |
| if (*(WORD *)pEsMsg->StubMsg.Buffer != 0x0101) |
| { |
| FIXME("unknown value at Buffer[0] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer); |
| RpcRaiseException(RPC_X_WRONG_ES_VERSION); |
| } |
| pEsMsg->StubMsg.Buffer += 2; |
| if (*(WORD *)pEsMsg->StubMsg.Buffer != 0xcccc) |
| FIXME("unknown value at Buffer[2] 0x%04x\n", *(WORD *)pEsMsg->StubMsg.Buffer); |
| pEsMsg->StubMsg.Buffer += 2; |
| if (memcmp(pEsMsg->StubMsg.Buffer, &client_interface->TransferSyntax, sizeof(RPC_SYNTAX_IDENTIFIER))) |
| { |
| const RPC_SYNTAX_IDENTIFIER *AlienTransferSyntax = (const RPC_SYNTAX_IDENTIFIER *)pEsMsg->StubMsg.Buffer; |
| ERR("bad transfer syntax %s {%d.%d}\n", debugstr_guid(&AlienTransferSyntax->SyntaxGUID), |
| AlienTransferSyntax->SyntaxVersion.MajorVersion, |
| AlienTransferSyntax->SyntaxVersion.MinorVersion); |
| RpcRaiseException(RPC_S_UNSUPPORTED_TRANS_SYN); |
| } |
| pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); |
| memcpy(&pEsMsg->InterfaceId, pEsMsg->StubMsg.Buffer, sizeof(RPC_SYNTAX_IDENTIFIER)); |
| pEsMsg->StubMsg.Buffer += sizeof(RPC_SYNTAX_IDENTIFIER); |
| pEsMsg->ProcNumber = *(DWORD *)pEsMsg->StubMsg.Buffer; |
| pEsMsg->StubMsg.Buffer += 4; |
| if (*(DWORD *)pEsMsg->StubMsg.Buffer != 0x00000001) |
| FIXME("unknown value 0x%08x, expected 0x00000001\n", *(DWORD *)pEsMsg->StubMsg.Buffer); |
| pEsMsg->StubMsg.Buffer += 4; |
| pEsMsg->ByteCount = *(DWORD *)pEsMsg->StubMsg.Buffer; |
| pEsMsg->StubMsg.Buffer += 4; |
| if (pEsMsg->ByteCount + mes_proc_header_buffer_size() < pEsMsg->ByteCount) |
| RpcRaiseException(RPC_S_INVALID_BOUND); |
| } |
| |
| /*********************************************************************** |
| * NdrMesProcEncodeDecode [RPCRT4.@] |
| */ |
| void WINAPIV NdrMesProcEncodeDecode(handle_t Handle, const MIDL_STUB_DESC * pStubDesc, PFORMAT_STRING pFormat, ...) |
| { |
| /* pointer to start of stack where arguments start */ |
| RPC_MESSAGE rpcMsg; |
| MIDL_ES_MESSAGE *pEsMsg = Handle; |
| /* size of stack */ |
| unsigned short stack_size; |
| /* header for procedure string */ |
| const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; |
| const RPC_CLIENT_INTERFACE *client_interface; |
| __ms_va_list args; |
| unsigned int number_of_params; |
| ULONG_PTR arg_buffer[256]; |
| |
| TRACE("Handle %p, pStubDesc %p, pFormat %p, ...\n", Handle, pStubDesc, pFormat); |
| |
| /* Later NDR language versions probably won't be backwards compatible */ |
| if (pStubDesc->Version > 0x50002) |
| { |
| FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); |
| RpcRaiseException(RPC_X_WRONG_STUB_VERSION); |
| } |
| |
| client_interface = pStubDesc->RpcInterfaceInformation; |
| pEsMsg->InterfaceId = client_interface->InterfaceId; |
| |
| if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) |
| { |
| const NDR_PROC_HEADER_RPC *header_rpc = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; |
| stack_size = header_rpc->stack_size; |
| pEsMsg->ProcNumber = header_rpc->proc_num; |
| pFormat += sizeof(NDR_PROC_HEADER_RPC); |
| } |
| else |
| { |
| stack_size = pProcHeader->stack_size; |
| pEsMsg->ProcNumber = pProcHeader->proc_num; |
| pFormat += sizeof(NDR_PROC_HEADER); |
| } |
| |
| if (pProcHeader->handle_type == RPC_FC_BIND_EXPLICIT) |
| { |
| switch (*pFormat) /* handle_type */ |
| { |
| case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ |
| pFormat += sizeof(NDR_EHD_PRIMITIVE); |
| break; |
| case RPC_FC_BIND_GENERIC: /* explicit generic */ |
| pFormat += sizeof(NDR_EHD_GENERIC); |
| break; |
| case RPC_FC_BIND_CONTEXT: /* explicit context */ |
| pFormat += sizeof(NDR_EHD_CONTEXT); |
| break; |
| default: |
| ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); |
| RpcRaiseException(RPC_X_BAD_STUB_DATA); |
| } |
| } |
| |
| TRACE("stack size: 0x%x\n", stack_size); |
| TRACE("proc num: %d\n", pEsMsg->ProcNumber); |
| |
| memset(&rpcMsg, 0, sizeof(rpcMsg)); |
| pEsMsg->StubMsg.RpcMsg = &rpcMsg; |
| pEsMsg->StubMsg.StubDesc = pStubDesc; |
| pEsMsg->StubMsg.pfnAllocate = pStubDesc->pfnAllocate; |
| pEsMsg->StubMsg.pfnFree = pStubDesc->pfnFree; |
| |
| /* create the full pointer translation tables, if requested */ |
| if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) |
| pEsMsg->StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); |
| |
| TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); |
| TRACE("stubdesc version = 0x%x\n", pStubDesc->Version); |
| TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); |
| |
| /* needed for conformance of top-level objects */ |
| __ms_va_start( args, pFormat ); |
| pEsMsg->StubMsg.StackTop = va_arg( args, unsigned char * ); |
| __ms_va_end( args ); |
| |
| pFormat = convert_old_args( &pEsMsg->StubMsg, pFormat, stack_size, FALSE, |
| arg_buffer, sizeof(arg_buffer), &number_of_params ); |
| |
| switch (pEsMsg->Operation) |
| { |
| case MES_ENCODE: |
| pEsMsg->StubMsg.BufferLength = mes_proc_header_buffer_size(); |
| |
| client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_CALCSIZE, NULL, number_of_params, NULL ); |
| |
| pEsMsg->ByteCount = pEsMsg->StubMsg.BufferLength - mes_proc_header_buffer_size(); |
| es_data_alloc(pEsMsg, pEsMsg->StubMsg.BufferLength); |
| |
| mes_proc_header_marshal(pEsMsg); |
| |
| client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_MARSHAL, NULL, number_of_params, NULL ); |
| |
| es_data_write(pEsMsg, pEsMsg->ByteCount); |
| break; |
| case MES_DECODE: |
| mes_proc_header_unmarshal(pEsMsg); |
| |
| es_data_read(pEsMsg, pEsMsg->ByteCount); |
| |
| client_do_args( &pEsMsg->StubMsg, pFormat, STUBLESS_UNMARSHAL, NULL, number_of_params, NULL ); |
| break; |
| default: |
| RpcRaiseException(RPC_S_INTERNAL_ERROR); |
| return; |
| } |
| /* free the full pointer translation tables */ |
| if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) |
| NdrFullPointerXlatFree(pEsMsg->StubMsg.FullPtrXlatTables); |
| } |
| |
| void RPC_ENTRY NdrMesTypeDecode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, |
| const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject) |
| { |
| FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); |
| } |
| |
| void RPC_ENTRY NdrMesTypeEncode2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, |
| const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, const void *pObject) |
| { |
| FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); |
| } |
| |
| void RPC_ENTRY NdrMesTypeFree2(handle_t Handle, const MIDL_TYPE_PICKLING_INFO *pPicklingInfo, |
| const MIDL_STUB_DESC *pStubDesc, PFORMAT_STRING pFormatString, void *pObject) |
| { |
| FIXME("(%p, %p, %p, %p, %p)\n", Handle, pPicklingInfo, pStubDesc, pFormatString, pObject); |
| } |