Implement conformant varying array functions.
diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index f579c84..89a8dfd 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c
@@ -1956,7 +1956,35 @@ 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; } @@ -1969,7 +1997,29 @@ 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; } @@ -1991,7 +2041,26 @@ 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); }