diff --git a/reactos/lib/rpcrt4/cpsf.c b/reactos/lib/rpcrt4/cpsf.c index 63ff8519534..3f0190c24aa 100644 --- a/reactos/lib/rpcrt4/cpsf.c +++ b/reactos/lib/rpcrt4/cpsf.c @@ -133,6 +133,10 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, const CLSID *pclsid, CStdPSFactoryBuffer *pPSFactoryBuffer) { + TRACE("(%s, %s, %p, %p, %s, %p)\n", debugstr_guid(rclsid), + debugstr_guid(iid), ppv, pProxyFileList, debugstr_guid(pclsid), + pPSFactoryBuffer); + *ppv = NULL; if (!pPSFactoryBuffer->lpVtbl) { pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; @@ -141,7 +145,17 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, } if (IsEqualGUID(rclsid, pclsid)) return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); - return CLASS_E_CLASSNOTAVAILABLE; + else { + const ProxyFileInfo *info; + int index; + /* otherwise, the dll may be using the iid as the clsid, so + * search for it in the proxy file list */ + if (FindProxyInfo(pProxyFileList, rclsid, &info, &index)) + return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); + + WARN("class %s not available\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; + } } /*********************************************************************** diff --git a/reactos/lib/rpcrt4/cpsf.h b/reactos/lib/rpcrt4/cpsf.h index bdb6503ea63..60364d39db2 100644 --- a/reactos/lib/rpcrt4/cpsf.h +++ b/reactos/lib/rpcrt4/cpsf.h @@ -41,4 +41,6 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub); +const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); + #endif /* __WINE_CPSF_H */ diff --git a/reactos/lib/rpcrt4/cstub.c b/reactos/lib/rpcrt4/cstub.c index 13004dd0e02..2633298fe46 100644 --- a/reactos/lib/rpcrt4/cstub.c +++ b/reactos/lib/rpcrt4/cstub.c @@ -177,3 +177,9 @@ void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface, CStdStubBuffer *This = (CStdStubBuffer *)iface; TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); } + +const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) +{ + CStdStubBuffer *This = (CStdStubBuffer *)iface; + return STUB_HEADER(This).pServerInfo; +} diff --git a/reactos/lib/rpcrt4/ndr_marshall.c b/reactos/lib/rpcrt4/ndr_marshall.c index e5c834198d1..42b72e3b77a 100644 --- a/reactos/lib/rpcrt4/ndr_marshall.c +++ b/reactos/lib/rpcrt4/ndr_marshall.c @@ -97,18 +97,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align) #define STD_OVERFLOW_CHECK(_Msg) do { \ - TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \ - if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \ + TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \ + if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \ + ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \ } while (0) #define NDR_TABLE_SIZE 128 #define NDR_TABLE_MASK 127 +static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); +static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); +static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); +static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); +static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); + NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10 */ 0, + NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, + NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, + NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, + NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, + /* 0x10 */ + NdrBaseTypeMarshall, /* 0x11 */ NdrPointerMarshall, NdrPointerMarshall, NdrPointerMarshall, NdrPointerMarshall, @@ -139,10 +149,13 @@ NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { NdrUserMarshalMarshall }; NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10 */ 0, + NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, + NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, + NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, + NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, + /* 0x10 */ + NdrBaseTypeUnmarshall, /* 0x11 */ NdrPointerUnmarshall, NdrPointerUnmarshall, NdrPointerUnmarshall, NdrPointerUnmarshall, @@ -173,10 +186,13 @@ NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { NdrUserMarshalUnmarshall }; NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10 */ 0, + NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, + NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, + NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, + NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, + /* 0x10 */ + NdrBaseTypeBufferSize, /* 0x11 */ NdrPointerBufferSize, NdrPointerBufferSize, NdrPointerBufferSize, NdrPointerBufferSize, @@ -207,10 +223,13 @@ NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { NdrUserMarshalBufferSize }; NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10 */ 0, + NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, + NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, + NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, + NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, + /* 0x10 */ + NdrBaseTypeMemorySize, /* 0x11 */ NdrPointerMemorySize, NdrPointerMemorySize, NdrPointerMemorySize, NdrPointerMemorySize, @@ -234,10 +253,13 @@ NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { NdrUserMarshalMemorySize }; NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x10 */ 0, + NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, + NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, + NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, + NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, + /* 0x10 */ + NdrBaseTypeFree, /* 0x11 */ NdrPointerFree, NdrPointerFree, NdrPointerFree, NdrPointerFree, @@ -286,46 +308,56 @@ PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pForm return pFormat+4; } -PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, - PFORMAT_STRING pFormat, ULONG_PTR def) +static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) +{ + pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); + pStubMsg->Buffer += 4; + TRACE("unmarshalled variance is %ld\n", pStubMsg->ActualCount); + return pFormat+4; +} + +PFORMAT_STRING ComputeConformanceOrVariance( + MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, + PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount) { BYTE dtype = pFormat[0] & 0xf; - DWORD ofs = (DWORD)pFormat[2] | ((DWORD)pFormat[3] << 8); + short ofs = *(short *)&pFormat[2]; LPVOID ptr = NULL; DWORD data = 0; + /* FIXME: is this correct? */ if (pFormat[0] == 0xff) { /* null descriptor */ - pStubMsg->MaxCount = def; + *pCount = def; goto finish_conf; } switch (pFormat[0] & 0xf0) { case RPC_FC_NORMAL_CONFORMANCE: - TRACE("normal conformance, ofs=%ld\n", ofs); + TRACE("normal conformance, ofs=%d\n", ofs); ptr = pMemory + ofs; break; case RPC_FC_POINTER_CONFORMANCE: - TRACE("pointer conformance, ofs=%ld\n", ofs); + TRACE("pointer conformance, ofs=%d\n", ofs); ptr = pStubMsg->Memory + ofs; break; case RPC_FC_TOP_LEVEL_CONFORMANCE: - TRACE("toplevel conformance, ofs=%ld\n", ofs); + TRACE("toplevel conformance, ofs=%d\n", ofs); if (pStubMsg->StackTop) { ptr = pStubMsg->StackTop + ofs; } else { - /* -Os mode, MaxCount is already set */ + /* -Os mode, *pCount is already set */ goto finish_conf; } break; case RPC_FC_CONSTANT_CONFORMANCE: data = ofs | ((DWORD)pFormat[1] << 16); TRACE("constant conformance, val=%ld\n", data); - pStubMsg->MaxCount = data; + *pCount = data; goto finish_conf; case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE: - FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs); + FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs); if (pStubMsg->StackTop) { ptr = pStubMsg->StackTop + ofs; } @@ -376,7 +408,7 @@ PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pM done_conf_grab: switch (pFormat[1]) { case 0: /* no op */ - pStubMsg->MaxCount = data; + *pCount = data; break; case RPC_FC_DEREFERENCE: /* already handled */ @@ -387,7 +419,7 @@ done_conf_grab: } finish_conf: - TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount); + TRACE("resulting conformance is %ld\n", *pCount); return pFormat+4; } @@ -538,7 +570,6 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) { unsigned long len, esize, ofs; - unsigned char *pMem; TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", pStubMsg, *ppMemory, pFormat, fMustAlloc); @@ -563,33 +594,18 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg FIXME("sized string format=%d\n", pFormat[1]); } - if (fMustAlloc) { + if (fMustAlloc || !*ppMemory) *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA); - } else { - if (pStubMsg->ReuseBuffer && !*ppMemory) - /* for servers, we may just point straight into the RPC buffer, I think - * (I guess that's what MS does since MIDL code doesn't try to free) */ - *ppMemory = pStubMsg->Buffer - ofs*esize; - /* for clients, memory should be provided by caller */ - } - if (len == 0) { - *ppMemory = NULL; - return NULL; - } - - pMem = *ppMemory + ofs*esize; - - if (pMem != pStubMsg->Buffer) - memcpy(pMem, pStubMsg->Buffer, len*esize); + memcpy(*ppMemory, pStubMsg->Buffer, len*esize); pStubMsg->Buffer += len*esize; if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)pMem)); + TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); } else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)pMem)); + TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); } return NULL; /* FIXME: is this always right? */ @@ -749,8 +765,6 @@ void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, RpcRaiseException(RPC_X_BAD_STUB_DATA); } - *pPointer = NULL; - if (pointer_id) { m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; if (m) m(pStubMsg, pPointer, desc, fMustAlloc); @@ -1449,6 +1463,9 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_ALIGNM8: ALIGN_POINTER(pMemory, 7); break; + case RPC_FC_STRUCTPAD2: + pMemory += 2; + break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; pFormat += 2; @@ -1512,6 +1529,9 @@ unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_ALIGNM8: ALIGN_POINTER(pMemory, 7); break; + case RPC_FC_STRUCTPAD2: + pMemory += 2; + break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; pFormat += 2; @@ -1569,6 +1589,9 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_ALIGNM8: ALIGN_POINTER(pMemory, 7); break; + case RPC_FC_STRUCTPAD2: + pMemory += 2; + break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; pFormat += 2; @@ -1622,6 +1645,9 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_ALIGNM8: ALIGN_POINTER(pMemory, 7); break; + case RPC_FC_STRUCTPAD2: + pMemory += 2; + break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; pFormat += 2; @@ -1669,6 +1695,9 @@ unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_ALIGNM8: ALIGN_LENGTH(size, 7); break; + case RPC_FC_STRUCTPAD2: + size += 2; + break; case RPC_FC_EMBEDDED_COMPLEX: size += pFormat[1]; pFormat += 2; @@ -1901,7 +1930,8 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); size = pStubMsg->MaxCount; - pStubMsg->BufferLength += size*esize; + /* conformance value plus array */ + pStubMsg->BufferLength += sizeof(DWORD) + size*esize; EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } @@ -1912,16 +1942,18 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - DWORD size = 0; - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + DWORD size = 0, esize = *(const WORD*)(pFormat+2); + unsigned char *buffer; + + TRACE("(%p,%p)\n", pStubMsg, pFormat); if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); + buffer = pStubMsg->Buffer; pFormat = ReadConformance(pStubMsg, pFormat+4); + pStubMsg->Buffer = buffer; size = pStubMsg->MaxCount; - EmbeddedPointerMemorySize(pStubMsg, pFormat); - - return 0; + return size*esize; } /*********************************************************************** @@ -1945,7 +1977,35 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu unsigned char* pMemory, PFORMAT_STRING pFormat ) { - FIXME( "stub\n" ); + DWORD esize = *(const WORD*)(pFormat+2); + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if (pFormat[0] != RPC_FC_CVARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); + pStubMsg->Buffer += 4; + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); + pStubMsg->Buffer += 4; + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); + pStubMsg->Buffer += 4; + + memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize); + pStubMsg->BufferMark = pStubMsg->Buffer; + pStubMsg->Buffer += pStubMsg->ActualCount*esize; + + EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + + STD_OVERFLOW_CHECK(pStubMsg); + return NULL; } @@ -1958,7 +2018,29 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS PFORMAT_STRING pFormat, unsigned char fMustAlloc ) { - FIXME( "stub\n" ); + DWORD offset; + DWORD esize = *(const WORD*)(pFormat+2); + + TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + + if (pFormat[0] != RPC_FC_CVARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + pFormat = ReadConformance(pStubMsg, pFormat); + offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); + pStubMsg->Buffer += 4; + pFormat = ReadVariance(pStubMsg, pFormat); + + if (!*ppMemory || fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize); + memcpy(*ppMemory + offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize); + pStubMsg->Buffer += pStubMsg->ActualCount * esize; + + EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); + return NULL; } @@ -1980,7 +2062,26 @@ void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat ) { - FIXME( "stub\n" ); + DWORD esize = *(const WORD*)(pFormat+2); + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if (pFormat[0] != RPC_FC_CVARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + /* compute size */ + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + /* compute length */ + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + + /* conformance + offset + variance + array */ + pStubMsg->BufferLength += 3*sizeof(DWORD) + pStubMsg->ActualCount*esize; + + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } @@ -2269,6 +2370,14 @@ void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, lo is to raise an exception */ } +typedef struct _NDR_CSTRUCT_FORMAT +{ + unsigned char type; + unsigned char alignment; + unsigned short memory_size; + short offset_to_array_description; +} NDR_CSTRUCT_FORMAT; + /*********************************************************************** * NdrConformantStructMarshall [RPCRT4.@] */ @@ -2276,7 +2385,32 @@ unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat; + pFormat += sizeof(NDR_CSTRUCT_FORMAT); + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) + { + ERR("invalid format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + TRACE("memory_size = %d\n", pCStructFormat->memory_size); + + /* copy constant sized part of struct */ + memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size); + pStubMsg->Buffer += pCStructFormat->memory_size; + + if (pCStructFormat->offset_to_array_description) + { + PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + NdrConformantArrayMarshall(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat); + } + if (pCStructFormat->type == RPC_FC_CPSTRUCT) + EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); return NULL; } @@ -2288,7 +2422,52 @@ unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMs PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); + const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat; + pFormat += sizeof(NDR_CSTRUCT_FORMAT); + + TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + + if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) + { + ERR("invalid format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + TRACE("memory_size = %d\n", pCStructFormat->memory_size); + + /* work out how much memory to allocate if we need to do so */ + if (!*ppMemory || fMustAlloc) + { + SIZE_T size = pCStructFormat->memory_size; + + if (pCStructFormat->offset_to_array_description) + { + unsigned char *buffer; + PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + buffer = pStubMsg->Buffer; + pStubMsg->Buffer += pCStructFormat->memory_size; + size += NdrConformantArrayMemorySize(pStubMsg, pArrayFormat); + pStubMsg->Buffer = buffer; + } + *ppMemory = NdrAllocate(pStubMsg, size); + } + + /* now copy the data */ + memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size); + pStubMsg->Buffer += pCStructFormat->memory_size; + if (pCStructFormat->offset_to_array_description) + { + PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + unsigned char *pMemoryArray = *ppMemory + pCStructFormat->memory_size; + /* note that we pass fMustAlloc as 0 as we have already allocated the + * memory */ + NdrConformantArrayUnmarshall(pStubMsg, &pMemoryArray, pArrayFormat, 0); + } + if (pCStructFormat->type == RPC_FC_CPSTRUCT) + EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); return NULL; } @@ -2299,7 +2478,30 @@ void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat; + pFormat += sizeof(NDR_CSTRUCT_FORMAT); + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) + { + ERR("invalid format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + TRACE("memory_size = %d\n", pCStructFormat->memory_size); + + /* add constant sized part of struct to buffer size */ + pStubMsg->BufferLength += pCStructFormat->memory_size; + + if (pCStructFormat->offset_to_array_description) + { + PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + NdrConformantArrayBufferSize(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat); + } + if (pCStructFormat->type == RPC_FC_CPSTRUCT) + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } /*********************************************************************** @@ -2693,6 +2895,242 @@ void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg, FIXME("stub\n"); } +/*********************************************************************** + * NdrBaseTypeMarshall [internal] + */ +static unsigned char *WINAPI NdrBaseTypeMarshall( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + switch(*pFormat) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory; + pStubMsg->Buffer += sizeof(UCHAR); + TRACE("value: 0x%02x\n", *(UCHAR *)pMemory); + break; + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); + *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory; + pStubMsg->Buffer += sizeof(USHORT); + TRACE("value: 0x%04x\n", *(USHORT *)pMemory); + break; + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ERROR_STATUS_T: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1); + *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory; + pStubMsg->Buffer += sizeof(ULONG); + TRACE("value: 0x%08lx\n", *(ULONG *)pMemory); + break; + case RPC_FC_FLOAT: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1); + *(float *)pStubMsg->Buffer = *(float *)pMemory; + pStubMsg->Buffer += sizeof(float); + break; + case RPC_FC_DOUBLE: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1); + *(double *)pStubMsg->Buffer = *(double *)pMemory; + pStubMsg->Buffer += sizeof(double); + break; + case RPC_FC_HYPER: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1); + *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory; + pStubMsg->Buffer += sizeof(ULONGLONG); + TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); + break; + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + default: + FIXME("Unhandled base type: 0x%02x\n", *pFormat); + } + + STD_OVERFLOW_CHECK(pStubMsg); + + /* FIXME: what is the correct return value? */ + return NULL; +} + +/*********************************************************************** + * NdrBaseTypeUnmarshall [internal] + */ +static unsigned char *WINAPI NdrBaseTypeUnmarshall( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char **ppMemory, + PFORMAT_STRING pFormat, + unsigned char fMustAlloc) +{ + TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); + + if (fMustAlloc || !*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat)); + + TRACE("*ppMemory: %p\n", *ppMemory); + + switch(*pFormat) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + **(UCHAR **)ppMemory = *(UCHAR *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(UCHAR); + TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); + break; + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); + **(USHORT **)ppMemory = *(USHORT *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(USHORT); + TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); + break; + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ERROR_STATUS_T: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1); + **(ULONG **)ppMemory = *(ULONG *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(ULONG); + TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory); + break; + case RPC_FC_FLOAT: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1); + **(float **)ppMemory = *(float *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(float); + TRACE("value: %f\n", **(float **)ppMemory); + break; + case RPC_FC_DOUBLE: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1); + **(double **)ppMemory = *(double*)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(double); + TRACE("value: %f\n", **(double **)ppMemory); + break; + case RPC_FC_HYPER: + ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1); + **(ULONGLONG **)ppMemory = *(ULONGLONG *)pStubMsg->Buffer; + pStubMsg->Buffer += sizeof(ULONGLONG); + TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory)); + break; + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + default: + FIXME("Unhandled base type: 0x%02x\n", *pFormat); + } + + /* FIXME: what is the correct return value? */ + + return NULL; +} + +/*********************************************************************** + * NdrBaseTypeBufferSize [internal] + */ +static void WINAPI NdrBaseTypeBufferSize( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + switch(*pFormat) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + pStubMsg->BufferLength += sizeof(UCHAR); + break; + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT) - 1); + pStubMsg->BufferLength += sizeof(USHORT); + break; + case RPC_FC_LONG: + case RPC_FC_ULONG: + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG) - 1); + pStubMsg->BufferLength += sizeof(ULONG); + break; + case RPC_FC_FLOAT: + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float) - 1); + pStubMsg->BufferLength += sizeof(float); + break; + case RPC_FC_DOUBLE: + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double) - 1); + pStubMsg->BufferLength += sizeof(double); + break; + case RPC_FC_HYPER: + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG) - 1); + pStubMsg->BufferLength += sizeof(ULONGLONG); + break; + case RPC_FC_ERROR_STATUS_T: + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t) - 1); + pStubMsg->BufferLength += sizeof(error_status_t); + break; + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + default: + FIXME("Unhandled base type: 0x%02x\n", *pFormat); + } +} + +/*********************************************************************** + * NdrBaseTypeMemorySize [internal] + */ +static unsigned long WINAPI NdrBaseTypeMemorySize( + PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + switch(*pFormat) + { + 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: + 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_ERROR_STATUS_T: + return sizeof(error_status_t); + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + default: + FIXME("Unhandled base type: 0x%02x\n", *pFormat); + return 0; + } +} + +/*********************************************************************** + * NdrBaseTypeFree [internal] + */ +static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + /* nothing to do */ +} + /*********************************************************************** * NdrClientContextMarshall */ diff --git a/reactos/lib/rpcrt4/ndr_midl.c b/reactos/lib/rpcrt4/ndr_midl.c index d7e74709ce4..723c3c11603 100644 --- a/reactos/lib/rpcrt4/ndr_midl.c +++ b/reactos/lib/rpcrt4/ndr_midl.c @@ -140,8 +140,12 @@ void WINAPI NdrProxyFreeBuffer(void *This, */ HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode) { - FIXME("(0x%08lx): semi-stub\n", dwExceptionCode); - return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RPC, RPC_S_CALL_FAILED); + WARN("(0x%08lx): a proxy call failed\n", dwExceptionCode); + + if (FAILED(dwExceptionCode)) + return dwExceptionCode; + else + return HRESULT_FROM_WIN32(dwExceptionCode); } /*********************************************************************** @@ -234,12 +238,12 @@ unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_M unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle) { TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle); - + assert( stubmsg && stubmsg->RpcMsg ); /* I guess this is our chance to put the binding handle into the RPC_MESSAGE */ stubmsg->RpcMsg->Handle = handle; - + stubmsg->RpcMsg->BufferLength = buflen; if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK) return NULL; @@ -249,7 +253,6 @@ unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buf stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength; return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer); } - /*********************************************************************** * NdrFreeBuffer [RPCRT4.@] */ @@ -264,30 +267,29 @@ void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg) /************************************************************************ * NdrSendReceive [RPCRT4.@] */ -unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *pStubMsg, unsigned char *buffer ) +unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer ) { - TRACE("(pStubMsg == ^%p, buffer == ^%p)\n", pStubMsg, buffer); + TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer); /* FIXME: how to handle errors? (raise exception?) */ - if (!pStubMsg) { + if (!stubmsg) { ERR("NULL stub message. No action taken.\n"); return NULL; } - if (!pStubMsg->RpcMsg) { + if (!stubmsg->RpcMsg) { ERR("RPC Message not present in stub message. No action taken.\n"); return NULL; } - if (I_RpcSendReceive(pStubMsg->RpcMsg) != RPC_S_OK) { + if (I_RpcSendReceive(stubmsg->RpcMsg) != RPC_S_OK) { WARN("I_RpcSendReceive did not return success.\n"); /* FIXME: raise exception? */ - return NULL; } - pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; + stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength; + stubmsg->BufferStart = stubmsg->RpcMsg->Buffer; + stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength; + stubmsg->Buffer = stubmsg->BufferStart; /* FIXME: is this the right return value? */ return NULL; diff --git a/reactos/lib/rpcrt4/ndr_misc.h b/reactos/lib/rpcrt4/ndr_misc.h index b246b44d991..32f835dfd1d 100644 --- a/reactos/lib/rpcrt4/ndr_misc.h +++ b/reactos/lib/rpcrt4/ndr_misc.h @@ -35,8 +35,11 @@ LONG_PTR RPCRT4_NdrClientCall2(PMIDL_STUB_DESC pStubDesc, HRESULT RPCRT4_GetPSFactory(REFIID riid, struct IPSFactoryBuffer **ppPS); -PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, - PFORMAT_STRING pFormat, ULONG_PTR def); +#define ComputeConformance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount) +#define ComputeVariance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->ActualCount) +PFORMAT_STRING ComputeConformanceOrVariance( + MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, + PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount); typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char); diff --git a/reactos/lib/rpcrt4/ndr_ole.c b/reactos/lib/rpcrt4/ndr_ole.c index a92b7544f0c..0919f9fdd96 100644 --- a/reactos/lib/rpcrt4/ndr_ole.c +++ b/reactos/lib/rpcrt4/ndr_ole.c @@ -254,13 +254,17 @@ unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); pStubMsg->MaxCount = 0; if (!LoadCOM()) return NULL; - if (pStubMsg->Buffer + sizeof(DWORD) < pStubMsg->BufferEnd) { + if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { stream = RpcStream_Create(pStubMsg, TRUE); if (stream) { hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory, pStubMsg->dwDestContext, pStubMsg->pvDestContext, MSHLFLAGS_NORMAL); IStream_Release(stream); + if (FAILED(hr)) { + IUnknown_Release((LPUNKNOWN)pMemory); + RpcRaiseException(hr); + } } } return NULL; @@ -280,11 +284,13 @@ unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); if (!LoadCOM()) return NULL; *(LPVOID*)ppMemory = NULL; - if (pStubMsg->Buffer + sizeof(DWORD) < pStubMsg->BufferEnd) { + if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { stream = RpcStream_Create(pStubMsg, FALSE); if (stream) { hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory); IStream_Release(stream); + if (FAILED(hr)) + RpcRaiseException(hr); } } return NULL; @@ -307,7 +313,7 @@ void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->dwDestContext, pStubMsg->pvDestContext, MSHLFLAGS_NORMAL); TRACE("size=%ld\n", size); - if (size) pStubMsg->BufferLength += sizeof(DWORD) + size; + pStubMsg->BufferLength += sizeof(DWORD) + size; } /***********************************************************************