From f1661e061c36f3e98a68e8bfeea034371d38c9fb Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sat, 13 Sep 2008 15:52:50 +0000 Subject: [PATCH] sync most of rpcrt4 to wine 1.1.4 svn path=/trunk/; revision=36188 --- reactos/dll/win32/rpcrt4/cpsf.c | 9 +- reactos/dll/win32/rpcrt4/ndr_clientserver.c | 18 +- reactos/dll/win32/rpcrt4/ndr_contexthandle.c | 5 +- reactos/dll/win32/rpcrt4/ndr_es.c | 430 ++++ reactos/dll/win32/rpcrt4/ndr_marshall.c | 2170 ++++++++++-------- reactos/dll/win32/rpcrt4/ndr_ole.c | 11 +- reactos/dll/win32/rpcrt4/ndr_stubless.c | 128 +- reactos/dll/win32/rpcrt4/ndr_stubless.h | 8 +- reactos/dll/win32/rpcrt4/rpc_assoc.c | 21 +- reactos/dll/win32/rpcrt4/rpc_binding.c | 489 ++-- reactos/dll/win32/rpcrt4/rpc_binding.h | 4 +- reactos/dll/win32/rpcrt4/rpc_defs.h | 2 - reactos/dll/win32/rpcrt4/rpc_message.c | 339 ++- reactos/dll/win32/rpcrt4/rpc_message.h | 2 + reactos/dll/win32/rpcrt4/rpc_transport.c | 2 +- reactos/dll/win32/rpcrt4/rpcrt4.rbuild | 1 + reactos/dll/win32/rpcrt4/rpcrt4.spec | 18 +- reactos/include/psdk/midles.h | 133 ++ reactos/include/psdk/ndrtypes.h | 9 +- reactos/include/psdk/oleidl.idl | 4 +- reactos/include/psdk/rpcdce.h | 52 +- reactos/include/psdk/rpcdcep.h | 2 +- reactos/include/psdk/rpcndr.h | 20 +- reactos/include/psdk/rpcproxy.h | 4 +- 24 files changed, 2615 insertions(+), 1266 deletions(-) create mode 100644 reactos/dll/win32/rpcrt4/ndr_es.c create mode 100644 reactos/include/psdk/midles.h diff --git a/reactos/dll/win32/rpcrt4/cpsf.c b/reactos/dll/win32/rpcrt4/cpsf.c index dcf37219195..373c97a75ea 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.c +++ b/reactos/dll/win32/rpcrt4/cpsf.c @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" +#include "wine/port.h" + #include #include #include @@ -62,7 +65,7 @@ static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface, if (IsEqualGUID(&IID_IUnknown,riid) || IsEqualGUID(&IID_IPSFactoryBuffer,riid)) { *obj = This; - This->RefCount++; + InterlockedIncrement( &This->RefCount ); return S_OK; } return E_NOINTERFACE; @@ -72,14 +75,14 @@ static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface) { CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; TRACE("(%p)->AddRef()\n",iface); - return ++(This->RefCount); + return InterlockedIncrement( &This->RefCount ); } static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface) { CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; TRACE("(%p)->Release()\n",iface); - return --(This->RefCount); + return InterlockedDecrement( &This->RefCount ); } static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface, diff --git a/reactos/dll/win32/rpcrt4/ndr_clientserver.c b/reactos/dll/win32/rpcrt4/ndr_clientserver.c index 1afab2a6218..968ea61134f 100644 --- a/reactos/dll/win32/rpcrt4/ndr_clientserver.c +++ b/reactos/dll/win32/rpcrt4/ndr_clientserver.c @@ -67,8 +67,9 @@ void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg->pPointerQueueState = NULL; pStubMsg->IgnoreEmbeddedPointers = 0; pStubMsg->PointerBufferMark = NULL; - pStubMsg->fBufferValid = 0; + pStubMsg->CorrDespIncrement = 0; pStubMsg->uFlags = 0; + pStubMsg->UniquePtrCount = 0; pStubMsg->pfnAllocate = pStubDesc->pfnAllocate; pStubMsg->pfnFree = pStubDesc->pfnFree; pStubMsg->StackTop = NULL; @@ -81,6 +82,13 @@ void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg->fHasReturn = 0; pStubMsg->fHasExtensions = 0; pStubMsg->fHasNewCorrDesc = 0; + pStubMsg->fIsIn = 0; + pStubMsg->fIsOut = 0; + pStubMsg->fIsOicf = 0; + pStubMsg->fBufferValid = 0; + pStubMsg->fHasMemoryValidateCallback = 0; + pStubMsg->fInFree = 0; + pStubMsg->fNeedMCCP = 0; pStubMsg->fUnused = 0; pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE; pStubMsg->pvDestContext = NULL; @@ -113,6 +121,7 @@ unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_M pStubMsg->IgnoreEmbeddedPointers = 0; pStubMsg->PointerBufferMark = NULL; pStubMsg->uFlags = 0; + pStubMsg->UniquePtrCount = 0; pStubMsg->pfnAllocate = pStubDesc->pfnAllocate; pStubMsg->pfnFree = pStubDesc->pfnFree; pStubMsg->StackTop = NULL; @@ -126,6 +135,12 @@ unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_M pStubMsg->fHasReturn = 0; pStubMsg->fHasExtensions = 0; pStubMsg->fHasNewCorrDesc = 0; + pStubMsg->fIsIn = 0; + pStubMsg->fIsOut = 0; + pStubMsg->fIsOicf = 0; + pStubMsg->fHasMemoryValidateCallback = 0; + pStubMsg->fInFree = 0; + pStubMsg->fNeedMCCP = 0; pStubMsg->fUnused = 0; pStubMsg->dwDestContext = MSHCTX_DIFFERENTMACHINE; pStubMsg->pvDestContext = NULL; @@ -194,6 +209,7 @@ unsigned char *WINAPI NdrSendReceive( PMIDL_STUB_MESSAGE stubmsg, unsigned char return NULL; } + /* avoid sending uninitialised parts of the buffer on the wire */ stubmsg->RpcMsg->BufferLength = buffer - (unsigned char *)stubmsg->RpcMsg->Buffer; status = I_RpcSendReceive(stubmsg->RpcMsg); if (status != RPC_S_OK) diff --git a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c index 8ed8f669dc1..15192a72878 100644 --- a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c +++ b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c @@ -89,7 +89,10 @@ RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) LeaveCriticalSection(&ndr_context_cs); if (!handle) + { + ERR("invalid handle %p\n", CContext); RpcRaiseException(ERROR_INVALID_HANDLE); + } return handle; } @@ -183,7 +186,7 @@ static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext, che->magic = NDR_CONTEXT_HANDLE_MAGIC; RpcBindingCopy(hBinding, &che->handle); list_add_tail(&context_handle_list, &che->entry); - memcpy(&che->wire_data, chi, sizeof *chi); + che->wire_data = *chi; } *CContext = che; diff --git a/reactos/dll/win32/rpcrt4/ndr_es.c b/reactos/dll/win32/rpcrt4/ndr_es.c new file mode 100644 index 00000000000..3423d396cb8 --- /dev/null +++ b/reactos/dll/win32/rpcrt4/ndr_es.c @@ -0,0 +1,430 @@ +/* + * 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 +#include + +#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; +} + +/*********************************************************************** + * 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 ERROR_OUTOFMEMORY; + + 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 ERROR_OUTOFMEMORY; + + 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 = (MIDL_ES_MESSAGE *)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; +} + +/*********************************************************************** + * MesHandleFree [RPCRT4.@] + */ +RPC_STATUS WINAPI MesHandleFree(handle_t Handle) +{ + TRACE("(%p)\n", Handle); + HeapFree(GetProcessHeap(), 0, Handle); + return RPC_S_OK; +} + +/*********************************************************************** + * MesEncodeFixedBufferHandleCreate [RPCRT4.@] + */ +RPC_STATUS RPC_ENTRY MesEncodeFixedBufferHandleCreate( + char *Buffer, ULONG BufferSize, ULONG *pEncodedSize, handle_t *pHandle) +{ + MIDL_ES_MESSAGE *pEsMsg; + + TRACE("(%p, %d, %p, %p)\n", Buffer, BufferSize, pEncodedSize, pHandle); + + pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); + if (!pEsMsg) + return ERROR_OUTOFMEMORY; + + 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;} + +/*********************************************************************** + * MesDecodeBufferHandleCreate [RPCRT4.@] + */ +RPC_STATUS RPC_ENTRY MesDecodeBufferHandleCreate( + char *Buffer, ULONG BufferSize, handle_t *pHandle) +{ + MIDL_ES_MESSAGE *pEsMsg; + + TRACE("(%p, %d, %p)\n", Buffer, BufferSize, pHandle); + + pEsMsg = HeapAlloc(GetProcessHeap(), 0, sizeof(*pEsMsg)); + if (!pEsMsg) + return ERROR_OUTOFMEMORY; + + 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(ERROR_OUTOFMEMORY); + } + } + 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(ERROR_OUTOFMEMORY); + } + } + 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 = (MIDL_ES_MESSAGE *)Handle; + /* size of stack */ + unsigned short stack_size; + /* header for procedure string */ + const NDR_PROC_HEADER *pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; + /* the value to return to the client from the remote procedure */ + LONG_PTR RetVal = 0; + const RPC_CLIENT_INTERFACE *client_interface; + + 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 *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; + stack_size = pProcHeader->stack_size; + pEsMsg->ProcNumber = pProcHeader->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 */ +#ifdef __i386__ + pEsMsg->StubMsg.StackTop = *(unsigned char **)(&pFormat+1); +#else +# warning Stack not retrieved for your CPU architecture +#endif + + switch (pEsMsg->Operation) + { + case MES_ENCODE: + pEsMsg->StubMsg.BufferLength = mes_proc_header_buffer_size(); + + client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_CALCSIZE, + pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal, + FALSE /* object_proc */, TRUE /* ignore_retval */); + + 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_old_format(&pEsMsg->StubMsg, pFormat, PROXY_MARSHAL, + pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal, + FALSE /* object_proc */, TRUE /* ignore_retval */); + + es_data_write(pEsMsg, pEsMsg->ByteCount); + break; + case MES_DECODE: + mes_proc_header_unmarshal(pEsMsg); + + es_data_read(pEsMsg, pEsMsg->ByteCount); + + client_do_args_old_format(&pEsMsg->StubMsg, pFormat, PROXY_UNMARSHAL, + pEsMsg->StubMsg.StackTop, stack_size, (unsigned char *)&RetVal, + FALSE /* object_proc */, TRUE /* ignore_retval */); + 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); +} diff --git a/reactos/dll/win32/rpcrt4/ndr_marshall.c b/reactos/dll/win32/rpcrt4/ndr_marshall.c index 888b1503182..bda04be31f4 100644 --- a/reactos/dll/win32/rpcrt4/ndr_marshall.c +++ b/reactos/dll/win32/rpcrt4/ndr_marshall.c @@ -24,13 +24,12 @@ * - transmit_as/represent as * - Multi-dimensional arrays * - Conversion functions (NdrConvert) - * - Checks for integer addition overflow in base type and user marshall functions + * - Checks for integer addition overflow in user marshall functions */ #include #include #include -#include #include #include "windef.h" @@ -110,6 +109,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \ } while (0) +#define NDR_POINTER_ID_BASE 0x20000 +#define NDR_POINTER_ID(pStubMsg) (NDR_POINTER_ID_BASE + ((pStubMsg)->UniquePtrCount++) * 4) #define NDR_TABLE_SIZE 128 #define NDR_TABLE_MASK 127 @@ -624,6 +625,19 @@ finish_conf: return pFormat+4; } +static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + if (IsConformanceOrVariancePresent(pFormat)) + { + if (pStubMsg->fHasNewCorrDesc) + pFormat += 6; + else + pFormat += 4; + } + return pFormat; +} + /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if * the result overflows 32-bits */ static inline ULONG safe_multiply(ULONG a, ULONG b) @@ -688,487 +702,35 @@ static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void * pStubMsg->Buffer += size; } -/* - * NdrConformantString: - * - * What MS calls a ConformantString is, in DCE terminology, - * a Varying-Conformant String. - * [ - * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') - * offset: DWORD (actual string data begins at (offset) CHARTYPE's - * into unmarshalled string) - * length: DWORD (# of CHARTYPE characters, inclusive of '\0') - * [ - * data: CHARTYPE[maxlen] - * ] - * ], where CHARTYPE is the appropriate character type (specified externally) - * - */ - -/*********************************************************************** - * NdrConformantStringMarshall [RPCRT4.@] - */ -unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, - unsigned char *pszMessage, PFORMAT_STRING pFormat) -{ - ULONG esize, size; - - TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); - - if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)pszMessage)); - pStubMsg->ActualCount = strlen((char*)pszMessage)+1; - esize = 1; - } - else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage)); - pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1; - esize = 2; - } - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception. */ - return NULL; - } - - if (pFormat[1] == RPC_FC_STRING_SIZED) - pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - pStubMsg->Offset = 0; - WriteConformance(pStubMsg); - WriteVariance(pStubMsg); - - size = safe_multiply(esize, pStubMsg->ActualCount); - safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */ - - /* success */ - return NULL; /* is this always right? */ -} - -/*********************************************************************** - * NdrConformantStringBufferSize [RPCRT4.@] - */ -void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char* pMemory, PFORMAT_STRING pFormat) +/* verify that string data sitting in the buffer is valid and safe to + * unmarshall */ +static void validate_string_data(MIDL_STUB_MESSAGE *pStubMsg, ULONG bufsize, ULONG esize) { - ULONG esize; + ULONG i; - TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - - SizeConformance(pStubMsg); - SizeVariance(pStubMsg); - - if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)pMemory)); - pStubMsg->ActualCount = strlen((char*)pMemory)+1; - esize = 1; - } - else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1; - esize = 2; - } - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - return; - } - - if (pFormat[1] == RPC_FC_STRING_SIZED) - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); -} - -/************************************************************************ - * NdrConformantStringMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat ) -{ - ULONG bufsize, memsize, esize, i; - - TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); - - ReadConformance(pStubMsg, NULL); - ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); - - if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) - { - ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", - pStubMsg->ActualCount, pStubMsg->MaxCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - if (pStubMsg->Offset) - { - ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (*pFormat == RPC_FC_C_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_C_WSTRING) esize = 2; - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - esize = 0; - } - - memsize = safe_multiply(esize, pStubMsg->MaxCount); - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) + /* verify the buffer is safe to access */ + if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || + (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); + ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, + pStubMsg->BufferEnd, pStubMsg->Buffer); + RpcRaiseException(RPC_X_BAD_STUB_DATA); } - safe_buffer_increment(pStubMsg, bufsize); - pStubMsg->MemorySize += memsize; - - return pStubMsg->MemorySize; -} - -/************************************************************************ - * NdrConformantStringUnmarshall [RPCRT4.@] - */ -unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) -{ - ULONG bufsize, memsize, esize, i; - - TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", - pStubMsg, *ppMemory, pFormat, fMustAlloc); - - assert(pFormat && ppMemory && pStubMsg); - - ReadConformance(pStubMsg, NULL); - ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); - - if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) - { - ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", - pStubMsg->ActualCount, pStubMsg->MaxCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - if (pStubMsg->Offset) - { - ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - if (*pFormat == RPC_FC_C_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_C_WSTRING) esize = 2; - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - esize = 0; - } - - memsize = safe_multiply(esize, pStubMsg->MaxCount); - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return NULL; - } - - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) + /* strings must always have null terminating bytes */ + if (bufsize < esize) { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; + ERR("invalid string length of %d\n", bufsize / esize); + RpcRaiseException(RPC_S_INVALID_BOUND); } - if (fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, memsize); - else - { - if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) - /* if the data in the RPC buffer is big enough, we just point straight - * into it */ - *ppMemory = pStubMsg->Buffer; - else if (!*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, memsize); - } - - if (*ppMemory == pStubMsg->Buffer) - safe_buffer_increment(pStubMsg, bufsize); - else - safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); - - if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); - } - else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); - } - - return NULL; /* FIXME: is this always right? */ -} - -/*********************************************************************** - * NdrNonConformantStringMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG esize, size, maxsize; - - TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - - maxsize = *(USHORT *)&pFormat[2]; - - if (*pFormat == RPC_FC_CSTRING) - { - ULONG i; - const char *str = (const char *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_an(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 1; - } - else if (*pFormat == RPC_FC_WSTRING) - { - ULONG i; - const WCHAR *str = (const WCHAR *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_wn(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 2; - } - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - pStubMsg->Offset = 0; - WriteVariance(pStubMsg); - - size = safe_multiply(esize, pStubMsg->ActualCount); - safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ - - return NULL; -} - -/*********************************************************************** - * NdrNonConformantStringUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - ULONG bufsize, memsize, esize, i, maxsize; - - TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", - pStubMsg, *ppMemory, pFormat, fMustAlloc); - - maxsize = *(USHORT *)&pFormat[2]; - - ReadVariance(pStubMsg, NULL, maxsize); - if (pStubMsg->Offset) - { - ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (*pFormat == RPC_FC_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_WSTRING) esize = 2; - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - memsize = esize * maxsize; - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return NULL; - } - - /* strings must always have null terminating bytes */ - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, memsize); - - safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); - - if (*pFormat == RPC_FC_CSTRING) { - TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount)); - } - else if (*pFormat == RPC_FC_WSTRING) { - TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount)); - } - - return NULL; -} - -/*********************************************************************** - * NdrNonConformantStringBufferSize [RPCRT4.@] - */ -void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG esize, maxsize; - - TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - - maxsize = *(USHORT *)&pFormat[2]; - - SizeVariance(pStubMsg); - - if (*pFormat == RPC_FC_CSTRING) - { - ULONG i; - const char *str = (const char *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_an(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 1; - } - else if (*pFormat == RPC_FC_WSTRING) - { - ULONG i; - const WCHAR *str = (const WCHAR *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_wn(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 2; - } - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); -} - -/*********************************************************************** - * NdrNonConformantStringMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - ULONG bufsize, memsize, esize, i, maxsize; - - TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); - - maxsize = *(USHORT *)&pFormat[2]; - - ReadVariance(pStubMsg, NULL, maxsize); - - if (pStubMsg->Offset) - { - ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (*pFormat == RPC_FC_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_WSTRING) esize = 2; - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - memsize = esize * maxsize; - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - safe_buffer_increment(pStubMsg, bufsize); - pStubMsg->MemorySize += memsize; - - return pStubMsg->MemorySize; + for (i = bufsize - esize; i < bufsize; i++) + if (pStubMsg->Buffer[i] != 0) + { + ERR("string not null-terminated at byte position %d, data is 0x%x\n", + i, pStubMsg->Buffer[i]); + RpcRaiseException(RPC_S_INVALID_BOUND); + } } static inline void dump_pointer_attr(unsigned char attr) @@ -1221,7 +783,7 @@ static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, pointer_needs_marshaling = 1; else pointer_needs_marshaling = 0; - pointer_id = (ULONG)Pointer; + pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0; TRACE("writing 0x%08x to buffer\n", pointer_id); NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); break; @@ -1622,7 +1184,7 @@ static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, * EmbeddedPointerUnmarshall */ static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pDstMemoryPtrs, + unsigned char *pDstBuffer, unsigned char *pSrcMemoryPtrs, PFORMAT_STRING pFormat, unsigned char fMustAlloc) @@ -1632,7 +1194,7 @@ static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned i; unsigned char *saved_buffer = NULL; - TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc); + TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstBuffer, pSrcMemoryPtrs, pFormat, fMustAlloc); if (*pFormat != RPC_FC_PP) return NULL; pFormat += 2; @@ -1670,16 +1232,16 @@ static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, } for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; - unsigned char *memdstbase = pDstMemoryPtrs + (i * stride); + unsigned char *bufdstbase = pDstBuffer + (i * stride); unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride); unsigned char *bufbase = Mark + (i * stride); unsigned u; for (u=0; uBuffer, sizeof(type)); \ + TRACE("pMemory: %p\n", pMemory); \ + *(type *)pMemory = *(type *)pStubMsg->Buffer; \ + pStubMsg->Buffer += sizeof(type); + + switch(FormatChar) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + BASE_TYPE_UNMARSHALL(UCHAR); + TRACE("value: 0x%02x\n", *pMemory); + break; + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + BASE_TYPE_UNMARSHALL(USHORT); + TRACE("value: 0x%04x\n", *(USHORT *)pMemory); + break; + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ERROR_STATUS_T: + case RPC_FC_ENUM32: + BASE_TYPE_UNMARSHALL(ULONG); + TRACE("value: 0x%08x\n", *(ULONG *)pMemory); + break; + case RPC_FC_FLOAT: + BASE_TYPE_UNMARSHALL(float); + TRACE("value: %f\n", *(float *)pMemory); + break; + case RPC_FC_DOUBLE: + BASE_TYPE_UNMARSHALL(double); + TRACE("value: %f\n", *(double *)pMemory); + break; + case RPC_FC_HYPER: + BASE_TYPE_UNMARSHALL(ULONGLONG); + TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG *)pMemory)); + break; + case RPC_FC_ENUM16: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); + TRACE("pMemory: %p\n", pMemory); + /* 16-bits on the wire, but int in memory */ + *(UINT *)pMemory = *(USHORT *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(USHORT); + TRACE("value: 0x%08x\n", *(UINT *)pMemory); + break; + case RPC_FC_IGNORE: + break; + default: + FIXME("Unhandled base type: 0x%02x\n", FormatChar); + } +#undef BASE_TYPE_UNMARSHALL } /*********************************************************************** @@ -2114,8 +1735,821 @@ void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4); } +/* Array helpers */ -static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg, +static inline void array_compute_and_size_conformance( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + switch (fc) + { + case RPC_FC_CARRAY: + ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + SizeConformance(pStubMsg); + break; + case RPC_FC_CVARRAY: + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + SizeConformance(pStubMsg); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (pFormat[0] == RPC_FC_C_CSTRING) + { + TRACE("string=%s\n", debugstr_a((const char *)pMemory)); + pStubMsg->ActualCount = strlen((const char *)pMemory)+1; + } + else + { + TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory)); + pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; + } + + if (fc == RPC_FC_STRING_SIZED) + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + + SizeConformance(pStubMsg); + break; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline void array_buffer_size( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, + PFORMAT_STRING pFormat, unsigned char fHasPointers) +{ + DWORD size; + DWORD esize; + unsigned char alignment; + + switch (fc) + { + case RPC_FC_CARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + + ALIGN_LENGTH(pStubMsg->BufferLength, alignment); + + size = safe_multiply(esize, pStubMsg->MaxCount); + /* conformance value plus array */ + safe_buffer_length_increment(pStubMsg, size); + + if (fHasPointers) + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); + break; + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + pFormat = SkipConformance(pStubMsg, pFormat); + + SizeVariance(pStubMsg); + + ALIGN_LENGTH(pStubMsg->BufferLength, alignment); + + size = safe_multiply(esize, pStubMsg->ActualCount); + safe_buffer_length_increment(pStubMsg, size); + + if (fHasPointers) + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (fc == RPC_FC_C_CSTRING) + esize = 1; + else + esize = 2; + + SizeVariance(pStubMsg); + + size = safe_multiply(esize, pStubMsg->ActualCount); + safe_buffer_length_increment(pStubMsg, size); + break; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline void array_compute_and_write_conformance( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + switch (fc) + { + case RPC_FC_CARRAY: + ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + WriteConformance(pStubMsg); + break; + case RPC_FC_CVARRAY: + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, 0); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + WriteConformance(pStubMsg); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (fc == RPC_FC_C_CSTRING) + { + TRACE("string=%s\n", debugstr_a((const char *)pMemory)); + pStubMsg->ActualCount = strlen((const char *)pMemory)+1; + } + else + { + TRACE("string=%s\n", debugstr_w((LPCWSTR)pMemory)); + pStubMsg->ActualCount = strlenW((LPCWSTR)pMemory)+1; + } + if (pFormat[1] == RPC_FC_STRING_SIZED) + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + pStubMsg->Offset = 0; + WriteConformance(pStubMsg); + break; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline void array_write_variance_and_marshall( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, + PFORMAT_STRING pFormat, unsigned char fHasPointers) +{ + DWORD size; + DWORD esize; + unsigned char alignment; + + switch (fc) + { + case RPC_FC_CARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); + + size = safe_multiply(esize, pStubMsg->MaxCount); + if (fHasPointers) + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_to_buffer(pStubMsg, pMemory, size); + + if (fHasPointers) + EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + break; + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + /* conformance */ + pFormat = SkipConformance(pStubMsg, pFormat + 4); + /* variance */ + pFormat = SkipConformance(pStubMsg, pFormat); + + WriteVariance(pStubMsg); + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); + + size = safe_multiply(esize, pStubMsg->ActualCount); + + if (fHasPointers) + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, size); + + if (fHasPointers) + EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (fc == RPC_FC_C_CSTRING) + esize = 1; + else + esize = 2; + + WriteVariance(pStubMsg); + + size = safe_multiply(esize, pStubMsg->ActualCount); + safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ + break; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline ULONG array_read_conformance( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) +{ + DWORD esize; + + switch (fc) + { + case RPC_FC_CARRAY: + esize = *(const WORD*)(pFormat+2); + pFormat = ReadConformance(pStubMsg, pFormat+4); + return safe_multiply(esize, pStubMsg->MaxCount); + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pFormat+2); + pFormat = ReadConformance(pStubMsg, pFormat+4); + return safe_multiply(esize, pStubMsg->MaxCount); + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (fc == RPC_FC_C_CSTRING) + esize = 1; + else + esize = 2; + + if (pFormat[1] == RPC_FC_STRING_SIZED) + ReadConformance(pStubMsg, pFormat + 2); + else + ReadConformance(pStubMsg, NULL); + return safe_multiply(esize, pStubMsg->MaxCount); + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline ULONG array_read_variance_and_unmarshall( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, + PFORMAT_STRING pFormat, unsigned char fMustAlloc, + unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall) +{ + ULONG bufsize, memsize; + WORD esize; + unsigned char alignment; + unsigned char *saved_buffer; + ULONG offset; + + switch (fc) + { + case RPC_FC_CARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount); + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + + if (fUnmarshall) + { + if (fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, memsize); + else + { + if (fUseBufferMemoryServer && !pStubMsg->IsClient && !*ppMemory) + /* for servers, we just point straight into the RPC buffer */ + *ppMemory = pStubMsg->Buffer; + } + + saved_buffer = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); + + pStubMsg->BufferMark = saved_buffer; + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + TRACE("copying %p to %p\n", saved_buffer, *ppMemory); + if (*ppMemory != saved_buffer) + memcpy(*ppMemory, saved_buffer, bufsize); + } + return bufsize; + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + + pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + memsize = safe_multiply(esize, pStubMsg->MaxCount); + + if (fUnmarshall) + { + offset = pStubMsg->Offset; + + if (!fMustAlloc && !*ppMemory) + fMustAlloc = TRUE; + if (fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, memsize); + saved_buffer = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); + + pStubMsg->BufferMark = saved_buffer; + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, + fMustAlloc); + + memcpy(*ppMemory + offset, saved_buffer, bufsize); + } + return bufsize; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (fc == RPC_FC_C_CSTRING) + esize = 1; + else + esize = 2; + + ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); + + if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) + { + ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", + pStubMsg->ActualCount, pStubMsg->MaxCount); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + if (pStubMsg->Offset) + { + ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + memsize = safe_multiply(esize, pStubMsg->MaxCount); + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + validate_string_data(pStubMsg, bufsize, esize); + + if (fUnmarshall) + { + if (fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, memsize); + else + { + if (fUseBufferMemoryServer && !pStubMsg->IsClient && + !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) + /* if the data in the RPC buffer is big enough, we just point + * straight into it */ + *ppMemory = pStubMsg->Buffer; + else if (!*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, memsize); + } + + if (*ppMemory == pStubMsg->Buffer) + safe_buffer_increment(pStubMsg, bufsize); + else + safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); + + if (*pFormat == RPC_FC_C_CSTRING) + TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); + else + TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); + } + return bufsize; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline void array_memory_size( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, + unsigned char fHasPointers) +{ + ULONG bufsize, memsize; + DWORD esize; + unsigned char alignment; + + switch (fc) + { + case RPC_FC_CARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + + bufsize = memsize = safe_multiply(esize, pStubMsg->MaxCount); + pStubMsg->MemorySize += memsize; + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + if (fHasPointers) + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); + + if (fHasPointers) + EmbeddedPointerMemorySize(pStubMsg, pFormat); + break; + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pFormat+2); + alignment = pFormat[1] + 1; + + pFormat = SkipConformance(pStubMsg, pFormat + 4); + + pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + memsize = safe_multiply(esize, pStubMsg->MaxCount); + pStubMsg->MemorySize += memsize; + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + if (fHasPointers) + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); + + if (fHasPointers) + EmbeddedPointerMemorySize(pStubMsg, pFormat); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + if (fc == RPC_FC_C_CSTRING) + esize = 1; + else + esize = 2; + + ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); + + if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) + { + ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", + pStubMsg->ActualCount, pStubMsg->MaxCount); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + if (pStubMsg->Offset) + { + ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + memsize = safe_multiply(esize, pStubMsg->MaxCount); + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + validate_string_data(pStubMsg, bufsize, esize); + + safe_buffer_increment(pStubMsg, bufsize); + pStubMsg->MemorySize += memsize; + break; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static inline void array_free( + unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers) +{ + switch (fc) + { + case RPC_FC_CARRAY: + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + if (fHasPointers) + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); + break; + case RPC_FC_CVARRAY: + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + if (fHasPointers) + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); + break; + case RPC_FC_C_CSTRING: + case RPC_FC_C_WSTRING: + /* No embedded pointers so nothing to do */ + break; + default: + ERR("unknown array format 0x%x\n", fc); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +/* + * NdrConformantString: + * + * What MS calls a ConformantString is, in DCE terminology, + * a Varying-Conformant String. + * [ + * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') + * offset: DWORD (actual string data begins at (offset) CHARTYPE's + * into unmarshalled string) + * length: DWORD (# of CHARTYPE characters, inclusive of '\0') + * [ + * data: CHARTYPE[maxlen] + * ] + * ], where CHARTYPE is the appropriate character type (specified externally) + * + */ + +/*********************************************************************** + * NdrConformantStringMarshall [RPCRT4.@] + */ +unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, + unsigned char *pszMessage, PFORMAT_STRING pFormat) +{ + TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); + + if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { + ERR("Unhandled string type: %#x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + /* allow compiler to optimise inline function by passing constant into + * these functions */ + if (pFormat[0] == RPC_FC_C_CSTRING) { + array_compute_and_write_conformance(RPC_FC_C_CSTRING, pStubMsg, pszMessage, + pFormat); + array_write_variance_and_marshall(RPC_FC_C_CSTRING, pStubMsg, pszMessage, + pFormat, TRUE /* fHasPointers */); + } else { + array_compute_and_write_conformance(RPC_FC_C_WSTRING, pStubMsg, pszMessage, + pFormat); + array_write_variance_and_marshall(RPC_FC_C_WSTRING, pStubMsg, pszMessage, + pFormat, TRUE /* fHasPointers */); + } + + return NULL; +} + +/*********************************************************************** + * NdrConformantStringBufferSize [RPCRT4.@] + */ +void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char* pMemory, PFORMAT_STRING pFormat) +{ + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); + + if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { + ERR("Unhandled string type: %#x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + /* allow compiler to optimise inline function by passing constant into + * these functions */ + if (pFormat[0] == RPC_FC_C_CSTRING) { + array_compute_and_size_conformance(RPC_FC_C_CSTRING, pStubMsg, pMemory, + pFormat); + array_buffer_size(RPC_FC_C_CSTRING, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); + } else { + array_compute_and_size_conformance(RPC_FC_C_WSTRING, pStubMsg, pMemory, + pFormat); + array_buffer_size(RPC_FC_C_WSTRING, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); + } +} + +/************************************************************************ + * NdrConformantStringMemorySize [RPCRT4.@] + */ +ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat ) +{ + TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); + + if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { + ERR("Unhandled string type: %#x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + /* allow compiler to optimise inline function by passing constant into + * these functions */ + if (pFormat[0] == RPC_FC_C_CSTRING) { + array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat); + array_memory_size(RPC_FC_C_CSTRING, pStubMsg, pFormat, + TRUE /* fHasPointers */); + } else { + array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat); + array_memory_size(RPC_FC_C_WSTRING, pStubMsg, pFormat, + TRUE /* fHasPointers */); + } + + return pStubMsg->MemorySize; +} + +/************************************************************************ + * NdrConformantStringUnmarshall [RPCRT4.@] + */ +unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, + unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) +{ + TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", + pStubMsg, *ppMemory, pFormat, fMustAlloc); + + if (pFormat[0] != RPC_FC_C_CSTRING && pFormat[0] != RPC_FC_C_WSTRING) { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + /* allow compiler to optimise inline function by passing constant into + * these functions */ + if (pFormat[0] == RPC_FC_C_CSTRING) { + array_read_conformance(RPC_FC_C_CSTRING, pStubMsg, pFormat); + array_read_variance_and_unmarshall(RPC_FC_C_CSTRING, pStubMsg, ppMemory, + pFormat, fMustAlloc, + TRUE /* fUseBufferMemoryServer */, + TRUE /* fUnmarshall */); + } else { + array_read_conformance(RPC_FC_C_WSTRING, pStubMsg, pFormat); + array_read_variance_and_unmarshall(RPC_FC_C_WSTRING, pStubMsg, ppMemory, + pFormat, fMustAlloc, + TRUE /* fUseBufferMemoryServer */, + TRUE /* fUnmarshall */); + } + + return NULL; +} + +/*********************************************************************** + * NdrNonConformantStringMarshall [RPCRT4.@] + */ +unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + ULONG esize, size, maxsize; + + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); + + maxsize = *(USHORT *)&pFormat[2]; + + if (*pFormat == RPC_FC_CSTRING) + { + ULONG i; + const char *str = (const char *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_an(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 1; + } + else if (*pFormat == RPC_FC_WSTRING) + { + ULONG i; + const WCHAR *str = (const WCHAR *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_wn(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 2; + } + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + pStubMsg->Offset = 0; + WriteVariance(pStubMsg); + + size = safe_multiply(esize, pStubMsg->ActualCount); + safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ + + return NULL; +} + +/*********************************************************************** + * NdrNonConformantStringUnmarshall [RPCRT4.@] + */ +unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char **ppMemory, + PFORMAT_STRING pFormat, + unsigned char fMustAlloc) +{ + ULONG bufsize, memsize, esize, maxsize; + + TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", + pStubMsg, *ppMemory, pFormat, fMustAlloc); + + maxsize = *(USHORT *)&pFormat[2]; + + ReadVariance(pStubMsg, NULL, maxsize); + if (pStubMsg->Offset) + { + ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + if (*pFormat == RPC_FC_CSTRING) esize = 1; + else if (*pFormat == RPC_FC_WSTRING) esize = 2; + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + memsize = esize * maxsize; + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + validate_string_data(pStubMsg, bufsize, esize); + + if (fMustAlloc || !*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, memsize); + + safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); + + if (*pFormat == RPC_FC_CSTRING) { + TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount)); + } + else if (*pFormat == RPC_FC_WSTRING) { + TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount)); + } + + return NULL; +} + +/*********************************************************************** + * NdrNonConformantStringBufferSize [RPCRT4.@] + */ +void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + ULONG esize, maxsize; + + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); + + maxsize = *(USHORT *)&pFormat[2]; + + SizeVariance(pStubMsg); + + if (*pFormat == RPC_FC_CSTRING) + { + ULONG i; + const char *str = (const char *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_an(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 1; + } + else if (*pFormat == RPC_FC_WSTRING) + { + ULONG i; + const WCHAR *str = (const WCHAR *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_wn(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 2; + } + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); +} + +/*********************************************************************** + * NdrNonConformantStringMemorySize [RPCRT4.@] + */ +ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + ULONG bufsize, memsize, esize, maxsize; + + TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); + + maxsize = *(USHORT *)&pFormat[2]; + + ReadVariance(pStubMsg, NULL, maxsize); + + if (pStubMsg->Offset) + { + ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + if (*pFormat == RPC_FC_CSTRING) esize = 1; + else if (*pFormat == RPC_FC_WSTRING) esize = 2; + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + memsize = esize * maxsize; + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + validate_string_data(pStubMsg, bufsize, esize); + + safe_buffer_increment(pStubMsg, bufsize); + pStubMsg->MemorySize += memsize; + + return pStubMsg->MemorySize; +} + +/* Complex types */ + +#include "pshpack1.h" +typedef struct +{ + unsigned char type; + unsigned char flags_type; /* flags in upper nibble, type in lower nibble */ + ULONG low_value; + ULONG high_value; +} NDR_RANGE; +#include "poppack.h" + +static unsigned long EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { switch (*pFormat) { @@ -2129,6 +2563,34 @@ static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg, return *(const WORD*)&pFormat[2]; case RPC_FC_USER_MARSHAL: return *(const WORD*)&pFormat[4]; + case RPC_FC_RANGE: { + switch (((const NDR_RANGE *)pFormat)->flags_type & 0xf) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + return sizeof(UCHAR); + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + return sizeof(USHORT); + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM32: + return sizeof(ULONG); + case RPC_FC_FLOAT: + return sizeof(float); + case RPC_FC_DOUBLE: + return sizeof(double); + case RPC_FC_HYPER: + return sizeof(ULONGLONG); + case RPC_FC_ENUM16: + return sizeof(UINT); + default: + ERR("unknown type 0x%x\n", ((const NDR_RANGE *)pFormat)->flags_type & 0xf); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + } case RPC_FC_NON_ENCAPSULATED_UNION: pFormat += 2; if (pStubMsg->fHasNewCorrDesc) @@ -2190,6 +2652,13 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, safe_copy_to_buffer(pStubMsg, pMemory, 2); pMemory += 2; break; + case RPC_FC_ENUM16: + TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory); + if (32767 < *(DWORD*)pMemory) + RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); + safe_copy_to_buffer(pStubMsg, pMemory, 2); + pMemory += 4; + break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: @@ -2207,7 +2676,9 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *saved_buffer; int pointer_buffer_mark_set = 0; TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory); - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer); + if (*pPointer != RPC_FC_RP) + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); saved_buffer = pStubMsg->Buffer; if (pStubMsg->PointerBufferMark) { @@ -2215,21 +2686,18 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->PointerBufferMark = NULL; pointer_buffer_mark_set = 1; } - else + else if (*pPointer != RPC_FC_RP) safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer); if (pointer_buffer_mark_set) { STD_OVERFLOW_CHECK(pStubMsg); pStubMsg->PointerBufferMark = pStubMsg->Buffer; - if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - { - ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", - saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - pStubMsg->Buffer = saved_buffer + 4; + pStubMsg->Buffer = saved_buffer; + if (*pPointer != RPC_FC_RP) + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ } + TRACE("pStubMsg->Buffer after %p\n", pStubMsg->Buffer); pPointer += 4; pMemory += 4; break; @@ -2285,7 +2753,8 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, - PFORMAT_STRING pPointer) + PFORMAT_STRING pPointer, + unsigned char fMustAlloc) { PFORMAT_STRING desc; NDR_UNMARSHALL m; @@ -2308,6 +2777,14 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); pMemory += 2; break; + case RPC_FC_ENUM16: + safe_copy_from_buffer(pStubMsg, pMemory, 2); + *(DWORD*)pMemory &= 0xffff; + TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory); + if (32767 < *(DWORD*)pMemory) + RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); + pMemory += 4; + break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: @@ -2325,7 +2802,8 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *saved_buffer; int pointer_buffer_mark_set = 0; TRACE("pointer => %p\n", pMemory); - ALIGN_POINTER(pStubMsg->Buffer, 4); + if (*pPointer != RPC_FC_RP) + ALIGN_POINTER(pStubMsg->Buffer, 4); saved_buffer = pStubMsg->Buffer; if (pStubMsg->PointerBufferMark) { @@ -2333,21 +2811,17 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->PointerBufferMark = NULL; pointer_buffer_mark_set = 1; } - else + else if (*pPointer != RPC_FC_RP) safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ - PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE); + PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, fMustAlloc); if (pointer_buffer_mark_set) { STD_OVERFLOW_CHECK(pStubMsg); pStubMsg->PointerBufferMark = pStubMsg->Buffer; - if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - { - ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", - saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - pStubMsg->Buffer = saved_buffer + 4; + pStubMsg->Buffer = saved_buffer; + if (*pPointer != RPC_FC_RP) + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ } pPointer += 4; pMemory += 4; @@ -2375,8 +2849,14 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, desc = pFormat + *(const SHORT*)pFormat; size = EmbeddedComplexSize(pStubMsg, desc); TRACE("embedded complex (size=%ld) => %p\n", size, pMemory); + if (fMustAlloc) + /* we can't pass fMustAlloc=TRUE into the marshaller for this type + * since the type is part of the memory block that is encompassed by + * the whole complex type. Memory is forced to allocate when pointers + * are set to NULL, so we emulate that part of fMustAlloc=TRUE by + * clearing the memory we pass in to the unmarshaller */ + memset(pMemory, 0, size); m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; - memset(pMemory, 0, size); /* just in case */ if (m) { /* for some reason interface pointers aren't generated as @@ -2427,6 +2907,10 @@ static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, safe_buffer_length_increment(pStubMsg, 2); pMemory += 2; break; + case RPC_FC_ENUM16: + safe_buffer_length_increment(pStubMsg, 2); + pMemory += 4; + break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: @@ -2449,7 +2933,11 @@ static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->PointerLength = pStubMsg->BufferLength; pStubMsg->BufferLength = saved_buffer_length; } - safe_buffer_length_increment(pStubMsg, 4); + if (*pPointer != RPC_FC_RP) + { + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + safe_buffer_length_increment(pStubMsg, 4); + } pPointer += 4; pMemory += 4; break; @@ -2524,6 +3012,7 @@ static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, break; case RPC_FC_LONG: case RPC_FC_ULONG: + case RPC_FC_ENUM16: case RPC_FC_ENUM32: pMemory += 4; break; @@ -2582,7 +3071,8 @@ static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, } static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) + PFORMAT_STRING pFormat, + PFORMAT_STRING pPointer) { PFORMAT_STRING desc; unsigned long size = 0; @@ -2602,6 +3092,10 @@ static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, size += 2; safe_buffer_increment(pStubMsg, 2); break; + case RPC_FC_ENUM16: + size += 4; + safe_buffer_increment(pStubMsg, 2); + break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: @@ -2613,11 +3107,35 @@ static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, safe_buffer_increment(pStubMsg, 8); break; case RPC_FC_POINTER: - size += 4; - safe_buffer_increment(pStubMsg, 4); + { + unsigned char *saved_buffer; + int pointer_buffer_mark_set = 0; + if (*pPointer != RPC_FC_RP) + ALIGN_POINTER(pStubMsg->Buffer, 4); + saved_buffer = pStubMsg->Buffer; + if (pStubMsg->PointerBufferMark) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + pointer_buffer_mark_set = 1; + } + else if (*pPointer != RPC_FC_RP) + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ + if (!pStubMsg->IgnoreEmbeddedPointers) - FIXME("embedded pointers\n"); + PointerMemorySize(pStubMsg, saved_buffer, pPointer); + if (pointer_buffer_mark_set) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer; + if (*pPointer != RPC_FC_RP) + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ + } + pPointer += 4; + size += 4; break; + } case RPC_FC_ALIGNM4: ALIGN_LENGTH(size, 4); ALIGN_POINTER(pStubMsg->Buffer, 4); @@ -2674,6 +3192,7 @@ unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, break; case RPC_FC_LONG: case RPC_FC_ULONG: + case RPC_FC_ENUM16: case RPC_FC_ENUM32: size += 4; break; @@ -2727,6 +3246,9 @@ unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pointer_desc = NULL; unsigned char *OldMemory = pStubMsg->Memory; int pointer_buffer_mark_set = 0; + ULONG count = 0; + ULONG max_count = 0; + ULONG offset = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); @@ -2755,17 +3277,34 @@ unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1); pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; + if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; pFormat += 2; if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; pStubMsg->Memory = pMemory; - ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc); + if (conf_array) + { + unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat); + array_compute_and_write_conformance(conf_array[0], pStubMsg, + pMemory + struct_size, conf_array); + /* these could be changed in ComplexMarshall so save them for later */ + max_count = pStubMsg->MaxCount; + count = pStubMsg->ActualCount; + offset = pStubMsg->Offset; + } + + pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc); if (conf_array) - NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array); + { + pStubMsg->MaxCount = max_count; + pStubMsg->ActualCount = count; + pStubMsg->Offset = offset; + array_write_variance_and_marshall(conf_array[0], pStubMsg, pMemory, + conf_array, TRUE /* fHasPointers */); + } pStubMsg->Memory = OldMemory; @@ -2793,6 +3332,10 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pointer_desc = NULL; unsigned char *pMemory; int pointer_buffer_mark_set = 0; + ULONG count = 0; + ULONG max_count = 0; + ULONG offset = 0; + ULONG array_size = 0; TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -2819,22 +3362,40 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); - if (fMustAlloc || !*ppMemory) - { - *ppMemory = NdrAllocate(pStubMsg, size); - memset(*ppMemory, 0, size); - } - pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; + if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; pFormat += 2; if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; - pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc); + if (conf_array) + { + array_size = array_read_conformance(conf_array[0], pStubMsg, conf_array); + size += array_size; + + /* these could be changed in ComplexMarshall so save them for later */ + max_count = pStubMsg->MaxCount; + count = pStubMsg->ActualCount; + offset = pStubMsg->Offset; + } + + if (fMustAlloc || !*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, size); + + pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc); if (conf_array) - NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc); + { + pStubMsg->MaxCount = max_count; + pStubMsg->ActualCount = count; + pStubMsg->Offset = offset; + if (fMustAlloc) + memset(pMemory, 0, array_size); + array_read_variance_and_unmarshall(conf_array[0], pStubMsg, &pMemory, + conf_array, FALSE, + FALSE /* fUseBufferMemoryServer */, + TRUE /* fUnmarshall */); + } if (pointer_buffer_mark_set) { @@ -2856,6 +3417,9 @@ void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pointer_desc = NULL; unsigned char *OldMemory = pStubMsg->Memory; int pointer_length_set = 0; + ULONG count = 0; + ULONG max_count = 0; + ULONG offset = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); @@ -2882,17 +3446,35 @@ void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, } pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; + if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; pFormat += 2; if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; pStubMsg->Memory = pMemory; + if (conf_array) + { + unsigned long struct_size = ComplexStructSize(pStubMsg, pFormat); + array_compute_and_size_conformance(conf_array[0], pStubMsg, pMemory + struct_size, + conf_array); + + /* these could be changed in ComplexMarshall so save them for later */ + max_count = pStubMsg->MaxCount; + count = pStubMsg->ActualCount; + offset = pStubMsg->Offset; + } + pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc); if (conf_array) - NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array); + { + pStubMsg->MaxCount = max_count; + pStubMsg->ActualCount = count; + pStubMsg->Offset = offset; + array_buffer_size(conf_array[0], pStubMsg, pMemory, conf_array, + TRUE /* fHasPointers */); + } pStubMsg->Memory = OldMemory; @@ -2913,21 +3495,41 @@ ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, unsigned size = *(const WORD*)(pFormat+2); PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; + ULONG count = 0; + ULONG max_count = 0; + ULONG offset = 0; TRACE("(%p,%p)\n", pStubMsg, pFormat); ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; + if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; pFormat += 2; if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; - ComplexStructMemorySize(pStubMsg, pFormat); + if (conf_array) + { + array_read_conformance(conf_array[0], pStubMsg, conf_array); + + /* these could be changed in ComplexStructMemorySize so save them for + * later */ + max_count = pStubMsg->MaxCount; + count = pStubMsg->ActualCount; + offset = pStubMsg->Offset; + } + + ComplexStructMemorySize(pStubMsg, pFormat, pointer_desc); if (conf_array) - NdrConformantArrayMemorySize(pStubMsg, conf_array); + { + pStubMsg->MaxCount = max_count; + pStubMsg->ActualCount = count; + pStubMsg->Offset = offset; + array_memory_size(conf_array[0], pStubMsg, conf_array, + TRUE /* fHasPointers */); + } return size; } @@ -2946,7 +3548,7 @@ void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; + if (*(const SHORT*)pFormat) conf_array = pFormat + *(const SHORT*)pFormat; pFormat += 2; if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; @@ -2956,7 +3558,8 @@ void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc); if (conf_array) - NdrConformantArrayFree(pStubMsg, pMemory, conf_array); + array_free(conf_array[0], pStubMsg, pMemory, conf_array, + TRUE /* fHasPointers */); pStubMsg->Memory = OldMemory; } @@ -2968,23 +3571,17 @@ unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - DWORD size = 0, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); + if (pFormat[0] != RPC_FC_CARRAY) + { + ERR("invalid format = 0x%x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - - WriteConformance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); - - size = safe_multiply(esize, pStubMsg->MaxCount); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory, size); - - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + array_compute_and_write_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, + pFormat); + array_write_variance_and_marshall(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); return NULL; } @@ -2997,34 +3594,18 @@ unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - DWORD size, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - unsigned char *saved_buffer; - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - - pFormat = ReadConformance(pStubMsg, pFormat+4); - - size = safe_multiply(esize, pStubMsg->MaxCount); - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - if (fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, size); - else + if (pFormat[0] != RPC_FC_CARRAY) { - if (!pStubMsg->IsClient && !*ppMemory) - /* for servers, we just point straight into the RPC buffer */ - *ppMemory = pStubMsg->Buffer; + ERR("invalid format = 0x%x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); } - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, size); - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - TRACE("copying %p to %p\n", saved_buffer, *ppMemory); - if (*ppMemory != saved_buffer) - memcpy(*ppMemory, saved_buffer, size); + array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat); + array_read_variance_and_unmarshall(RPC_FC_CARRAY, pStubMsg, ppMemory, pFormat, + fMustAlloc, + TRUE /* fUseBufferMemoryServer */, + TRUE /* fUnmarshall */); return NULL; } @@ -3036,23 +3617,16 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - DWORD size, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); + if (pFormat[0] != RPC_FC_CARRAY) + { + ERR("invalid format = 0x%x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - - SizeConformance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, alignment); - - size = safe_multiply(esize, pStubMsg->MaxCount); - /* conformance value plus array */ - safe_buffer_length_increment(pStubMsg, size); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); + array_compute_and_size_conformance(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat); + array_buffer_size(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); } /*********************************************************************** @@ -3061,21 +3635,15 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - DWORD size = 0, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - TRACE("(%p,%p)\n", pStubMsg, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); + if (pFormat[0] != RPC_FC_CARRAY) + { + ERR("invalid format = 0x%x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } - pFormat = ReadConformance(pStubMsg, pFormat+4); - size = safe_multiply(esize, pStubMsg->MaxCount); - pStubMsg->MemorySize += size; - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, size); - - EmbeddedPointerMemorySize(pStubMsg, pFormat); + array_read_conformance(RPC_FC_CARRAY, pStubMsg, pFormat); + array_memory_size(RPC_FC_CARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */); return pStubMsg->MemorySize; } @@ -3088,11 +3656,14 @@ void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); + if (pFormat[0] != RPC_FC_CARRAY) + { + ERR("invalid format = 0x%x\n", pFormat[0]); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); + array_free(RPC_FC_CARRAY, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); } @@ -3103,10 +3674,6 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu unsigned char* pMemory, PFORMAT_STRING pFormat ) { - ULONG bufsize; - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); if (pFormat[0] != RPC_FC_CVARRAY) @@ -3116,20 +3683,10 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu return NULL; } - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - - WriteConformance(pStubMsg); - WriteVariance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); - - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + array_compute_and_write_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory, + pFormat); + array_write_variance_and_marshall(RPC_FC_CVARRAY, pStubMsg, pMemory, + pFormat, TRUE /* fHasPointers */); return NULL; } @@ -3143,12 +3700,6 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS PFORMAT_STRING pFormat, unsigned char fMustAlloc ) { - ULONG bufsize, memsize; - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - unsigned char *saved_buffer; - ULONG offset; - TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); if (pFormat[0] != RPC_FC_CVARRAY) @@ -3158,23 +3709,11 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS return NULL; } - pFormat = ReadConformance(pStubMsg, pFormat+4); - pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - memsize = safe_multiply(esize, pStubMsg->MaxCount); - offset = pStubMsg->Offset; - - if (!*ppMemory || fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, memsize); - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, bufsize); - - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - memcpy(*ppMemory + offset, saved_buffer, bufsize); + array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat); + array_read_variance_and_unmarshall(RPC_FC_CVARRAY, pStubMsg, ppMemory, + pFormat, fMustAlloc, + TRUE /* fUseBufferMemoryServer */, + TRUE /* fUnmarshall */); return NULL; } @@ -3196,10 +3735,8 @@ void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, return; } - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); + array_free(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); } @@ -3209,9 +3746,6 @@ void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat ) { - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); if (pFormat[0] != RPC_FC_CVARRAY) @@ -3221,19 +3755,10 @@ void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, return; } - /* compute size */ - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - /* compute length */ - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - - SizeConformance(pStubMsg); - SizeVariance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, alignment); - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); + array_compute_and_size_conformance(RPC_FC_CVARRAY, pStubMsg, pMemory, + pFormat); + array_buffer_size(RPC_FC_CVARRAY, pStubMsg, pMemory, pFormat, + TRUE /* fHasPointers */); } @@ -3243,10 +3768,6 @@ void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) { - ULONG bufsize, memsize; - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - TRACE("(%p, %p)\n", pStubMsg, pFormat); if (pFormat[0] != RPC_FC_CVARRAY) @@ -3256,18 +3777,9 @@ ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, return pStubMsg->MemorySize; } - pFormat = ReadConformance(pStubMsg, pFormat+4); - pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - memsize = safe_multiply(esize, pStubMsg->MaxCount); - - safe_buffer_increment(pStubMsg, bufsize); - pStubMsg->MemorySize += memsize; - - EmbeddedPointerMemorySize(pStubMsg, pFormat); + array_read_conformance(RPC_FC_CVARRAY, pStubMsg, pFormat); + array_memory_size(RPC_FC_CVARRAY, pStubMsg, pFormat, + TRUE /* fHasPointers */); return pStubMsg->MemorySize; } @@ -3409,17 +3921,14 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); if (fMustAlloc || !*ppMemory) - { *ppMemory = NdrAllocate(pStubMsg, size); - memset(*ppMemory, 0, size); - } ALIGN_POINTER(pStubMsg->Buffer, alignment); pMemory = *ppMemory; count = pStubMsg->ActualCount; for (i = 0; i < count; i++) - pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL); + pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc); if (pointer_buffer_mark_set) { @@ -3541,7 +4050,7 @@ ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, count = pStubMsg->ActualCount; for (i = 0; i < count; i++) - ComplexStructMemorySize(pStubMsg, pFormat); + ComplexStructMemorySize(pStubMsg, pFormat, NULL); pStubMsg->MemorySize = SavedMemorySize; @@ -4040,7 +4549,6 @@ void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg, { const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; PFORMAT_STRING pCArrayFormat; - ULONG esize; TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -4060,7 +4568,6 @@ void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg, RpcRaiseException(RPC_S_INTERNAL_ERROR); return; } - esize = *(const WORD*)(pCArrayFormat+2); ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat + 4, 0); @@ -4083,7 +4590,6 @@ unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pS { const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; PFORMAT_STRING pCVArrayFormat; - ULONG esize, bufsize; TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -4097,43 +4603,10 @@ unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pS pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + pCVStructFormat->offset_to_array_description; - switch (*pCVArrayFormat) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 4, 0); - pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat, 0); - break; - case RPC_FC_C_CSTRING: - TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - case RPC_FC_C_WSTRING: - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - WriteConformance(pStubMsg); + array_compute_and_write_conformance(*pCVArrayFormat, pStubMsg, + pMemory + pCVStructFormat->memory_size, + pCVArrayFormat); ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1); @@ -4143,12 +4616,9 @@ unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pS pStubMsg->BufferMark = pStubMsg->Buffer; safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size); - WriteVariance(pStubMsg); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* write array part */ - safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize); + array_write_variance_and_marshall(*pCVArrayFormat, pStubMsg, + pMemory + pCVStructFormat->memory_size, + pCVArrayFormat, FALSE /* fHasPointers */); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); @@ -4165,8 +4635,10 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE { const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; PFORMAT_STRING pCVArrayFormat; - ULONG esize, bufsize; - unsigned char cvarray_type; + ULONG memsize, bufsize; + unsigned char *saved_buffer, *saved_array_buffer; + ULONG offset; + unsigned char *array_memory; TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -4180,32 +4652,9 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + pCVStructFormat->offset_to_array_description; - cvarray_type = *pCVArrayFormat; - switch (cvarray_type) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4); - break; - case RPC_FC_C_CSTRING: - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - case RPC_FC_C_WSTRING: - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } + + memsize = array_read_conformance(*pCVArrayFormat, pStubMsg, + pCVArrayFormat); ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1); @@ -4214,49 +4663,42 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE /* work out how much memory to allocate if we need to do so */ if (!*ppMemory || fMustAlloc) { - SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount); + SIZE_T size = pCVStructFormat->memory_size + memsize; *ppMemory = NdrAllocate(pStubMsg, size); } + /* mark the start of the constant data */ + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); + + array_memory = *ppMemory + pCVStructFormat->memory_size; + bufsize = array_read_variance_and_unmarshall(*pCVArrayFormat, pStubMsg, + &array_memory, pCVArrayFormat, + FALSE /* fMustAlloc */, + FALSE /* fUseServerBufferMemory */, + FALSE /* fUnmarshall */); + + /* save offset in case unmarshalling pointers changes it */ + offset = pStubMsg->Offset; + + /* mark the start of the array data */ + saved_array_buffer = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); + + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + /* copy the constant data */ - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size); - - pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - if ((cvarray_type == RPC_FC_C_CSTRING) || - (cvarray_type == RPC_FC_C_WSTRING)) - { - ULONG i; - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - } - + memcpy(*ppMemory, saved_buffer, pCVStructFormat->memory_size); /* copy the array data */ - safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize); + TRACE("copying %p to %p\n", saved_array_buffer, *ppMemory + pCVStructFormat->memory_size); + memcpy(*ppMemory + pCVStructFormat->memory_size + offset, + saved_array_buffer, bufsize); - if (cvarray_type == RPC_FC_C_CSTRING) + if (*pCVArrayFormat == RPC_FC_C_CSTRING) TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); - else if (cvarray_type == RPC_FC_C_WSTRING) + else if (*pCVArrayFormat == RPC_FC_C_WSTRING) TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size))); - EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */); - return NULL; } @@ -4269,7 +4711,6 @@ void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, { const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; PFORMAT_STRING pCVArrayFormat; - ULONG esize; TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -4283,51 +4724,19 @@ void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + pCVStructFormat->offset_to_array_description; - switch (*pCVArrayFormat) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 4, 0); - pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat, 0); - break; - case RPC_FC_C_CSTRING: - TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - case RPC_FC_C_WSTRING: - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - SizeConformance(pStubMsg); + array_compute_and_size_conformance(*pCVArrayFormat, pStubMsg, + pMemory + pCVStructFormat->memory_size, + pCVArrayFormat); ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1); TRACE("memory_size = %d\n", pCVStructFormat->memory_size); safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size); - SizeVariance(pStubMsg); - safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); + + array_buffer_size(*pCVArrayFormat, pStubMsg, + pMemory + pCVStructFormat->memory_size, pCVArrayFormat, + FALSE /* fHasPointers */); EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } @@ -4340,8 +4749,6 @@ ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, { const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; PFORMAT_STRING pCVArrayFormat; - ULONG esize; - unsigned char cvarray_type; TRACE("(%p, %p)\n", pStubMsg, pFormat); @@ -4355,46 +4762,21 @@ ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + pCVStructFormat->offset_to_array_description; - cvarray_type = *pCVArrayFormat; - switch (cvarray_type) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4); - break; - case RPC_FC_C_CSTRING: - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - case RPC_FC_C_WSTRING: - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } + array_read_conformance(*pCVArrayFormat, pStubMsg, pCVArrayFormat); ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1); TRACE("memory_size = %d\n", pCVStructFormat->memory_size); safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); - pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); - safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); + array_memory_size(*pCVArrayFormat, pStubMsg, pCVArrayFormat, + FALSE /* fHasPointers */); - pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount); + pStubMsg->MemorySize += pCVStructFormat->memory_size; EmbeddedPointerMemorySize(pStubMsg, pFormat); - return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize; + return pStubMsg->MemorySize; } /*********************************************************************** @@ -4406,7 +4788,6 @@ void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg, { const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; PFORMAT_STRING pCVArrayFormat; - ULONG esize; TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -4420,41 +4801,9 @@ void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg, pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + pCVStructFormat->offset_to_array_description; - switch (*pCVArrayFormat) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 4, 0); - pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat, 0); - break; - case RPC_FC_C_CSTRING: - TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - case RPC_FC_C_WSTRING: - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } + array_free(*pCVArrayFormat, pStubMsg, + pMemory + pCVStructFormat->memory_size, pCVArrayFormat, + FALSE /* fHasPointers */); TRACE("memory_size = %d\n", pCVStructFormat->memory_size); @@ -4928,7 +5277,6 @@ void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - unsigned char alignment; DWORD elements; TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -4941,8 +5289,6 @@ void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, return; } - alignment = pFormat[1] + 1; - if (pFormat[0] == RPC_FC_SMVARRAY) { pFormat += 2; @@ -5444,7 +5790,7 @@ void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, pMemory += increment; - return union_arm_free(pStubMsg, pMemory, switch_value, pFormat); + union_arm_free(pStubMsg, pMemory, switch_value, pFormat); } /*********************************************************************** @@ -5599,7 +5945,7 @@ void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); - return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); + union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); } /*********************************************************************** @@ -5708,16 +6054,6 @@ void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg, FIXME("stub\n"); } -#include "pshpack1.h" -typedef struct -{ - unsigned char type; - unsigned char flags_type; /* flags in upper nibble, type in lower nibble */ - ULONG low_value; - ULONG high_value; -} NDR_RANGE; -#include "poppack.h" - /*********************************************************************** * NdrRangeMarshall [internal] */ @@ -5980,15 +6316,15 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall( { \ *ppMemory = pStubMsg->Buffer; \ TRACE("*ppMemory: %p\n", *ppMemory); \ + safe_buffer_increment(pStubMsg, sizeof(type)); \ } \ else \ { \ if (fMustAlloc) \ *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ TRACE("*ppMemory: %p\n", *ppMemory); \ - **(type **)ppMemory = *(type *)pStubMsg->Buffer; \ - } \ - pStubMsg->Buffer += sizeof(type); + safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \ + } switch(*pFormat) { diff --git a/reactos/dll/win32/rpcrt4/ndr_ole.c b/reactos/dll/win32/rpcrt4/ndr_ole.c index edfc78c95d0..9bfab956d0e 100644 --- a/reactos/dll/win32/rpcrt4/ndr_ole.c +++ b/reactos/dll/win32/rpcrt4/ndr_ole.c @@ -79,7 +79,7 @@ static HMODULE LoadCOM(void) typedef struct RpcStreamImpl { const IStreamVtbl *lpVtbl; - DWORD RefCount; + LONG RefCount; PMIDL_STUB_MESSAGE pMsg; LPDWORD size; unsigned char *data; @@ -95,7 +95,7 @@ static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface, IsEqualGUID(&IID_ISequentialStream, riid) || IsEqualGUID(&IID_IStream, riid)) { *obj = This; - This->RefCount++; + InterlockedIncrement( &This->RefCount ); return S_OK; } return E_NOINTERFACE; @@ -104,19 +104,20 @@ static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface, static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface) { RpcStreamImpl *This = (RpcStreamImpl *)iface; - return ++(This->RefCount); + return InterlockedIncrement( &This->RefCount ); } static ULONG WINAPI RpcStream_Release(LPSTREAM iface) { RpcStreamImpl *This = (RpcStreamImpl *)iface; - if (!--(This->RefCount)) { + ULONG ref = InterlockedDecrement( &This->RefCount ); + if (!ref) { TRACE("size=%d\n", *This->size); This->pMsg->Buffer = This->data + *This->size; HeapFree(GetProcessHeap(),0,This); return 0; } - return This->RefCount; + return ref; } static HRESULT WINAPI RpcStream_Read(LPSTREAM iface, diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.c b/reactos/dll/win32/rpcrt4/ndr_stubless.c index af06fb8c302..275502a7e6d 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.c +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.c @@ -91,29 +91,6 @@ static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemor if (m) m(pStubMsg, pMemory, pFormat); } -static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) -{ - NDR_MEMORYSIZE m = NdrMemorySizer[pFormat[0] & NDR_TABLE_MASK]; - if (m) - { - unsigned char *saved_buffer = pStubMsg->Buffer; - unsigned long ret; - int saved_ignore_embedded_pointers = pStubMsg->IgnoreEmbeddedPointers; - pStubMsg->MemorySize = 0; - pStubMsg->IgnoreEmbeddedPointers = 1; - ret = m(pStubMsg, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded_pointers; - pStubMsg->Buffer = saved_buffer; - return ret; - } - else - { - FIXME("format type 0x%x not implemented\n", pFormat[0]); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return 0; - } -} - #define STUBLESS_UNMARSHAL 1 #define STUBLESS_INITOUT 2 #define STUBLESS_CALLSERVER 3 @@ -159,7 +136,7 @@ static void WINAPI dump_INTERPRETER_OPT_FLAGS(INTERPRETER_OPT_FLAGS Oi2Flags) TRACE("\n"); } -#define ARG_FROM_OFFSET(stubMsg, offset) ((stubMsg).StackTop + (offset)) +#define ARG_FROM_OFFSET(args, offset) ((args) + (offset)) static PFORMAT_STRING client_get_handle( PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader, @@ -179,9 +156,9 @@ static PFORMAT_STRING client_get_handle( TRACE("Explicit primitive handle @ %d\n", pDesc->offset); if (pDesc->flag) /* pointer to binding */ - *phBinding = **(handle_t **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + *phBinding = **(handle_t **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - *phBinding = *(handle_t *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + *phBinding = *(handle_t *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); return pFormat + sizeof(NDR_EHD_PRIMITIVE); } case RPC_FC_BIND_GENERIC: /* explicit generic */ @@ -194,9 +171,9 @@ static PFORMAT_STRING client_get_handle( TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index); if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) - pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; *phBinding = pGenPair->pfnBind(pObject); @@ -210,10 +187,10 @@ static PFORMAT_STRING client_get_handle( if (pDesc->flags & HANDLE_PARAM_IS_VIA_PTR) { TRACE("\tHANDLE_PARAM_IS_VIA_PTR\n"); - context_handle = **(NDR_CCONTEXT **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + context_handle = **(NDR_CCONTEXT **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); } else - context_handle = *(NDR_CCONTEXT *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + context_handle = *(NDR_CCONTEXT *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); if ((pDesc->flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL) && !context_handle) { @@ -277,9 +254,9 @@ static void client_free_handle( TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index); if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) - pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; pGenPair->pfnUnbind(pObject, hBinding); @@ -308,7 +285,8 @@ static void client_free_handle( } static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, - int phase, unsigned short number_of_params, unsigned char *pRetVal) + int phase, unsigned char *args, unsigned short number_of_params, + unsigned char *pRetVal) { /* current format string offset */ int current_offset = 0; @@ -324,7 +302,7 @@ static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char * pArg; current_stack_offset = pParam->stack_offset; - pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset); + pArg = ARG_FROM_OFFSET(args, current_stack_offset); TRACE("param[%d]: new format\n", i); TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); @@ -426,9 +404,44 @@ static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, } } -static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat, int phase, unsigned short stack_size, - unsigned char *pRetVal, BOOL object_proc) +static unsigned int type_stack_size(unsigned char fc) +{ + switch (fc) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + return sizeof(char); + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + return sizeof(short); + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + return sizeof(int); + case RPC_FC_FLOAT: + return sizeof(float); + case RPC_FC_DOUBLE: + return sizeof(double); + case RPC_FC_HYPER: + return sizeof(ULONGLONG); + case RPC_FC_ERROR_STATUS_T: + return sizeof(error_status_t); + case RPC_FC_IGNORE: + return sizeof(void *); + default: + ERR("invalid base type 0x%x\n", fc); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } +} + +void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat, int phase, unsigned char *args, + unsigned short stack_size, + unsigned char *pRetVal, BOOL object_proc, BOOL ignore_retval) { /* current format string offset */ int current_offset = 0; @@ -437,7 +450,7 @@ static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, /* counter */ unsigned short i; - /* NOTE: V1 style format does't terminate on the number_of_params + /* NOTE: V1 style format doesn't terminate on the number_of_params * condition as it doesn't have this attribute. Instead it * terminates when the stack size given in the header is exceeded. */ @@ -449,7 +462,7 @@ static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, * if present, so adjust this */ unsigned short current_stack_offset_adjusted = current_stack_offset + (object_proc ? sizeof(void *) : 0); - unsigned char * pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset_adjusted); + unsigned char * pArg = ARG_FROM_OFFSET(args, current_stack_offset_adjusted); /* no more parameters; exit loop */ if (current_stack_offset_adjusted >= stack_size) @@ -479,10 +492,11 @@ static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, call_marshaller(pStubMsg, pArg, pTypeFormat); break; case PROXY_UNMARSHAL: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + if (!ignore_retval && + pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) { if (pParam->param_direction & RPC_FC_RETURN_PARAM) - call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); + call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0); else call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); } @@ -491,7 +505,7 @@ static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, RpcRaiseException(RPC_S_INTERNAL_ERROR); } - current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); + current_stack_offset += type_stack_size(*pTypeFormat); current_offset += sizeof(NDR_PARAM_OI_BASETYPE); } else @@ -705,12 +719,12 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma case PROXY_MARSHAL: case PROXY_UNMARSHAL: if (bV2Format) - client_do_args(&stubMsg, pFormat, phase, number_of_params, - (unsigned char *)&RetVal); + client_do_args(&stubMsg, pFormat, phase, stubMsg.StackTop, + number_of_params, (unsigned char *)&RetVal); else - client_do_args_old_format(&stubMsg, pFormat, phase, stack_size, - (unsigned char *)&RetVal, - (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); + client_do_args_old_format(&stubMsg, pFormat, phase, + stubMsg.StackTop, stack_size, (unsigned char *)&RetVal, + (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE); break; default: ERR("shouldn't reach here. phase %d\n", phase); @@ -718,7 +732,7 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma } } } - __EXCEPT(NULL) + __EXCEPT_ALL { RetVal = NdrProxyErrorHandler(GetExceptionCode()); } @@ -783,12 +797,12 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma case PROXY_MARSHAL: case PROXY_UNMARSHAL: if (bV2Format) - client_do_args(&stubMsg, pFormat, phase, number_of_params, - (unsigned char *)&RetVal); + client_do_args(&stubMsg, pFormat, phase, stubMsg.StackTop, + number_of_params, (unsigned char *)&RetVal); else - client_do_args_old_format(&stubMsg, pFormat, phase, stack_size, - (unsigned char *)&RetVal, - (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); + client_do_args_old_format(&stubMsg, pFormat, phase, + stubMsg.StackTop, stack_size, (unsigned char *)&RetVal, + (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE); break; default: ERR("shouldn't reach here. phase %d\n", phase); @@ -826,7 +840,7 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma return RetVal; } -/* calls a function with the specificed arguments, restoring the stack +/* Calls a function with the specified arguments, restoring the stack * properly afterwards as we don't know the calling convention of the * function */ #if defined __i386__ && defined _MSC_VER @@ -1160,7 +1174,7 @@ static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg, RpcRaiseException(RPC_S_INTERNAL_ERROR); } - current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); + current_stack_offset += type_stack_size(*pTypeFormat); current_offset += sizeof(NDR_PARAM_OI_BASETYPE); } else @@ -1464,9 +1478,7 @@ LONG WINAPI NdrStubCall2( Status = I_RpcGetBuffer(pRpcMsg); if (Status) RpcRaiseException(Status); - stubMsg.BufferStart = pRpcMsg->Buffer; - stubMsg.BufferEnd = stubMsg.BufferStart + stubMsg.BufferLength; - stubMsg.Buffer = stubMsg.BufferStart; + stubMsg.Buffer = pRpcMsg->Buffer; } break; case STUBLESS_UNMARSHAL: diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.h b/reactos/dll/win32/rpcrt4/ndr_stubless.h index 02850d196cf..9a6fb444783 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.h +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.h @@ -23,7 +23,6 @@ /* there can't be any alignment with the structures in this file */ #include "pshpack1.h" -/* From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/parameter_descriptors.asp */ typedef struct _NDR_PROC_HEADER { /* type of handle to use: @@ -36,7 +35,7 @@ typedef struct _NDR_PROC_HEADER * RPC_FC_BIND_PRIMITIVE = 32 - Implicit handle using handle_t created by * calling application * RPC_FC_AUTO_HANDLE = 33 - Automatic handle - * RPC_FC_CALLBACK_HANDLE = 34 - undocmented + * RPC_FC_CALLBACK_HANDLE = 34 - undocumented */ unsigned char handle_type; @@ -236,3 +235,8 @@ typedef struct _NDR_EHD_CONTEXT } NDR_EHD_CONTEXT; #include "poppack.h" + +void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat, int phase, unsigned char *args, + unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc, + BOOL ignore_retval); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.c b/reactos/dll/win32/rpcrt4/rpc_assoc.c index 6075278c4a4..e8f367659d7 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.c +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.c @@ -222,6 +222,8 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * RpcPktHdr *response_hdr; RPC_MESSAGE msg; RPC_STATUS status; + unsigned char *auth_data = NULL; + unsigned long auth_length; TRACE("sending bind request to server\n"); @@ -235,10 +237,10 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * if (status != RPC_S_OK) return status; - status = RPCRT4_Receive(conn, &response_hdr, &msg); + status = RPCRT4_ReceiveWithAuth(conn, &response_hdr, &msg, &auth_data, &auth_length); if (status != RPC_S_OK) { - ERR("receive failed\n"); + ERR("receive failed with error %ld\n", status); return status; } @@ -259,9 +261,17 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * switch (results->results[0].result) { case RESULT_ACCEPT: - conn->assoc_group_id = response_hdr->bind_ack.assoc_gid; - conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize; - conn->ActiveInterface = *InterfaceId; + /* respond to authorization request */ + if (auth_length > sizeof(RpcAuthVerifier)) + status = RPCRT4_AuthorizeConnection(conn, + auth_data + sizeof(RpcAuthVerifier), + auth_length); + if (status == RPC_S_OK) + { + conn->assoc_group_id = response_hdr->bind_ack.assoc_gid; + conn->MaxTransmissionSize = response_hdr->bind_ack.max_tsize; + conn->ActiveInterface = *InterfaceId; + } break; case RESULT_PROVIDER_REJECTION: switch (results->results[0].reason) @@ -334,6 +344,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * I_RpcFree(msg.Buffer); RPCRT4_FreeHeader(response_hdr); + HeapFree(GetProcessHeap(), 0, auth_data); return status; } diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.c b/reactos/dll/win32/rpcrt4/rpc_binding.c index 24769e2ce60..6a17a8c31ea 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.c +++ b/reactos/dll/win32/rpcrt4/rpc_binding.c @@ -157,20 +157,19 @@ static RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPCSTR NetworkAdd RPCRT4_strfree(Binding->NetworkAddr); Binding->NetworkAddr = RPCRT4_strdupA(NetworkAddr); RPCRT4_strfree(Binding->Endpoint); - if (Endpoint) { - Binding->Endpoint = RPCRT4_strdupA(Endpoint); - } else { - Binding->Endpoint = RPCRT4_strdupA(""); - } + Binding->Endpoint = RPCRT4_strdupA(Endpoint); HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); Binding->NetworkOptions = RPCRT4_strdupAtoW(NetworkOptions); - if (!Binding->Endpoint) ERR("out of memory?\n"); - status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, - Binding->Endpoint, Binding->NetworkOptions, - &Binding->Assoc); - if (status != RPC_S_OK) - return status; + /* only attempt to get an association if the binding is complete */ + if (Endpoint && Endpoint[0] != '\0') + { + status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, + Binding->Endpoint, Binding->NetworkOptions, + &Binding->Assoc); + if (status != RPC_S_OK) + return status; + } return RPC_S_OK; } @@ -186,20 +185,19 @@ static RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPCWSTR NetworkAd RPCRT4_strfree(Binding->NetworkAddr); Binding->NetworkAddr = RPCRT4_strdupWtoA(NetworkAddr); RPCRT4_strfree(Binding->Endpoint); - if (Endpoint) { - Binding->Endpoint = RPCRT4_strdupWtoA(Endpoint); - } else { - Binding->Endpoint = RPCRT4_strdupA(""); - } - if (!Binding->Endpoint) ERR("out of memory?\n"); + Binding->Endpoint = RPCRT4_strdupWtoA(Endpoint); HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); Binding->NetworkOptions = RPCRT4_strdupW(NetworkOptions); - status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, - Binding->Endpoint, Binding->NetworkOptions, - &Binding->Assoc); - if (status != RPC_S_OK) - return status; + /* only attempt to get an association if the binding is complete */ + if (Endpoint && Endpoint[0] != '\0') + { + status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, + Binding->Endpoint, Binding->NetworkOptions, + &Binding->Assoc); + if (status != RPC_S_OK) + return status; + } return RPC_S_OK; } @@ -213,7 +211,7 @@ RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint) RPCRT4_strfree(Binding->Endpoint); Binding->Endpoint = RPCRT4_strdupA(Endpoint); - RpcAssoc_Release(Binding->Assoc); + if (Binding->Assoc) RpcAssoc_Release(Binding->Assoc); Binding->Assoc = NULL; status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, Binding->Endpoint, Binding->NetworkOptions, @@ -227,7 +225,7 @@ RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint) RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid) { TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding, debugstr_guid(ObjectUuid)); - if (ObjectUuid) memcpy(&Binding->ObjectUuid, ObjectUuid, sizeof(UUID)); + if (ObjectUuid) Binding->ObjectUuid = *ObjectUuid; else UuidCreateNil(&Binding->ObjectUuid); return RPC_S_OK; } @@ -249,14 +247,12 @@ RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) return RPC_S_OK; } -RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding) +void RPCRT4_AddRefBinding(RpcBinding* Binding) { - InterlockedIncrement(&OldBinding->refs); - *Binding = OldBinding; - return RPC_S_OK; + InterlockedIncrement(&Binding->refs); } -RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding) +RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding) { if (InterlockedDecrement(&Binding->refs)) return RPC_S_OK; @@ -310,21 +306,6 @@ RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) } } -/* utility functions for string composing and parsing */ -static unsigned RPCRT4_strcopyA(LPSTR data, LPCSTR src) -{ - unsigned len = strlen(src); - memcpy(data, src, len*sizeof(CHAR)); - return len; -} - -static unsigned RPCRT4_strcopyW(LPWSTR data, LPCWSTR src) -{ - unsigned len = strlenW(src); - memcpy(data, src, len*sizeof(WCHAR)); - return len; -} - static LPSTR RPCRT4_strconcatA(LPSTR dst, LPCSTR src) { DWORD len = strlen(dst), slen = strlen(src); @@ -353,6 +334,123 @@ static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src) return ndst; } +/* Copies the escaped version of a component into a string binding. + * Note: doesn't nul-terminate the string */ +static RPC_CSTR escape_string_binding_component(RPC_CSTR string_binding, + const unsigned char *component) +{ + for (; *component; component++) { + switch (*component) { + case '@': + case ':': + case '[': + case ']': + case '\\': + *string_binding++ = '\\'; + *string_binding++ = *component; + break; + default: + *string_binding++ = *component; + break; + } + } + return string_binding; +} + +static RPC_WSTR escape_string_binding_componentW(RPC_WSTR string_binding, + const WCHAR *component) +{ + for (; *component; component++) { + switch (*component) { + case '@': + case ':': + case '[': + case ']': + case '\\': + *string_binding++ = '\\'; + *string_binding++ = *component; + break; + default: + *string_binding++ = *component; + break; + } + } + return string_binding; +} + +static const unsigned char *string_binding_find_delimiter( + const unsigned char *string_binding, unsigned char delim) +{ + const unsigned char *next; + for (next = string_binding; *next; next++) { + if (*next == '\\') { + next++; + continue; + } + if (*next == delim) + return next; + } + return NULL; +} + +static const WCHAR *string_binding_find_delimiterW( + const WCHAR *string_binding, WCHAR delim) +{ + const WCHAR *next; + for (next = string_binding; *next; next++) { + if (*next == '\\') { + next++; + continue; + } + if (*next == delim) + return next; + } + return NULL; +} + +static RPC_CSTR unescape_string_binding_component( + const unsigned char *string_binding, int len) +{ + RPC_CSTR component, p; + + if (len == -1) len = strlen((const char *)string_binding); + + component = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(*component)); + if (!component) return NULL; + for (p = component; len > 0; string_binding++, len--) { + if (*string_binding == '\\') { + string_binding++; + len--; + *p++ = *string_binding; + } else { + *p++ = *string_binding; + } + } + *p = '\0'; + return component; +} + +static RPC_WSTR unescape_string_binding_componentW( + const WCHAR *string_binding, int len) +{ + RPC_WSTR component, p; + + if (len == -1) len = strlen((const char *)string_binding); + + component = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(*component)); + if (!component) return NULL; + for (p = component; len > 0; string_binding++, len--) { + if (*string_binding == '\\') { + string_binding++; + len--; + *p++ = *string_binding; + } else { + *p++ = *string_binding; + } + } + *p = '\0'; + return component; +} /*********************************************************************** * RpcStringBindingComposeA (RPCRT4.@) @@ -362,42 +460,43 @@ RPC_STATUS WINAPI RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, RPC_CSTR Options, RPC_CSTR *StringBinding ) { DWORD len = 1; - LPSTR data; + RPC_CSTR data; TRACE( "(%s,%s,%s,%s,%s,%p)\n", debugstr_a( (char*)ObjUuid ), debugstr_a( (char*)Protseq ), debugstr_a( (char*)NetworkAddr ), debugstr_a( (char*)Endpoint ), debugstr_a( (char*)Options ), StringBinding ); - if (ObjUuid && *ObjUuid) len += strlen((char*)ObjUuid) + 1; - if (Protseq && *Protseq) len += strlen((char*)Protseq) + 1; - if (NetworkAddr && *NetworkAddr) len += strlen((char*)NetworkAddr); - if (Endpoint && *Endpoint) len += strlen((char*)Endpoint) + 2; - if (Options && *Options) len += strlen((char*)Options) + 2; + /* overestimate for each component for escaping of delimiters */ + if (ObjUuid && *ObjUuid) len += strlen((char*)ObjUuid) * 2 + 1; + if (Protseq && *Protseq) len += strlen((char*)Protseq) * 2 + 1; + if (NetworkAddr && *NetworkAddr) len += strlen((char*)NetworkAddr) * 2; + if (Endpoint && *Endpoint) len += strlen((char*)Endpoint) * 2 + 2; + if (Options && *Options) len += strlen((char*)Options) * 2 + 2; data = HeapAlloc(GetProcessHeap(), 0, len); - *StringBinding = (unsigned char*)data; + *StringBinding = data; if (ObjUuid && *ObjUuid) { - data += RPCRT4_strcopyA(data, (char*)ObjUuid); + data = escape_string_binding_component(data, ObjUuid); *data++ = '@'; } if (Protseq && *Protseq) { - data += RPCRT4_strcopyA(data, (char*)Protseq); + data = escape_string_binding_component(data, Protseq); *data++ = ':'; } if (NetworkAddr && *NetworkAddr) - data += RPCRT4_strcopyA(data, (char*)NetworkAddr); + data = escape_string_binding_component(data, NetworkAddr); if ((Endpoint && *Endpoint) || (Options && *Options)) { *data++ = '['; if (Endpoint && *Endpoint) { - data += RPCRT4_strcopyA(data, (char*)Endpoint); + data = escape_string_binding_component(data, Endpoint); if (Options && *Options) *data++ = ','; } if (Options && *Options) { - data += RPCRT4_strcopyA(data, (char*)Options); + data = escape_string_binding_component(data, Options); } *data++ = ']'; } @@ -421,35 +520,36 @@ RPC_STATUS WINAPI RpcStringBindingComposeW( RPC_WSTR ObjUuid, RPC_WSTR Protseq, debugstr_w( NetworkAddr ), debugstr_w( Endpoint ), debugstr_w( Options ), StringBinding); - if (ObjUuid && *ObjUuid) len += strlenW(ObjUuid) + 1; - if (Protseq && *Protseq) len += strlenW(Protseq) + 1; - if (NetworkAddr && *NetworkAddr) len += strlenW(NetworkAddr); - if (Endpoint && *Endpoint) len += strlenW(Endpoint) + 2; - if (Options && *Options) len += strlenW(Options) + 2; + /* overestimate for each component for escaping of delimiters */ + if (ObjUuid && *ObjUuid) len += strlenW(ObjUuid) * 2 + 1; + if (Protseq && *Protseq) len += strlenW(Protseq) * 2 + 1; + if (NetworkAddr && *NetworkAddr) len += strlenW(NetworkAddr) * 2; + if (Endpoint && *Endpoint) len += strlenW(Endpoint) * 2 + 2; + if (Options && *Options) len += strlenW(Options) * 2 + 2; data = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); *StringBinding = data; if (ObjUuid && *ObjUuid) { - data += RPCRT4_strcopyW(data, ObjUuid); + data = escape_string_binding_componentW(data, ObjUuid); *data++ = '@'; } if (Protseq && *Protseq) { - data += RPCRT4_strcopyW(data, Protseq); + data = escape_string_binding_componentW(data, Protseq); *data++ = ':'; } if (NetworkAddr && *NetworkAddr) { - data += RPCRT4_strcopyW(data, NetworkAddr); + data = escape_string_binding_componentW(data, NetworkAddr); } if ((Endpoint && *Endpoint) || (Options && *Options)) { *data++ = '['; if (Endpoint && *Endpoint) { - data += RPCRT4_strcopyW(data, Endpoint); + data = escape_string_binding_componentW(data, Endpoint); if (Options && *Options) *data++ = ','; } if (Options && *Options) { - data += RPCRT4_strcopyW(data, Options); + data = escape_string_binding_componentW(data, Options); } *data++ = ']'; } @@ -466,8 +566,9 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU RPC_CSTR *Protseq, RPC_CSTR *NetworkAddr, RPC_CSTR *Endpoint, RPC_CSTR *Options) { - CHAR *data, *next; + const unsigned char *data, *next; static const char ep_opt[] = "endpoint="; + BOOL endpoint_already_found = FALSE; TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding), ObjUuid, Protseq, NetworkAddr, Endpoint, Options); @@ -478,57 +579,75 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU if (Endpoint) *Endpoint = NULL; if (Options) *Options = NULL; - data = (char*) StringBinding; + data = StringBinding; - next = strchr(data, '@'); + next = string_binding_find_delimiter(data, '@'); if (next) { - if (ObjUuid) *ObjUuid = (unsigned char*)RPCRT4_strndupA(data, next - data); + UUID uuid; + RPC_STATUS status; + RPC_CSTR str_uuid = unescape_string_binding_component(data, next - data); + status = UuidFromStringA(str_uuid, &uuid); + if (status != RPC_S_OK) { + HeapFree(GetProcessHeap(), 0, str_uuid); + return status; + } + if (ObjUuid) + *ObjUuid = str_uuid; + else + HeapFree(GetProcessHeap(), 0, str_uuid); data = next+1; } - next = strchr(data, ':'); + next = string_binding_find_delimiter(data, ':'); if (next) { - if (Protseq) *Protseq = (unsigned char*)RPCRT4_strndupA(data, next - data); + if (Protseq) *Protseq = unescape_string_binding_component(data, next - data); data = next+1; } - next = strchr(data, '['); + next = string_binding_find_delimiter(data, '['); if (next) { - CHAR *close, *opt; + const unsigned char *close; + RPC_CSTR opt; - if (NetworkAddr) *NetworkAddr = (unsigned char*)RPCRT4_strndupA(data, next - data); + if (NetworkAddr) *NetworkAddr = unescape_string_binding_component(data, next - data); data = next+1; - close = strchr(data, ']'); + close = string_binding_find_delimiter(data, ']'); if (!close) goto fail; /* tokenize options */ while (data < close) { - next = strchr(data, ','); + next = string_binding_find_delimiter(data, ','); if (!next || next > close) next = close; /* FIXME: this is kind of inefficient */ - opt = RPCRT4_strndupA(data, next - data); + opt = unescape_string_binding_component(data, next - data); data = next+1; /* parse option */ - next = strchr(opt, '='); + next = string_binding_find_delimiter(opt, '='); if (!next) { /* not an option, must be an endpoint */ - if (*Endpoint) goto fail; - *Endpoint = (unsigned char*) opt; + if (endpoint_already_found) goto fail; + if (Endpoint) *Endpoint = opt; + else HeapFree(GetProcessHeap(), 0, opt); + endpoint_already_found = TRUE; } else { - if (strncmp(opt, ep_opt, strlen(ep_opt)) == 0) { + if (strncmp((const char *)opt, ep_opt, strlen(ep_opt)) == 0) { /* endpoint option */ - if (*Endpoint) goto fail; - *Endpoint = (unsigned char*) RPCRT4_strdupA(next+1); + if (endpoint_already_found) goto fail; + if (Endpoint) *Endpoint = unescape_string_binding_component(next+1, -1); HeapFree(GetProcessHeap(), 0, opt); + endpoint_already_found = TRUE; } else { /* network option */ - if (*Options) { - /* FIXME: this is kind of inefficient */ - *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt); + if (Options) { + if (*Options) { + /* FIXME: this is kind of inefficient */ + *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, (char *)opt); + HeapFree(GetProcessHeap(), 0, opt); + } else + *Options = opt; + } else HeapFree(GetProcessHeap(), 0, opt); - } else - *Options = (unsigned char*) opt; } } } @@ -537,7 +656,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU if (*data) goto fail; } else if (NetworkAddr) - *NetworkAddr = (unsigned char*)RPCRT4_strdupA(data); + *NetworkAddr = unescape_string_binding_component(data, -1); return RPC_S_OK; @@ -557,8 +676,9 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU RPC_WSTR *Protseq, RPC_WSTR *NetworkAddr, RPC_WSTR *Endpoint, RPC_WSTR *Options) { - WCHAR *data, *next; + const WCHAR *data, *next; static const WCHAR ep_opt[] = {'e','n','d','p','o','i','n','t','=',0}; + BOOL endpoint_already_found = FALSE; TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding), ObjUuid, Protseq, NetworkAddr, Endpoint, Options); @@ -571,55 +691,73 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU data = StringBinding; - next = strchrW(data, '@'); + next = string_binding_find_delimiterW(data, '@'); if (next) { - if (ObjUuid) *ObjUuid = RPCRT4_strndupW(data, next - data); + UUID uuid; + RPC_STATUS status; + RPC_WSTR str_uuid = unescape_string_binding_componentW(data, next - data); + status = UuidFromStringW(str_uuid, &uuid); + if (status != RPC_S_OK) { + HeapFree(GetProcessHeap(), 0, str_uuid); + return status; + } + if (ObjUuid) + *ObjUuid = str_uuid; + else + HeapFree(GetProcessHeap(), 0, str_uuid); data = next+1; } - next = strchrW(data, ':'); + next = string_binding_find_delimiterW(data, ':'); if (next) { - if (Protseq) *Protseq = RPCRT4_strndupW(data, next - data); + if (Protseq) *Protseq = unescape_string_binding_componentW(data, next - data); data = next+1; } - next = strchrW(data, '['); + next = string_binding_find_delimiterW(data, '['); if (next) { - WCHAR *close, *opt; + const WCHAR *close; + RPC_WSTR opt; - if (NetworkAddr) *NetworkAddr = RPCRT4_strndupW(data, next - data); + if (NetworkAddr) *NetworkAddr = unescape_string_binding_componentW(data, next - data); data = next+1; - close = strchrW(data, ']'); + close = string_binding_find_delimiterW(data, ']'); if (!close) goto fail; /* tokenize options */ while (data < close) { - next = strchrW(data, ','); + next = string_binding_find_delimiterW(data, ','); if (!next || next > close) next = close; /* FIXME: this is kind of inefficient */ - opt = RPCRT4_strndupW(data, next - data); + opt = unescape_string_binding_componentW(data, next - data); data = next+1; /* parse option */ - next = strchrW(opt, '='); + next = string_binding_find_delimiterW(opt, '='); if (!next) { /* not an option, must be an endpoint */ - if (*Endpoint) goto fail; - *Endpoint = opt; + if (endpoint_already_found) goto fail; + if (Endpoint) *Endpoint = opt; + else HeapFree(GetProcessHeap(), 0, opt); + endpoint_already_found = TRUE; } else { if (strncmpW(opt, ep_opt, strlenW(ep_opt)) == 0) { /* endpoint option */ - if (*Endpoint) goto fail; - *Endpoint = RPCRT4_strdupW(next+1); + if (endpoint_already_found) goto fail; + if (Endpoint) *Endpoint = unescape_string_binding_componentW(next+1, -1); HeapFree(GetProcessHeap(), 0, opt); + endpoint_already_found = TRUE; } else { /* network option */ - if (*Options) { - /* FIXME: this is kind of inefficient */ - *Options = RPCRT4_strconcatW(*Options, opt); + if (Options) { + if (*Options) { + /* FIXME: this is kind of inefficient */ + *Options = RPCRT4_strconcatW(*Options, opt); + HeapFree(GetProcessHeap(), 0, opt); + } else + *Options = opt; + } else HeapFree(GetProcessHeap(), 0, opt); - } else - *Options = opt; } } } @@ -627,7 +765,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjU data = close+1; if (*data) goto fail; } else if (NetworkAddr) - *NetworkAddr = RPCRT4_strdupW(data); + *NetworkAddr = unescape_string_binding_componentW(data, -1); return RPC_S_OK; @@ -647,7 +785,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) { RPC_STATUS status; TRACE("(%p) = %p\n", Binding, *Binding); - status = RPCRT4_DestroyBinding(*Binding); + status = RPCRT4_ReleaseBinding(*Binding); if (status == RPC_S_OK) *Binding = 0; return status; } @@ -677,10 +815,10 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU RpcBinding* bind = (RpcBinding*)Binding; TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid)); - memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID)); + *ObjectUuid = bind->ObjectUuid; return RPC_S_OK; } - + /*********************************************************************** * RpcBindingSetObject (RPCRT4.@) */ @@ -713,8 +851,8 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) ret = RPCRT4_CreateBindingA(&bind, FALSE, (char*)Protseq); - if (ret == RPC_S_OK) - ret = RPCRT4_SetBindingObject(bind, &Uuid); + if (ret != RPC_S_OK) return ret; + ret = RPCRT4_SetBindingObject(bind, &Uuid); if (ret == RPC_S_OK) ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options); @@ -727,7 +865,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; else - RPCRT4_DestroyBinding(bind); + RPCRT4_ReleaseBinding(bind); return ret; } @@ -752,8 +890,8 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) ret = RPCRT4_CreateBindingW(&bind, FALSE, Protseq); - if (ret == RPC_S_OK) - ret = RPCRT4_SetBindingObject(bind, &Uuid); + if (ret != RPC_S_OK) return ret; + ret = RPCRT4_SetBindingObject(bind, &Uuid); if (ret == RPC_S_OK) ret = RPCRT4_CompleteBindingW(bind, NetworkAddr, Endpoint, Options); @@ -766,7 +904,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; else - RPCRT4_DestroyBinding(bind); + RPCRT4_ReleaseBinding(bind); return ret; } @@ -782,8 +920,13 @@ RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CS TRACE("(%p,%p)\n", Binding, StringBinding); - ret = UuidToStringA(&bind->ObjectUuid, &ObjectUuid); - if (ret != RPC_S_OK) return ret; + if (UuidIsNil(&bind->ObjectUuid, &ret)) + ObjectUuid = NULL; + else + { + ret = UuidToStringA(&bind->ObjectUuid, &ObjectUuid); + if (ret != RPC_S_OK) return ret; + } ret = RpcStringBindingComposeA(ObjectUuid, (unsigned char*)bind->Protseq, (unsigned char*) bind->NetworkAddr, (unsigned char*) bind->Endpoint, NULL, StringBinding); @@ -807,6 +950,17 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS return ret; } +/*********************************************************************** + * I_RpcBindingInqTransportType (RPCRT4.@) + */ +RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsigned int * Type ) +{ + + FIXME( "(%p,%p): stub\n", Binding, Type); + *Type = TRANSPORT_TYPE_LPC; + return RPC_S_OK; +} + /*********************************************************************** * I_RpcBindingSetAsync (RPCRT4.@) * NOTES @@ -858,6 +1012,23 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy( return RPC_S_OK; } +/*********************************************************************** + * RpcBindingReset (RPCRT4.@) + */ +RPC_STATUS RPC_ENTRY RpcBindingReset(RPC_BINDING_HANDLE Binding) +{ + RpcBinding *bind = Binding; + + TRACE("(%p)\n", Binding); + + RPCRT4_strfree(bind->Endpoint); + bind->Endpoint = NULL; + if (bind->Assoc) RpcAssoc_Release(bind->Assoc); + bind->Assoc = NULL; + + return RPC_S_OK; +} + /*********************************************************************** * RpcImpersonateClient (RPCRT4.@) * @@ -937,6 +1108,7 @@ static RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc, AuthInfo->exp = exp; AuthInfo->cbMaxToken = cbMaxToken; AuthInfo->identity = identity; + AuthInfo->server_principal_name = NULL; /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to * enable better matching in RpcAuthInfo_IsEqual */ @@ -967,9 +1139,9 @@ static RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc, AuthInfo->nt_identity->Password = RPCRT4_strndupAtoW((const char *)nt_identity->Password, nt_identity->PasswordLength); AuthInfo->nt_identity->PasswordLength = nt_identity->PasswordLength; - if (!AuthInfo->nt_identity->User || - !AuthInfo->nt_identity->Domain || - !AuthInfo->nt_identity->Password) + if ((nt_identity->User && !AuthInfo->nt_identity->User) || + (nt_identity->Domain && !AuthInfo->nt_identity->Domain) || + (nt_identity->Password && !AuthInfo->nt_identity->Password)) { HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User); HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain); @@ -1004,6 +1176,7 @@ ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo) HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Password); HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity); } + HeapFree(GetProcessHeap(), 0, AuthInfo->server_principal_name); HeapFree(GetProcessHeap(), 0, AuthInfo); } @@ -1390,7 +1563,8 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, return RPC_S_UNKNOWN_AUTHN_LEVEL; } - if (AuthzSvr) + /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */ + if (AuthzSvr && AuthnSvc != RPC_C_AUTHN_WINNT) { FIXME("unsupported AuthzSvr %u\n", AuthzSvr); return RPC_S_UNKNOWN_AUTHZ_SERVICE; @@ -1415,19 +1589,32 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, } TRACE("found package %s for service %u\n", packages[i].Name, AuthnSvc); - r = AcquireCredentialsHandleA((SEC_CHAR *)ServerPrincName, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, + r = AcquireCredentialsHandleA(NULL, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, AuthIdentity, NULL, NULL, &cred, &exp); cbMaxToken = packages[i].cbMaxToken; FreeContextBuffer(packages); if (r == ERROR_SUCCESS) { - if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); - bind->AuthInfo = NULL; + RpcAuthInfo *new_auth_info; r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, cbMaxToken, - AuthIdentity, &bind->AuthInfo); - if (r != RPC_S_OK) + AuthIdentity, &new_auth_info); + if (r == RPC_S_OK) + { + new_auth_info->server_principal_name = RPCRT4_strdupAtoW((char *)ServerPrincName); + if (new_auth_info->server_principal_name) + { + if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); + bind->AuthInfo = new_auth_info; + } + else + { + RpcAuthInfo_Release(new_auth_info); + r = ERROR_OUTOFMEMORY; + } + } + else FreeCredentialsHandle(&cred); - return RPC_S_OK; + return r; } else { @@ -1506,7 +1693,8 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, return RPC_S_UNKNOWN_AUTHN_LEVEL; } - if (AuthzSvr) + /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */ + if (AuthzSvr && AuthnSvc != RPC_C_AUTHN_WINNT) { FIXME("unsupported AuthzSvr %u\n", AuthzSvr); return RPC_S_UNKNOWN_AUTHZ_SERVICE; @@ -1515,7 +1703,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, r = EnumerateSecurityPackagesW(&package_count, &packages); if (r != SEC_E_OK) { - ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r); + ERR("EnumerateSecurityPackagesW failed with error 0x%08x\n", r); return RPC_S_SEC_PKG_ERROR; } @@ -1531,23 +1719,36 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, } TRACE("found package %s for service %u\n", debugstr_w(packages[i].Name), AuthnSvc); - r = AcquireCredentialsHandleW((SEC_WCHAR *)ServerPrincName, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, + r = AcquireCredentialsHandleW(NULL, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, AuthIdentity, NULL, NULL, &cred, &exp); cbMaxToken = packages[i].cbMaxToken; FreeContextBuffer(packages); if (r == ERROR_SUCCESS) { - if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); - bind->AuthInfo = NULL; + RpcAuthInfo *new_auth_info; r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, cbMaxToken, - AuthIdentity, &bind->AuthInfo); - if (r != RPC_S_OK) + AuthIdentity, &new_auth_info); + if (r == RPC_S_OK) + { + new_auth_info->server_principal_name = RPCRT4_strdupW(ServerPrincName); + if (!ServerPrincName || new_auth_info->server_principal_name) + { + if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); + bind->AuthInfo = new_auth_info; + } + else + { + RpcAuthInfo_Release(new_auth_info); + r = ERROR_OUTOFMEMORY; + } + } + else FreeCredentialsHandle(&cred); - return RPC_S_OK; + return r; } else { - ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r); + ERR("AcquireCredentialsHandleW failed with error 0x%08x\n", r); return RPC_S_SEC_PKG_ERROR; } } @@ -1579,8 +1780,8 @@ RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, UL /*********************************************************************** * RpcBindingSetOption (RPCRT4.@) */ -RPC_STATUS WINAPI RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle, ULONG Option, ULONG OptionValue) +RPC_STATUS WINAPI RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle, ULONG Option, ULONG_PTR OptionValue) { - FIXME("(%p, %d, %d): stub\n", BindingHandle, Option, OptionValue); + FIXME("(%p, %d, %ld): stub\n", BindingHandle, Option, OptionValue); return RPC_S_OK; } diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.h b/reactos/dll/win32/rpcrt4/rpc_binding.h index e169a650e6e..3251df210c7 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.h +++ b/reactos/dll/win32/rpcrt4/rpc_binding.h @@ -145,8 +145,8 @@ RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* Old RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint); RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid); RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection); -RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding); -RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding); +void RPCRT4_AddRefBinding(RpcBinding* Binding); +RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding* Binding); RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId); RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection); diff --git a/reactos/dll/win32/rpcrt4/rpc_defs.h b/reactos/dll/win32/rpcrt4/rpc_defs.h index c0c3609f1cc..f552490ade7 100644 --- a/reactos/dll/win32/rpcrt4/rpc_defs.h +++ b/reactos/dll/win32/rpcrt4/rpc_defs.h @@ -22,8 +22,6 @@ #ifndef __WINE_RPC_DEFS_H #define __WINE_RPC_DEFS_H -/* info from http://www.microsoft.com/msj/0398/dcomtextfigs.htm */ - typedef struct { unsigned char rpc_ver; /* RPC major version (5) */ diff --git a/reactos/dll/win32/rpcrt4/rpc_message.c b/reactos/dll/win32/rpcrt4/rpc_message.c index 07af1fc4cec..48c7df0d085 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.c +++ b/reactos/dll/win32/rpcrt4/rpc_message.c @@ -27,6 +27,7 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" +#include "winuser.h" #include "rpc.h" #include "rpcndr.h" @@ -195,8 +196,8 @@ RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, header->bind.assoc_gid = AssocGroupId; header->bind.num_elements = 1; header->bind.num_syntaxes = 1; - memcpy(&header->bind.abstract, AbstractId, sizeof(RPC_SYNTAX_IDENTIFIER)); - memcpy(&header->bind.transfer, TransferId, sizeof(RPC_SYNTAX_IDENTIFIER)); + header->bind.abstract = *AbstractId; + header->bind.transfer = *TransferId; return header; } @@ -277,7 +278,7 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, results->results[0].result = Result; results->results[0].reason = Reason; transfer_id = (RPC_SYNTAX_IDENTIFIER*)(results + 1); - memcpy(transfer_id, TransferId, sizeof(RPC_SYNTAX_IDENTIFIER)); + *transfer_id = *TransferId; return header; } @@ -436,13 +437,13 @@ static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, } /*********************************************************************** - * RPCRT4_SendAuth (internal) + * RPCRT4_SendWithAuth (internal) * * Transmit a packet with authorization data over connection in acceptable fragments. */ -static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header, - void *Buffer, unsigned int BufferLength, - const void *Auth, unsigned int AuthLength) +static RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Header, + void *Buffer, unsigned int BufferLength, + const void *Auth, unsigned int AuthLength) { PUCHAR buffer_pos; DWORD hdr_size; @@ -580,10 +581,10 @@ static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in, inp_desc.pBuffers = in; inp_desc.ulVersion = 0; - r = InitializeSecurityContextA(&conn->AuthInfo->cred, in ? &conn->ctx : NULL, - NULL, context_req, 0, SECURITY_NETWORK_DREP, - in ? &inp_desc : NULL, 0, &conn->ctx, &out_desc, &conn->attr, - &conn->exp); + r = InitializeSecurityContextW(&conn->AuthInfo->cred, in ? &conn->ctx : NULL, + in ? NULL : conn->AuthInfo->server_principal_name, context_req, 0, + SECURITY_NETWORK_DREP, in ? &inp_desc : NULL, 0, &conn->ctx, + &out_desc, &conn->attr, &conn->exp); if (FAILED(r)) { WARN("InitializeSecurityContext failed with error 0x%08x\n", r); @@ -630,8 +631,8 @@ failed: /*********************************************************************** * RPCRT4_AuthorizeBinding (internal) */ -static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn, - BYTE *challenge, ULONG count) +RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, + ULONG count) { SecBuffer inp, out; RpcPktHdr *resp_hdr; @@ -650,7 +651,7 @@ static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn, if (!resp_hdr) return E_OUTOFMEMORY; - status = RPCRT4_SendAuth(conn, resp_hdr, NULL, 0, out.pvBuffer, out.cbBuffer); + status = RPCRT4_SendWithAuth(conn, resp_hdr, NULL, 0, out.pvBuffer, out.cbBuffer); HeapFree(GetProcessHeap(), 0, out.pvBuffer); RPCRT4_FreeHeader(resp_hdr); @@ -671,40 +672,65 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, if (!Connection->AuthInfo || SecIsValidHandle(&Connection->ctx)) { - return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0); + return RPCRT4_SendWithAuth(Connection, Header, Buffer, BufferLength, NULL, 0); } /* tack on a negotiate packet */ - RPCRT4_ClientAuthorize(Connection, NULL, &out); - r = RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, out.pvBuffer, out.cbBuffer); - HeapFree(GetProcessHeap(), 0, out.pvBuffer); + r = RPCRT4_ClientAuthorize(Connection, NULL, &out); + if (r == RPC_S_OK) + { + r = RPCRT4_SendWithAuth(Connection, Header, Buffer, BufferLength, out.pvBuffer, out.cbBuffer); + HeapFree(GetProcessHeap(), 0, out.pvBuffer); + } return r; } +/* validates version and frag_len fields */ +RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) +{ + DWORD hdr_length; + + /* verify if the header really makes sense */ + if (hdr->rpc_ver != RPC_VER_MAJOR || + hdr->rpc_ver_minor != RPC_VER_MINOR) + { + WARN("unhandled packet version\n"); + return RPC_S_PROTOCOL_ERROR; + } + + hdr_length = RPCRT4_GetHeaderSize((const RpcPktHdr*)hdr); + if (hdr_length == 0) + { + WARN("header length == 0\n"); + return RPC_S_PROTOCOL_ERROR; + } + + if (hdr->frag_len < hdr_length) + { + WARN("bad frag length %d\n", hdr->frag_len); + return RPC_S_PROTOCOL_ERROR; + } + + return RPC_S_OK; +} + /*********************************************************************** - * RPCRT4_Receive (internal) + * RPCRT4_receive_fragment (internal) * - * Receive a packet from connection and merge the fragments. + * Receive a fragment from a connection. */ -RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, - PRPC_MESSAGE pMsg) +RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) { RPC_STATUS status; DWORD hdr_length; LONG dwRead; - unsigned short first_flag; - unsigned long data_length; - unsigned long buffer_length; - unsigned long auth_length; - unsigned char *auth_data = NULL; RpcPktCommonHdr common_hdr; *Header = NULL; + *Payload = NULL; - TRACE("(%p, %p, %p)\n", Connection, Header, pMsg); - - RPCRT4_SetThreadCurrentConnection(Connection); + TRACE("(%p, %p, %p)\n", Connection, Header, Payload); /* read packet common header */ dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr)); @@ -714,13 +740,8 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, goto fail; } - /* verify if the header really makes sense */ - if (common_hdr.rpc_ver != RPC_VER_MAJOR || - common_hdr.rpc_ver_minor != RPC_VER_MINOR) { - WARN("unhandled packet version\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } + status = RPCRT4_ValidateCommonHeader(&common_hdr); + if (status != RPC_S_OK) goto fail; hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr); if (hdr_length == 0) { @@ -740,8 +761,74 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, goto fail; } + if (common_hdr.frag_len - hdr_length) + { + *Payload = HeapAlloc(GetProcessHeap(), 0, common_hdr.frag_len - hdr_length); + if (!*Payload) + { + status = RPC_S_OUT_OF_RESOURCES; + goto fail; + } + + dwRead = rpcrt4_conn_read(Connection, *Payload, common_hdr.frag_len - hdr_length); + if (dwRead != common_hdr.frag_len - hdr_length) + { + WARN("bad data length, %d/%d\n", dwRead, common_hdr.frag_len - hdr_length); + status = RPC_S_CALL_FAILED; + goto fail; + } + } + else + *Payload = NULL; + + /* success */ + status = RPC_S_OK; + +fail: + if (status != RPC_S_OK) { + RPCRT4_FreeHeader(*Header); + *Header = NULL; + HeapFree(GetProcessHeap(), 0, *Payload); + *Payload = NULL; + } + return status; +} + +/*********************************************************************** + * RPCRT4_ReceiveWithAuth (internal) + * + * Receive a packet from connection, merge the fragments and return the auth + * data. + */ +RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, + PRPC_MESSAGE pMsg, + unsigned char **auth_data_out, + unsigned long *auth_length_out) +{ + RPC_STATUS status; + DWORD hdr_length; + unsigned short first_flag; + unsigned long data_length; + unsigned long buffer_length; + unsigned long auth_length = 0; + unsigned char *auth_data = NULL; + RpcPktHdr *CurrentHeader = NULL; + void *payload = NULL; + + *Header = NULL; + pMsg->Buffer = NULL; + + TRACE("(%p, %p, %p, %p)\n", Connection, Header, pMsg, auth_data_out); + + RPCRT4_SetThreadCurrentConnection(Connection); + + status = RPCRT4_receive_fragment(Connection, Header, &payload); + if (status != RPC_S_OK) goto fail; + + hdr_length = RPCRT4_GetHeaderSize(*Header); + /* read packet body */ - switch (common_hdr.ptype) { + switch ((*Header)->common.ptype) { case PKT_RESPONSE: pMsg->BufferLength = (*Header)->response.alloc_hint; break; @@ -749,7 +836,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, pMsg->BufferLength = (*Header)->request.alloc_hint; break; default: - pMsg->BufferLength = common_hdr.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&common_hdr); + pMsg->BufferLength = (*Header)->common.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&(*Header)->common); } TRACE("buffer length = %u\n", pMsg->BufferLength); @@ -762,43 +849,44 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, } first_flag = RPC_FLG_FIRST; - auth_length = common_hdr.auth_len; + auth_length = (*Header)->common.auth_len; if (auth_length) { - auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr)); + auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&(*Header)->common)); if (!auth_data) { status = RPC_S_OUT_OF_RESOURCES; goto fail; } } + CurrentHeader = *Header; buffer_length = 0; while (TRUE) { - unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common); + unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&CurrentHeader->common); /* verify header fields */ - if (((*Header)->common.frag_len < hdr_length) || - ((*Header)->common.frag_len - hdr_length < header_auth_len)) { + if ((CurrentHeader->common.frag_len < hdr_length) || + (CurrentHeader->common.frag_len - hdr_length < header_auth_len)) { WARN("frag_len %d too small for hdr_length %d and auth_len %d\n", - (*Header)->common.frag_len, hdr_length, header_auth_len); + CurrentHeader->common.frag_len, hdr_length, CurrentHeader->common.auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; } - if ((*Header)->common.auth_len != auth_length) { + if (CurrentHeader->common.auth_len != auth_length) { WARN("auth_len header field changed from %ld to %d\n", - auth_length, (*Header)->common.auth_len); + auth_length, CurrentHeader->common.auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; } - if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag) { + if ((CurrentHeader->common.flags & RPC_FLG_FIRST) != first_flag) { TRACE("invalid packet flags\n"); status = RPC_S_PROTOCOL_ERROR; goto fail; } - data_length = (*Header)->common.frag_len - hdr_length - header_auth_len; + data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len; if (data_length + buffer_length > pMsg->BufferLength) { TRACE("allocation hint exceeded, new buffer length = %ld\n", data_length + buffer_length); @@ -807,17 +895,11 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, if (status != RPC_S_OK) goto fail; } - if (data_length == 0) dwRead = 0; else - dwRead = rpcrt4_conn_read(Connection, - (unsigned char *)pMsg->Buffer + buffer_length, data_length); - if (dwRead != data_length) { - WARN("bad data length, %d/%ld\n", dwRead, data_length); - status = RPC_S_CALL_FAILED; - goto fail; - } + memcpy((unsigned char *)pMsg->Buffer + buffer_length, payload, data_length); if (header_auth_len) { - if (header_auth_len < sizeof(RpcAuthVerifier)) { + if (header_auth_len < sizeof(RpcAuthVerifier) || + header_auth_len > RPC_AUTH_VERIFIER_LEN(&(*Header)->common)) { WARN("bad auth verifier length %d\n", header_auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; @@ -828,22 +910,14 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, * however, the details of how this is done is very sketchy in the * DCE/RPC spec. for all other packet types that have authentication * verifier data then it is just duplicated in all the fragments */ - dwRead = rpcrt4_conn_read(Connection, auth_data, header_auth_len); - if (dwRead != header_auth_len) { - WARN("bad authentication data length, %d/%d\n", dwRead, - header_auth_len); - status = RPC_S_CALL_FAILED; - goto fail; - } + memcpy(auth_data, (unsigned char *)payload + data_length, header_auth_len); /* these packets are handled specially, not by the generic SecurePacket * function */ - if ((common_hdr.ptype != PKT_BIND) && - (common_hdr.ptype != PKT_BIND_ACK) && - (common_hdr.ptype != PKT_AUTH3)) + if (!auth_data_out && SecIsValidHandle(&Connection->ctx)) { status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE, - *Header, hdr_length, + CurrentHeader, hdr_length, (unsigned char *)pMsg->Buffer + buffer_length, data_length, (RpcAuthVerifier *)auth_data, auth_data + sizeof(RpcAuthVerifier), @@ -853,16 +927,19 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, } buffer_length += data_length; - if (!((*Header)->common.flags & RPC_FLG_LAST)) { + if (!(CurrentHeader->common.flags & RPC_FLG_LAST)) { TRACE("next header\n"); - /* read the header of next packet */ - dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length); - if (dwRead != hdr_length) { - WARN("invalid packet header size (%d)\n", dwRead); - status = RPC_S_CALL_FAILED; - goto fail; + if (*Header != CurrentHeader) + { + RPCRT4_FreeHeader(CurrentHeader); + CurrentHeader = NULL; } + HeapFree(GetProcessHeap(), 0, payload); + payload = NULL; + + status = RPCRT4_receive_fragment(Connection, &CurrentHeader, &payload); + if (status != RPC_S_OK) goto fail; first_flag = 0; } else { @@ -871,29 +948,40 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, } pMsg->BufferLength = buffer_length; - /* respond to authorization request */ - if (common_hdr.ptype == PKT_BIND_ACK && auth_length > sizeof(RpcAuthVerifier)) - { - status = RPCRT_AuthorizeConnection(Connection, - auth_data + sizeof(RpcAuthVerifier), - auth_length); - if (status) - goto fail; - } - /* success */ status = RPC_S_OK; fail: RPCRT4_SetThreadCurrentConnection(NULL); + if (CurrentHeader != *Header) + RPCRT4_FreeHeader(CurrentHeader); if (status != RPC_S_OK) { + I_RpcFree(pMsg->Buffer); + pMsg->Buffer = NULL; RPCRT4_FreeHeader(*Header); *Header = NULL; } - HeapFree(GetProcessHeap(), 0, auth_data); + if (auth_data_out && status == RPC_S_OK) { + *auth_length_out = auth_length; + *auth_data_out = auth_data; + } + else + HeapFree(GetProcessHeap(), 0, auth_data); + HeapFree(GetProcessHeap(), 0, payload); return status; } +/*********************************************************************** + * RPCRT4_Receive (internal) + * + * Receive a packet from connection and merge the fragments. + */ +RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, + PRPC_MESSAGE pMsg) +{ + return RPCRT4_ReceiveWithAuth(Connection, Header, pMsg, NULL, NULL); +} + /*********************************************************************** * I_RpcNegotiateTransferSyntax [RPCRT4.@] * @@ -936,7 +1024,10 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) &cif->InterfaceId); if (status == RPC_S_OK) + { pMsg->ReservedForRuntime = conn; + RPCRT4_AddRefBinding(bind); + } } return status; @@ -1033,12 +1124,67 @@ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) { RpcConnection *conn = pMsg->ReservedForRuntime; RPCRT4_CloseBinding(bind, conn); + RPCRT4_ReleaseBinding(bind); pMsg->ReservedForRuntime = NULL; } I_RpcFree(pMsg->Buffer); return RPC_S_OK; } +static void CALLBACK async_apc_notifier_proc(ULONG_PTR ulParam) +{ + RPC_ASYNC_STATE *state = (RPC_ASYNC_STATE *)ulParam; + state->u.APC.NotificationRoutine(state, NULL, state->Event); +} + +static DWORD WINAPI async_notifier_proc(LPVOID p) +{ + RpcConnection *conn = p; + RPC_ASYNC_STATE *state = conn->async_state; + + if (state && conn->ops->wait_for_incoming_data(conn) != -1) + { + state->Event = RpcCallComplete; + switch (state->NotificationType) + { + case RpcNotificationTypeEvent: + TRACE("RpcNotificationTypeEvent %p\n", state->u.hEvent); + SetEvent(state->u.hEvent); + break; + case RpcNotificationTypeApc: + TRACE("RpcNotificationTypeApc %p\n", state->u.APC.hThread); + QueueUserAPC(async_apc_notifier_proc, state->u.APC.hThread, (ULONG_PTR)state); + break; + case RpcNotificationTypeIoc: + TRACE("RpcNotificationTypeIoc %p, 0x%x, 0x%lx, %p\n", + state->u.IOC.hIOPort, state->u.IOC.dwNumberOfBytesTransferred, + state->u.IOC.dwCompletionKey, state->u.IOC.lpOverlapped); + PostQueuedCompletionStatus(state->u.IOC.hIOPort, + state->u.IOC.dwNumberOfBytesTransferred, + state->u.IOC.dwCompletionKey, + state->u.IOC.lpOverlapped); + break; + case RpcNotificationTypeHwnd: + TRACE("RpcNotificationTypeHwnd %p 0x%x\n", state->u.HWND.hWnd, + state->u.HWND.Msg); + PostMessageW(state->u.HWND.hWnd, state->u.HWND.Msg, 0, 0); + break; + case RpcNotificationTypeCallback: + TRACE("RpcNotificationTypeCallback %p\n", state->u.NotificationRoutine); + state->u.NotificationRoutine(state, NULL, state->Event); + break; + case RpcNotificationTypeNone: + TRACE("RpcNotificationTypeNone\n"); + break; + default: + FIXME("unknown NotificationType: %d/0x%x\n", state->NotificationType, state->NotificationType); + break; + } + } + + return 0; +} + /*********************************************************************** * I_RpcSend [RPCRT4.@] * @@ -1080,6 +1226,12 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) RPCRT4_FreeHeader(hdr); + if (status == RPC_S_OK && pMsg->RpcFlags & RPC_BUFFER_ASYNC) + { + if (!QueueUserWorkItem(async_notifier_proc, conn, WT_EXECUTEDEFAULT | WT_EXECUTELONGFUNCTION)) + status = RPC_S_OUT_OF_RESOURCES; + } + return status; } @@ -1198,8 +1350,17 @@ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync) { - FIXME("(%p, %p): stub\n", pMsg, pAsync); - return RPC_S_INVALID_BINDING; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcConnection *conn; + + TRACE("(%p, %p)\n", pMsg, pAsync); + + if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING; + + conn = pMsg->ReservedForRuntime; + conn->async_state = pAsync; + + return RPC_S_OK; } /*********************************************************************** diff --git a/reactos/dll/win32/rpcrt4/rpc_message.h b/reactos/dll/win32/rpcrt4/rpc_message.h index cbf83d30ce0..95eb8076ab8 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.h +++ b/reactos/dll/win32/rpcrt4/rpc_message.h @@ -34,7 +34,9 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned VOID RPCRT4_FreeHeader(RpcPktHdr *Header); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); +RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out); NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status); +RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count); #endif diff --git a/reactos/dll/win32/rpcrt4/rpc_transport.c b/reactos/dll/win32/rpcrt4/rpc_transport.c index b66ccc5616b..08261274b89 100644 --- a/reactos/dll/win32/rpcrt4/rpc_transport.c +++ b/reactos/dll/win32/rpcrt4/rpc_transport.c @@ -1571,7 +1571,7 @@ RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection) if (Connection->QOS) RpcQualityOfService_Release(Connection->QOS); /* server-only */ - if (Connection->server_binding) RPCRT4_DestroyBinding(Connection->server_binding); + if (Connection->server_binding) RPCRT4_ReleaseBinding(Connection->server_binding); HeapFree(GetProcessHeap(), 0, Connection); return RPC_S_OK; diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild index 092e9f17986..132ed2161de 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild +++ b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild @@ -39,6 +39,7 @@ rpcrt4_main.c rpcss_np_client.c unix_func.c + ndr_es.c rpcrt4.rc rpcrt4.spec diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.spec b/reactos/dll/win32/rpcrt4/rpcrt4.spec index 78aa71a5e7f..4c0d4eaa26a 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.spec +++ b/reactos/dll/win32/rpcrt4/rpcrt4.spec @@ -31,7 +31,7 @@ @ stub I_RpcBindingInqDynamicEndPointW @ stub I_RpcBindingInqLocalClientPID # wxp @ stub I_RpcBindingInqSecurityContext -@ stub I_RpcBindingInqTransportType +@ stdcall I_RpcBindingInqTransportType(ptr ptr) @ stub I_RpcBindingInqWireIdForSnego @ stub I_RpcBindingIsClientLocal # 9x version of I_RpcBindingSetAsync has 3 arguments, not 2 @@ -97,13 +97,13 @@ @ stub MIDL_wchar_strcpy @ stub MIDL_wchar_strlen @ stub MesBufferHandleReset -@ stub MesDecodeBufferHandleCreate -@ stub MesDecodeIncrementalHandleCreate +@ stdcall MesDecodeBufferHandleCreate(ptr long ptr) +@ stdcall MesDecodeIncrementalHandleCreate(ptr ptr ptr) @ stub MesEncodeDynBufferHandleCreate -@ stub MesEncodeFixedBufferHandleCreate -@ stub MesEncodeIncrementalHandleCreate -@ stub MesHandleFree -@ stub MesIncrementalHandleReset +@ stdcall MesEncodeFixedBufferHandleCreate(ptr long ptr ptr) +@ stdcall MesEncodeIncrementalHandleCreate(ptr ptr ptr ptr) +@ stdcall MesHandleFree(ptr) +@ stdcall MesIncrementalHandleReset(ptr ptr ptr ptr ptr long) @ stub MesInqProcEncodingId @ stdcall NDRCContextBinding(ptr) @ stdcall NDRCContextMarshall(ptr ptr) @@ -218,7 +218,7 @@ @ stdcall NdrMapCommAndFaultStatus(ptr ptr ptr long) @ stub NdrMarkNextActivePipe @ stub NdrMesProcEncodeDecode2 -@ stub NdrMesProcEncodeDecode +@ varargs NdrMesProcEncodeDecode(ptr ptr ptr) @ stub NdrMesSimpleTypeAlignSize @ stub NdrMesSimpleTypeDecode @ stub NdrMesSimpleTypeEncode @@ -350,7 +350,7 @@ @ stdcall RpcBindingInqAuthInfoW(ptr ptr ptr ptr ptr ptr) @ stdcall RpcBindingInqObject(ptr ptr) @ stub RpcBindingInqOption -@ stub RpcBindingReset +@ stdcall RpcBindingReset(ptr) @ stub RpcBindingServerFromClient @ stdcall RpcBindingSetAuthInfoA(ptr str long long ptr long) @ stdcall RpcBindingSetAuthInfoExA(ptr str long long ptr long ptr) diff --git a/reactos/include/psdk/midles.h b/reactos/include/psdk/midles.h new file mode 100644 index 00000000000..99b2effd104 --- /dev/null +++ b/reactos/include/psdk/midles.h @@ -0,0 +1,133 @@ +/* + * 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 + */ + +#ifndef __WINE_MIDLES_H__ +#define __WINE_MIDLES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + MES_ENCODE, + MES_DECODE +} MIDL_ES_CODE; + +typedef enum +{ + MES_INCREMENTAL_HANDLE, + MES_FIXED_BUFFER_HANDLE, + MES_DYNAMIC_BUFFER_HANDLE +} MIDL_ES_HANDLE_STYLE; + +typedef void (__RPC_USER * MIDL_ES_ALLOC)(void *,char **,unsigned int *); +typedef void (__RPC_USER * MIDL_ES_WRITE)(void *,char *,unsigned int); +typedef void (__RPC_USER * MIDL_ES_READ)(void *,char **,unsigned int *); + +typedef struct _MIDL_ES_MESSAGE +{ + MIDL_STUB_MESSAGE StubMsg; + MIDL_ES_CODE Operation; + void *UserState; + ULONG MesVersion : 8; + ULONG HandleStyle : 8; + ULONG HandleFlags : 8; + ULONG Reserve : 8; + MIDL_ES_ALLOC Alloc; + MIDL_ES_WRITE Write; + MIDL_ES_READ Read; + unsigned char *Buffer; + ULONG BufferSize; + unsigned char **pDynBuffer; + ULONG *pEncodedSize; + RPC_SYNTAX_IDENTIFIER InterfaceId; + ULONG ProcNumber; + ULONG AlienDataRep; + ULONG IncrDataSize; + ULONG ByteCount; +} MIDL_ES_MESSAGE, *PMIDL_ES_MESSAGE; + +typedef PMIDL_ES_MESSAGE MIDL_ES_HANDLE; + +typedef struct _MIDL_TYPE_PICKLING_INFO +{ + ULONG Version; + ULONG Flags; + UINT_PTR Reserved[3]; +} MIDL_TYPE_PICKLING_INFO, *PMIDL_TYPE_PICKLING_INFO; + +RPC_STATUS RPC_ENTRY + MesEncodeIncrementalHandleCreate(void *,MIDL_ES_ALLOC,MIDL_ES_WRITE,handle_t *); +RPC_STATUS RPC_ENTRY + MesDecodeIncrementalHandleCreate(void *,MIDL_ES_READ,handle_t *); +RPC_STATUS RPC_ENTRY + MesIncrementalHandleReset(handle_t,void *,MIDL_ES_ALLOC,MIDL_ES_WRITE,MIDL_ES_READ,MIDL_ES_CODE); + +RPC_STATUS RPC_ENTRY + MesEncodeFixedBufferHandleCreate(char *,ULONG,ULONG *,handle_t *); +RPC_STATUS RPC_ENTRY + MesEncodeDynBufferHandleCreate(char **,ULONG *,handle_t *); +RPC_STATUS RPC_ENTRY + MesDecodeBufferHandleCreate(char *,ULONG,handle_t *); +RPC_STATUS RPC_ENTRY + MesBufferHandleReset(handle_t,ULONG,MIDL_ES_CODE,char **,ULONG,ULONG *); + +RPC_STATUS RPC_ENTRY + MesHandleFree(handle_t); + +RPC_STATUS RPC_ENTRY + MesInqProcEncodingId(handle_t,PRPC_SYNTAX_IDENTIFIER,ULONG *); + +SIZE_T RPC_ENTRY + NdrMesSimpleTypeAlignSize(handle_t); +void RPC_ENTRY + NdrMesSimpleTypeDecode(handle_t,void *,short); +void RPC_ENTRY + NdrMesSimpleTypeEncode(handle_t,const MIDL_STUB_DESC *,const void *,short); + +SIZE_T RPC_ENTRY + NdrMesTypeAlignSize(handle_t,const MIDL_STUB_DESC *,PFORMAT_STRING,const void *); +void RPC_ENTRY + NdrMesTypeEncode(handle_t,const MIDL_STUB_DESC *,PFORMAT_STRING,const void *); +void RPC_ENTRY + NdrMesTypeDecode(handle_t,const MIDL_STUB_DESC *,PFORMAT_STRING,void *); + +SIZE_T RPC_ENTRY + NdrMesTypeAlignSize2(handle_t,const MIDL_TYPE_PICKLING_INFO *,const MIDL_STUB_DESC *,PFORMAT_STRING,const void *); +void RPC_ENTRY + NdrMesTypeEncode2(handle_t,const MIDL_TYPE_PICKLING_INFO *,const MIDL_STUB_DESC *,PFORMAT_STRING,const void *); +void RPC_ENTRY + NdrMesTypeDecode2(handle_t,const MIDL_TYPE_PICKLING_INFO *,const MIDL_STUB_DESC *,PFORMAT_STRING,void *); +void RPC_ENTRY + NdrMesTypeFree2(handle_t,const MIDL_TYPE_PICKLING_INFO *,const MIDL_STUB_DESC *,PFORMAT_STRING,void *); + +void RPC_VAR_ENTRY + NdrMesProcEncodeDecode(handle_t,const MIDL_STUB_DESC *,PFORMAT_STRING,...); +CLIENT_CALL_RETURN RPC_VAR_ENTRY + NdrMesProcEncodeDeocde2(handle_t,const MIDL_STUB_DESC *,PFORMAT_STRING,...); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_MIDLES_H__ */ diff --git a/reactos/include/psdk/ndrtypes.h b/reactos/include/psdk/ndrtypes.h index c4665fc4288..8605b737748 100644 --- a/reactos/include/psdk/ndrtypes.h +++ b/reactos/include/psdk/ndrtypes.h @@ -15,12 +15,14 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __NDRTYPES_H__ #define __NDRTYPES_H__ +#include + typedef struct { unsigned short MustSize : 1; /* 0x0001 - client interpreter MUST size this @@ -29,9 +31,7 @@ typedef struct unsigned short MustFree : 1; /* 0x0002 - server interpreter MUST size this * parameter, other parameters may be skipped, using the value in * NDR_PROC_PARTIAL_OIF_HEADER::constant_server_buffer_size instead. */ - unsigned short IsPipe : 1; /* 0x0004 - The parameter is a pipe handle. See - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/pipes.asp - * for more information on pipes. */ + unsigned short IsPipe : 1; /* 0x0004 - The parameter is a pipe handle */ unsigned short IsIn : 1; /* 0x0008 - The parameter is an input */ unsigned short IsOut : 1; /* 0x0010 - The parameter is an output */ unsigned short IsReturn : 1; /* 0x0020 - The parameter is to be returned */ @@ -178,5 +178,4 @@ typedef enum #define NDR_CONTEXT_HANDLE_SERIALIZE 0x02 #define NDR_CONTEXT_HANDLE_CANNOT_BE_NULL 0x01 - #endif diff --git a/reactos/include/psdk/oleidl.idl b/reactos/include/psdk/oleidl.idl index 02aef43b5e3..5c92cb19d45 100644 --- a/reactos/include/psdk/oleidl.idl +++ b/reactos/include/psdk/oleidl.idl @@ -18,7 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifndef DO_NO_IMPORTS import "objidl.idl"; +#endif interface IOleInPlaceActiveObject; @@ -331,7 +333,7 @@ interface IOleItemContainer : IOleContainer OLECONTF_EMBEDDINGS = 1, OLECONTF_LINKS = 2, OLECONTF_OTHERS = 4, - OLECONTF_OLNYUSER = 8, + OLECONTF_ONLYUSER = 8, OLECONTF_ONLYIFRUNNING = 16 } OLECONTF; diff --git a/reactos/include/psdk/rpcdce.h b/reactos/include/psdk/rpcdce.h index 473a799cc14..8c10233d9bd 100644 --- a/reactos/include/psdk/rpcdce.h +++ b/reactos/include/psdk/rpcdce.h @@ -139,6 +139,11 @@ typedef I_RPC_HANDLE *RPC_EP_INQ_HANDLE; #define RPC_C_AUTHN_MQ 100 #define RPC_C_AUTHN_DEFAULT 0xffffffff +#define RPC_C_AUTHZ_NONE 0 +#define RPC_C_AUTHZ_NAME 1 +#define RPC_C_AUTHZ_DCE 2 +#define RPC_C_AUTHZ_DEFAULT 0xffffffff + /* values for RPC_SECURITY_QOS*::ImpersonationType */ #define RPC_C_IMP_LEVEL_DEFAULT 0 #define RPC_C_IMP_LEVEL_ANONYMOUS 1 @@ -280,10 +285,13 @@ typedef struct _RPC_SECURITY_QOS_V2_A #define SEC_WINNT_AUTH_IDENTITY_UNICODE 0x2 /* RpcServerRegisterIfEx Flags */ -#define RPC_IF_AUTOLISTEN 0x1 -#define RPC_IF_OLE 0x2 -#define RPC_IF_ALLOW_UNKNOWN_AUTHORITY 0x4 -#define RPC_IF_ALLOW_SECURE_ONLY 0x8 +#define RPC_IF_AUTOLISTEN 0x01 +#define RPC_IF_OLE 0x02 +#define RPC_IF_ALLOW_UNKNOWN_AUTHORITY 0x04 +#define RPC_IF_ALLOW_SECURE_ONLY 0x08 +#define RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH 0x10 +#define RPC_IF_ALLOW_LOCAL_ONLY 0x20 +#define RPC_IF_SEC_NO_CACHE 0x40 RPC_STATUS RPC_ENTRY DceErrorInqTextA(RPC_STATUS e, RPC_CSTR buffer); RPC_STATUS RPC_ENTRY DceErrorInqTextW(RPC_STATUS e, RPC_WSTR buffer); @@ -291,7 +299,7 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextW(RPC_STATUS e, RPC_WSTR buffer); RPCRTAPI DECLSPEC_NORETURN void RPC_ENTRY RpcRaiseException( RPC_STATUS exception ); - + RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingCopy( RPC_BINDING_HANDLE SourceBinding, RPC_BINDING_HANDLE* DestinationBinding ); @@ -300,10 +308,14 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcBindingInqOption( RPC_BINDING_HANDLE Binding, ULONG Option, ULONG_PTR *OptionValue ); RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingReset( RPC_BINDING_HANDLE Binding ); RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcBindingSetOption( RPC_BINDING_HANDLE Binding, ULONG Option, ULONG_PTR OptionValue ); RPCRTAPI RPC_STATUS RPC_ENTRY RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid ); @@ -317,7 +329,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding ); RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WSTR *StringBinding ); -#define RpcBindingFromStringBinding WINELIB_NAME_AW(RpcBindingFromStringBinding) +#define RpcBindingToStringBinding WINELIB_NAME_AW(RpcBindingToStringBinding) RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ); @@ -367,6 +379,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerListen( unsigned int MinimumCallThreads, unsigned int MaxCalls, unsigned int DontWait ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcMgmtEnableIdleCleanup( void ); + RPCRTAPI RPC_STATUS RPC_ENTRY RpcMgmtSetCancelTimeout(LONG); RPCRTAPI RPC_STATUS RPC_ENTRY @@ -375,6 +390,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY RpcMgmtStopServerListening( RPC_BINDING_HANDLE Binding ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding); + RPCRTAPI RPC_STATUS RPC_ENTRY RpcMgmtInqIfIds( RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR** IfIdVector ); @@ -382,6 +400,12 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcMgmtEpEltInqBegin( RPC_BINDING_HANDLE EpBinding, ULONG InquiryType, RPC_IF_ID *IfId, ULONG VersOption, UUID *ObjectUuid, RPC_EP_INQ_HANDLE *InquiryContext); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcMgmtSetComTimeout( RPC_BINDING_HANDLE Binding, unsigned int Timeout ); + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcMgmtSetServerStackSize( ULONG ThreadStackSize ); + RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv ); @@ -469,6 +493,10 @@ RPCRTAPI RPC_STATUS RPC_ENTRY #define RpcBindingInqAuthInfo WINELIB_NAME_AW(RpcBindingInqAuthInfo) RPCRTAPI RPC_STATUS RPC_ENTRY RpcCancelThread(void*); +RPCRTAPI RPC_STATUS RPC_ENTRY RpcCancelThreadEx(void*,LONG); + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcImpersonateClient( RPC_BINDING_HANDLE Binding ); RPCRTAPI RPC_STATUS RPC_ENTRY RpcNetworkIsProtseqValidA( RPC_CSTR protseq ); @@ -476,6 +504,11 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcNetworkIsProtseqValidW( RPC_WSTR protseq ); #define RpcNetworkIsProtseqValid WINELIB_NAME_AW(RpcNetworkIsProtseqValid) +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcRevertToSelf( void ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcRevertToSelfEx( RPC_BINDING_HANDLE Binding ); + RPCRTAPI RPC_STATUS RPC_ENTRY RpcStringFreeA(RPC_CSTR* String); RPCRTAPI RPC_STATUS RPC_ENTRY @@ -509,13 +542,6 @@ RPCRTAPI unsigned short RPC_ENTRY RPCRTAPI int RPC_ENTRY UuidIsNil( UUID* Uuid, RPC_STATUS* Status_ ); - -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcImpersonateClient (IN RPC_BINDING_HANDLE BindingHandle OPTIONAL); - -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcRevertToSelf (); - #ifdef __cplusplus } #endif diff --git a/reactos/include/psdk/rpcdcep.h b/reactos/include/psdk/rpcdcep.h index f511bb04306..1bdfb471681 100644 --- a/reactos/include/psdk/rpcdcep.h +++ b/reactos/include/psdk/rpcdcep.h @@ -48,7 +48,7 @@ typedef struct _RPC_MESSAGE unsigned long RpcFlags; } RPC_MESSAGE, *PRPC_MESSAGE; -/* or'd with ProcNum */ +/* or'ed with ProcNum */ #define RPC_FLAGS_VALID_BIT 0x00008000 #define RPC_CONTEXT_HANDLE_DEFAULT_GUARD ((void *)0xfffff00d) diff --git a/reactos/include/psdk/rpcndr.h b/reactos/include/psdk/rpcndr.h index 9f4911cf1e1..9bf28407951 100644 --- a/reactos/include/psdk/rpcndr.h +++ b/reactos/include/psdk/rpcndr.h @@ -18,7 +18,7 @@ #ifndef __RPCNDR_H_VERSION__ /* FIXME: What version? Perhaps something is better than nothing, however incorrect */ -#define __RPCNDR_H_VERSION__ ( 500 ) +#define __RPCNDR_H_VERSION__ ( 399 ) #endif #ifndef __WINE_RPCNDR_H @@ -175,13 +175,15 @@ typedef struct _MIDL_STUB_MESSAGE ULONG BufferLength; ULONG MemorySize; unsigned char *Memory; - int IsClient; + unsigned char IsClient; + unsigned char Pad; + unsigned short uFlags2; int ReuseBuffer; struct NDR_ALLOC_ALL_NODES_CONTEXT *pAllocAllNodesContext; struct NDR_POINTER_QUEUE_STATE *pPointerQueueState; int IgnoreEmbeddedPointers; unsigned char *PointerBufferMark; - unsigned char fBufferValid; + unsigned char CorrDespIncrement; unsigned char uFlags; unsigned short UniquePtrCount; ULONG_PTR MaxCount; @@ -203,7 +205,14 @@ typedef struct _MIDL_STUB_MESSAGE int fHasReturn:1; int fHasExtensions:1; int fHasNewCorrDesc:1; - int fUnused:10; + int fIsIn:1; + int fIsOut:1; + int fIsOicf:1; + int fBufferValid:1; + int fHasMemoryValidateCallback:1; + int fInFree:1; + int fNeedMCCP:1; + int fUnused:3; int fUnused2:16; DWORD dwDestContext; void *pvDestContext; @@ -536,6 +545,9 @@ RPCRTAPI void RPC_ENTRY RPCRTAPI NDR_SCONTEXT RPC_ENTRY NdrServerContextNewUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcSmDestroyClientContext( void **ContextHandle ); + RPCRTAPI void RPC_ENTRY RpcSsDestroyClientContext( void **ContextHandle ); diff --git a/reactos/include/psdk/rpcproxy.h b/reactos/include/psdk/rpcproxy.h index eaf2a6a6508..acddc729b36 100644 --- a/reactos/include/psdk/rpcproxy.h +++ b/reactos/include/psdk/rpcproxy.h @@ -350,8 +350,6 @@ ULONG WINAPI CStdStubBuffer2_Release(IRpcStubBuffer *This) \ #if 0 -/* see http://www.microsoft.com/msj/0199/com/com0199.aspx */ - RPCRTAPI HRESULT RPC_ENTRY CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv ); @@ -365,4 +363,4 @@ RPCRTAPI HRESULT RPC_ENTRY } #endif -#endif /*__WINE_RPCDCE_H */ +#endif /*__WINE_RPCPROXY_H */