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