Robert Shearman : rpcrt4: Implement varying array NDR functions.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jun 5 07:28:14 CDT 2006
Module: wine
Branch: refs/heads/master
Commit: c9779ca16b7f7715ed04450c3339f200c8fccb9b
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c9779ca16b7f7715ed04450c3339f200c8fccb9b
Author: Robert Shearman <rob at codeweavers.com>
Date: Mon Jun 5 01:41:30 2006 +0100
rpcrt4: Implement varying array NDR functions.
---
dlls/rpcrt4/ndr_marshall.c | 252 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 245 insertions(+), 7 deletions(-)
diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c
index af20c0a..30f5ddc 100644
--- a/dlls/rpcrt4/ndr_marshall.c
+++ b/dlls/rpcrt4/ndr_marshall.c
@@ -21,7 +21,6 @@
* TODO:
* - Non-conformant strings
* - String structs
- * - Varying arrays
* - Encapsulated unions
* - Byte count pointers
* - transmit_as/represent as
@@ -3532,7 +3531,59 @@ unsigned char * WINAPI NdrVaryingArrayM
unsigned char *pMemory,
PFORMAT_STRING pFormat)
{
- FIXME("stub\n");
+ unsigned char alignment;
+ DWORD elements, esize;
+
+ TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
+
+ if ((pFormat[0] != RPC_FC_SMVARRAY) &&
+ (pFormat[0] != RPC_FC_LGVARRAY))
+ {
+ ERR("invalid format type %x\n", pFormat[0]);
+ RpcRaiseException(RPC_S_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ alignment = pFormat[1] + 1;
+
+ if (pFormat[0] == RPC_FC_SMVARRAY)
+ {
+ pFormat += 2;
+ pFormat += sizeof(WORD);
+ elements = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ }
+ else
+ {
+ pFormat += 2;
+ pFormat += sizeof(DWORD);
+ elements = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ }
+
+ esize = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+
+ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
+ if ((pStubMsg->ActualCount > elements) ||
+ (pStubMsg->ActualCount + pStubMsg->Offset > elements))
+ {
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+ return NULL;
+ }
+
+ WriteVariance(pStubMsg);
+
+ ALIGN_POINTER(pStubMsg->Buffer, alignment);
+
+ 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;
}
@@ -3544,7 +3595,58 @@ unsigned char * WINAPI NdrVaryingArrayU
PFORMAT_STRING pFormat,
unsigned char fMustAlloc)
{
- FIXME("stub\n");
+ unsigned char alignment;
+ DWORD size, elements, esize;
+
+ TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
+
+ if ((pFormat[0] != RPC_FC_SMVARRAY) &&
+ (pFormat[0] != RPC_FC_LGVARRAY))
+ {
+ ERR("invalid format type %x\n", pFormat[0]);
+ RpcRaiseException(RPC_S_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ alignment = pFormat[1] + 1;
+
+ if (pFormat[0] == RPC_FC_SMVARRAY)
+ {
+ pFormat += 2;
+ size = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ elements = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ }
+ else
+ {
+ pFormat += 2;
+ size = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ elements = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ }
+
+ esize = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+
+ pFormat = ReadVariance(pStubMsg, pFormat);
+ if ((pStubMsg->ActualCount > elements) ||
+ (pStubMsg->ActualCount + pStubMsg->Offset > elements))
+ {
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+ return NULL;
+ }
+
+ ALIGN_POINTER(pStubMsg->Buffer, alignment);
+
+ if (!*ppMemory || fMustAlloc)
+ *ppMemory = NdrAllocate(pStubMsg, size);
+ memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize);
+ pStubMsg->Buffer += pStubMsg->ActualCount * esize;
+
+ EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
+
return NULL;
}
@@ -3555,7 +3657,54 @@ void WINAPI NdrVaryingArrayBufferSize(PM
unsigned char *pMemory,
PFORMAT_STRING pFormat)
{
- FIXME("stub\n");
+ unsigned char alignment;
+ DWORD elements, esize;
+
+ TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
+
+ if ((pFormat[0] != RPC_FC_SMVARRAY) &&
+ (pFormat[0] != RPC_FC_LGVARRAY))
+ {
+ ERR("invalid format type %x\n", pFormat[0]);
+ RpcRaiseException(RPC_S_INTERNAL_ERROR);
+ return;
+ }
+
+ alignment = pFormat[1] + 1;
+
+ if (pFormat[0] == RPC_FC_SMVARRAY)
+ {
+ pFormat += 2;
+ pFormat += sizeof(WORD);
+ elements = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ }
+ else
+ {
+ pFormat += 2;
+ pFormat += sizeof(DWORD);
+ elements = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ }
+
+ esize = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+
+ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
+ if ((pStubMsg->ActualCount > elements) ||
+ (pStubMsg->ActualCount + pStubMsg->Offset > elements))
+ {
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+ return;
+ }
+
+ SizeVariance(pStubMsg);
+
+ ALIGN_LENGTH(pStubMsg->BufferLength, alignment);
+
+ pStubMsg->BufferLength += pStubMsg->ActualCount * esize;
+
+ EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
}
/***********************************************************************
@@ -3564,8 +3713,57 @@ void WINAPI NdrVaryingArrayBufferSize(PM
unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
PFORMAT_STRING pFormat)
{
- FIXME("stub\n");
- return 0;
+ unsigned char alignment;
+ DWORD size, elements, esize;
+
+ TRACE("(%p, %p)\n", pStubMsg, pFormat);
+
+ if ((pFormat[0] != RPC_FC_SMVARRAY) &&
+ (pFormat[0] != RPC_FC_LGVARRAY))
+ {
+ ERR("invalid format type %x\n", pFormat[0]);
+ RpcRaiseException(RPC_S_INTERNAL_ERROR);
+ return 0;
+ }
+
+ alignment = pFormat[1] + 1;
+
+ if (pFormat[0] == RPC_FC_SMVARRAY)
+ {
+ pFormat += 2;
+ size = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ elements = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ }
+ else
+ {
+ pFormat += 2;
+ size = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ elements = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ }
+
+ esize = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+
+ pFormat = ReadVariance(pStubMsg, pFormat);
+ if ((pStubMsg->ActualCount > elements) ||
+ (pStubMsg->ActualCount + pStubMsg->Offset > elements))
+ {
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+ return 0;
+ }
+
+ ALIGN_POINTER(pStubMsg->Buffer, alignment);
+
+ pStubMsg->Buffer += pStubMsg->ActualCount * esize;
+ pStubMsg->MemorySize += size;
+
+ EmbeddedPointerMemorySize(pStubMsg, pFormat);
+
+ return pStubMsg->MemorySize;
}
/***********************************************************************
@@ -3575,7 +3773,47 @@ void WINAPI NdrVaryingArrayFree(PMIDL_ST
unsigned char *pMemory,
PFORMAT_STRING pFormat)
{
- FIXME("stub\n");
+ unsigned char alignment;
+ DWORD elements;
+
+ TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
+
+ if ((pFormat[0] != RPC_FC_SMVARRAY) &&
+ (pFormat[0] != RPC_FC_LGVARRAY))
+ {
+ ERR("invalid format type %x\n", pFormat[0]);
+ RpcRaiseException(RPC_S_INTERNAL_ERROR);
+ return;
+ }
+
+ alignment = pFormat[1] + 1;
+
+ if (pFormat[0] == RPC_FC_SMVARRAY)
+ {
+ pFormat += 2;
+ pFormat += sizeof(WORD);
+ elements = *(const WORD*)pFormat;
+ pFormat += sizeof(WORD);
+ }
+ else
+ {
+ pFormat += 2;
+ pFormat += sizeof(DWORD);
+ elements = *(const DWORD*)pFormat;
+ pFormat += sizeof(DWORD);
+ }
+
+ pFormat += sizeof(WORD);
+
+ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0);
+ if ((pStubMsg->ActualCount > elements) ||
+ (pStubMsg->ActualCount + pStubMsg->Offset > elements))
+ {
+ RpcRaiseException(RPC_S_INVALID_BOUND);
+ return;
+ }
+
+ EmbeddedPointerFree(pStubMsg, pMemory, pFormat);
}
/***********************************************************************
More information about the wine-cvs
mailing list