Alexandre Julliard : rpcrt4: Add support for complex arrays in the generic array unmarshalling functions .

Alexandre Julliard julliard at winehq.org
Tue Apr 6 11:20:04 CDT 2010


Module: wine
Branch: master
Commit: fe2f875aafea660527a10a81b1d06a44c9fc6f23
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fe2f875aafea660527a10a81b1d06a44c9fc6f23

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Apr  5 22:02:20 2010 +0200

rpcrt4: Add support for complex arrays in the generic array unmarshalling functions.

---

 dlls/rpcrt4/ndr_marshall.c |  132 +++++++++++++++++++++++++++-----------------
 1 files changed, 82 insertions(+), 50 deletions(-)

diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c
index d28bf62..24c7dbc 100644
--- a/dlls/rpcrt4/ndr_marshall.c
+++ b/dlls/rpcrt4/ndr_marshall.c
@@ -27,6 +27,7 @@
  *  - Checks for integer addition overflow in user marshall functions
  */
 
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -2046,7 +2047,8 @@ static inline void array_write_variance_and_marshall(
 static inline ULONG array_read_conformance(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
 {
-  DWORD esize;
+  DWORD def, esize;
+  unsigned char alignment;
 
   switch (fc)
   {
@@ -2070,6 +2072,21 @@ static inline ULONG array_read_conformance(
     else
       ReadConformance(pStubMsg, NULL);
     return safe_multiply(esize, pStubMsg->MaxCount);
+  case RPC_FC_BOGUS_ARRAY:
+    alignment = pFormat[1] + 1;
+    def = *(const WORD *)(pFormat + 2);
+    pFormat += 4;
+    if (IsConformanceOrVariancePresent(pFormat)) pFormat = ReadConformance(pStubMsg, pFormat);
+    else
+    {
+        pStubMsg->MaxCount = def;
+        pFormat = SkipConformance( pStubMsg, pFormat );
+    }
+    pFormat = SkipVariance( pStubMsg, pFormat );
+
+    align_pointer(&pStubMsg->Buffer, alignment);
+    esize = ComplexStructSize(pStubMsg, pFormat);
+    return safe_multiply(pStubMsg->MaxCount, esize);
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -2084,8 +2101,8 @@ static inline ULONG array_read_variance_and_unmarshall(
   ULONG bufsize, memsize;
   WORD esize;
   unsigned char alignment;
-  unsigned char *saved_buffer;
-  ULONG offset;
+  unsigned char *saved_buffer, *pMemory;
+  ULONG i, offset, count;
 
   switch (fc)
   {
@@ -2204,6 +2221,31 @@ static inline ULONG array_read_variance_and_unmarshall(
         TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
     }
     return bufsize;
+
+  case RPC_FC_BOGUS_ARRAY:
+    alignment = pFormat[1] + 1;
+    pFormat = SkipConformance(pStubMsg, pFormat + 4);
+    pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
+
+    esize = ComplexStructSize(pStubMsg, pFormat);
+    memsize = safe_multiply(esize, pStubMsg->MaxCount);
+
+    assert( fUnmarshall );
+
+    if (!fMustAlloc && !*ppMemory)
+      fMustAlloc = TRUE;
+    if (fMustAlloc)
+      *ppMemory = NdrAllocate(pStubMsg, memsize);
+
+    align_pointer(&pStubMsg->Buffer, alignment);
+    saved_buffer = pStubMsg->Buffer;
+
+    pMemory = *ppMemory;
+    count = pStubMsg->ActualCount;
+    for (i = 0; i < count; i++)
+        pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
+    return pStubMsg->Buffer - saved_buffer;
+
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -2214,6 +2256,7 @@ static inline void array_memory_size(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat,
     unsigned char fHasPointers)
 {
+  ULONG i, count, SavedMemorySize;
   ULONG bufsize, memsize;
   DWORD esize;
   unsigned char alignment;
@@ -2286,6 +2329,24 @@ static inline void array_memory_size(
     safe_buffer_increment(pStubMsg, bufsize);
     pStubMsg->MemorySize += memsize;
     break;
+  case RPC_FC_BOGUS_ARRAY:
+    alignment = pFormat[1] + 1;
+    pFormat = SkipConformance(pStubMsg, pFormat + 4);
+    pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
+
+    align_pointer(&pStubMsg->Buffer, alignment);
+
+    SavedMemorySize = pStubMsg->MemorySize;
+
+    esize = ComplexStructSize(pStubMsg, pFormat);
+    memsize = safe_multiply(pStubMsg->MaxCount, esize);
+
+    count = pStubMsg->ActualCount;
+    for (i = 0; i < count; i++)
+        ComplexStructMemorySize(pStubMsg, pFormat, NULL);
+
+    pStubMsg->MemorySize = SavedMemorySize + memsize;
+    break;
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -2296,6 +2357,8 @@ static inline void array_free(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg,
     unsigned char *pMemory, PFORMAT_STRING pFormat, unsigned char fHasPointers)
 {
+  DWORD i, count;
+
   switch (fc)
   {
   case RPC_FC_CARRAY:
@@ -2313,6 +2376,15 @@ static inline void array_free(
   case RPC_FC_C_WSTRING:
     /* No embedded pointers so nothing to do */
     break;
+  case RPC_FC_BOGUS_ARRAY:
+      count = *(const WORD *)(pFormat + 2);
+      pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 4, count);
+      pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
+
+      count = pStubMsg->ActualCount;
+      for (i = 0; i < count; i++)
+          pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL);
+    break;
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -4048,9 +4120,7 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
                                                  PFORMAT_STRING pFormat,
                                                  unsigned char fMustAlloc)
 {
-  ULONG i, count, size;
-  unsigned char alignment;
-  unsigned char *pMemory;
+  ULONG size;
   unsigned char *saved_buffer;
   int pointer_buffer_mark_set = 0;
   int saved_ignore_embedded;
@@ -4064,8 +4134,6 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
       return NULL;
   }
 
-  alignment = pFormat[1] + 1;
-
   saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers;
   /* save buffer pointer */
   saved_buffer = pStubMsg->Buffer;
@@ -4087,22 +4155,9 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
   /* restore the original buffer */
   pStubMsg->Buffer = saved_buffer;
 
-  pFormat += 4;
-
-  pFormat = ReadConformance(pStubMsg, pFormat);
-  pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
-
-  if (!fMustAlloc && !*ppMemory)
-    fMustAlloc = TRUE;
-  if (fMustAlloc)
-    *ppMemory = NdrAllocate(pStubMsg, size);
-
-  align_pointer(&pStubMsg->Buffer, alignment);
-
-  pMemory = *ppMemory;
-  count = pStubMsg->ActualCount;
-  for (i = 0; i < count; i++)
-    pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc);
+  array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
+  array_read_variance_and_unmarshall(RPC_FC_BOGUS_ARRAY, pStubMsg, ppMemory, pFormat, fMustAlloc,
+                                     TRUE /* fUseBufferMemoryServer */, TRUE /* fUnmarshall */);
 
   if (pointer_buffer_mark_set)
   {
@@ -4174,9 +4229,6 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
 ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
                                        PFORMAT_STRING pFormat)
 {
-  ULONG i, count, esize, SavedMemorySize, MemorySize;
-  unsigned char alignment;
-
   TRACE("(%p,%p)\n", pStubMsg, pFormat);
 
   if (pFormat[0] != RPC_FC_BOGUS_ARRAY)
@@ -4186,29 +4238,9 @@ ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
       return 0;
   }
 
-  alignment = pFormat[1] + 1;
-
-  pFormat += 4;
-
-  pFormat = ReadConformance(pStubMsg, pFormat);
-  pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount);
-
-  align_pointer(&pStubMsg->Buffer, alignment);
-
-  SavedMemorySize = pStubMsg->MemorySize;
-
-  esize = ComplexStructSize(pStubMsg, pFormat);
-
-  MemorySize = safe_multiply(pStubMsg->MaxCount, esize);
-
-  count = pStubMsg->ActualCount;
-  for (i = 0; i < count; i++)
-    ComplexStructMemorySize(pStubMsg, pFormat, NULL);
-
-  pStubMsg->MemorySize = SavedMemorySize;
-
-  pStubMsg->MemorySize += MemorySize;
-  return MemorySize;
+  array_read_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat);
+  array_memory_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pFormat, TRUE /* fHasPointers */);
+  return pStubMsg->MemorySize;
 }
 
 /***********************************************************************




More information about the wine-cvs mailing list