ntdll: Correct 'b' parameter descriptions for _alldiv and _aulldiv.
[wine] / dlls / rpcrt4 / ndr_marshall.c
index 3b5a340..db8be60 100644 (file)
@@ -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>
@@ -139,6 +140,27 @@ static void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STR
 
 static ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
 
+static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
+                                         unsigned char *pMemory,
+                                         PFORMAT_STRING pFormat,
+                                         PFORMAT_STRING pPointer);
+static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                       unsigned char *pMemory,
+                                       PFORMAT_STRING pFormat,
+                                       PFORMAT_STRING pPointer);
+static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                         unsigned char *pMemory,
+                                         PFORMAT_STRING pFormat,
+                                         PFORMAT_STRING pPointer,
+                                         unsigned char fMustAlloc);
+static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
+                                     PFORMAT_STRING pFormat,
+                                     PFORMAT_STRING pPointer);
+static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
+                                   unsigned char *pMemory,
+                                   PFORMAT_STRING pFormat,
+                                   PFORMAT_STRING pPointer);
+
 const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
   0,
   NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
@@ -644,14 +666,16 @@ finish_conf:
 static inline PFORMAT_STRING SkipConformance(PMIDL_STUB_MESSAGE pStubMsg,
                                              PFORMAT_STRING pFormat)
 {
-  if (IsConformanceOrVariancePresent(pFormat))
-  {
     if (pStubMsg->fHasNewCorrDesc)
       pFormat += 6;
     else
       pFormat += 4;
-  }
-  return pFormat;
+    return pFormat;
+}
+
+static inline PFORMAT_STRING SkipVariance(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
+{
+    return SkipConformance( pStubMsg, pFormat );
 }
 
 /* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if
@@ -1657,6 +1681,20 @@ void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char*
         pStubMsg->Buffer += sizeof(USHORT);
         TRACE("value: 0x%08x\n", *(UINT *)pMemory);
         break;
+    case RPC_FC_INT3264:
+        align_pointer(&pStubMsg->Buffer, sizeof(INT));
+        /* 32-bits on the wire, but int_ptr in memory */
+        *(INT_PTR *)pMemory = *(INT *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(INT);
+        TRACE("value: 0x%08lx\n", *(INT_PTR *)pMemory);
+        break;
+    case RPC_FC_UINT3264:
+        align_pointer(&pStubMsg->Buffer, sizeof(UINT));
+        /* 32-bits on the wire, but int_ptr in memory */
+        *(UINT_PTR *)pMemory = *(UINT *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(UINT);
+        TRACE("value: 0x%08lx\n", *(UINT_PTR *)pMemory);
+        break;
     case RPC_FC_IGNORE:
         break;
     default:
@@ -1775,6 +1813,8 @@ static inline void array_compute_and_size_conformance(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
     PFORMAT_STRING pFormat)
 {
+  DWORD count;
+
   switch (fc)
   {
   case RPC_FC_CARRAY:
@@ -1806,6 +1846,13 @@ static inline void array_compute_and_size_conformance(
 
     SizeConformance(pStubMsg);
     break;
+  case RPC_FC_BOGUS_ARRAY:
+    count = *(const WORD *)(pFormat + 2);
+    pFormat += 4;
+    if (IsConformanceOrVariancePresent(pFormat)) SizeConformance(pStubMsg);
+    pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, count);
+    pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
+    break;
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -1816,7 +1863,7 @@ static inline void array_buffer_size(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
     PFORMAT_STRING pFormat, unsigned char fHasPointers)
 {
-  DWORD size;
+  DWORD i, size;
   DWORD esize;
   unsigned char alignment;
 
@@ -1842,7 +1889,7 @@ static inline void array_buffer_size(
     alignment = pFormat[1] + 1;
 
     pFormat = SkipConformance(pStubMsg, pFormat + 4);
-    pFormat = SkipConformance(pStubMsg, pFormat);
+    pFormat = SkipVariance(pStubMsg, pFormat);
 
     SizeVariance(pStubMsg);
 
@@ -1866,6 +1913,18 @@ static inline void array_buffer_size(
     size = safe_multiply(esize, pStubMsg->ActualCount);
     safe_buffer_length_increment(pStubMsg, size);
     break;
+  case RPC_FC_BOGUS_ARRAY:
+    alignment = pFormat[1] + 1;
+    pFormat = SkipConformance(pStubMsg, pFormat + 4);
+    if (IsConformanceOrVariancePresent(pFormat)) SizeVariance(pStubMsg);
+    pFormat = SkipVariance(pStubMsg, pFormat);
+
+    align_length(&pStubMsg->BufferLength, alignment);
+
+    size = pStubMsg->ActualCount;
+    for (i = 0; i < size; i++)
+      pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
+    break;
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -1876,6 +1935,9 @@ static inline void array_compute_and_write_conformance(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
     PFORMAT_STRING pFormat)
 {
+  ULONG def;
+  BOOL conformance_present;
+
   switch (fc)
   {
   case RPC_FC_CARRAY:
@@ -1906,6 +1968,14 @@ static inline void array_compute_and_write_conformance(
     pStubMsg->Offset = 0;
     WriteConformance(pStubMsg);
     break;
+  case RPC_FC_BOGUS_ARRAY:
+    def = *(const WORD *)(pFormat + 2);
+    pFormat += 4;
+    conformance_present = IsConformanceOrVariancePresent(pFormat);
+    pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
+    pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
+    if (conformance_present) WriteConformance(pStubMsg);
+    break;
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -1916,7 +1986,7 @@ static inline void array_write_variance_and_marshall(
     unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory,
     PFORMAT_STRING pFormat, unsigned char fHasPointers)
 {
-  DWORD size;
+  DWORD i, size;
   DWORD esize;
   unsigned char alignment;
 
@@ -1942,10 +2012,8 @@ static inline void array_write_variance_and_marshall(
     esize = *(const WORD*)(pFormat+2);
     alignment = pFormat[1] + 1;
 
-    /* conformance */
     pFormat = SkipConformance(pStubMsg, pFormat + 4);
-    /* variance */
-    pFormat = SkipConformance(pStubMsg, pFormat);
+    pFormat = SkipVariance(pStubMsg, pFormat);
 
     WriteVariance(pStubMsg);
 
@@ -1972,6 +2040,18 @@ static inline void array_write_variance_and_marshall(
     size = safe_multiply(esize, pStubMsg->ActualCount);
     safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */
     break;
+  case RPC_FC_BOGUS_ARRAY:
+    alignment = pFormat[1] + 1;
+    pFormat = SkipConformance(pStubMsg, pFormat + 4);
+    if (IsConformanceOrVariancePresent(pFormat)) WriteVariance(pStubMsg);
+    pFormat = SkipVariance(pStubMsg, pFormat);
+
+    align_pointer_clear(&pStubMsg->Buffer, alignment);
+
+    size = pStubMsg->ActualCount;
+    for (i = 0; i < size; i++)
+      pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
+    break;
   default:
     ERR("unknown array format 0x%x\n", fc);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
@@ -1981,7 +2061,7 @@ 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;
 
   switch (fc)
   {
@@ -2005,6 +2085,19 @@ static inline ULONG array_read_conformance(
     else
       ReadConformance(pStubMsg, NULL);
     return safe_multiply(esize, pStubMsg->MaxCount);
+  case RPC_FC_BOGUS_ARRAY:
+    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 );
+
+    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);
@@ -2019,8 +2112,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)
   {
@@ -2139,6 +2232,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);
@@ -2149,6 +2267,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;
@@ -2221,6 +2340,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);
@@ -2231,6 +2368,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:
@@ -2248,6 +2387,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);
@@ -2609,6 +2757,8 @@ static ULONG EmbeddedComplexSize(MIDL_STUB_MESSAGE *pStubMsg,
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
     case RPC_FC_ENUM32:
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
         return sizeof(ULONG);
     case RPC_FC_FLOAT:
         return sizeof(float);
@@ -2685,12 +2835,15 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
       pMemory += 2;
       break;
     case RPC_FC_ENUM16:
+    {
+      USHORT val = *(DWORD *)pMemory;
       TRACE("enum16=%d <= %p\n", *(DWORD*)pMemory, pMemory);
       if (32767 < *(DWORD*)pMemory)
         RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
-      safe_copy_to_buffer(pStubMsg, pMemory, 2);
+      safe_copy_to_buffer(pStubMsg, &val, 2);
       pMemory += 4;
       break;
+    }
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
     case RPC_FC_ENUM32:
@@ -2698,6 +2851,15 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
       safe_copy_to_buffer(pStubMsg, pMemory, 4);
       pMemory += 4;
       break;
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+    {
+      UINT val = *(UINT_PTR *)pMemory;
+      TRACE("int3264=%ld <= %p\n", *(UINT_PTR *)pMemory, pMemory);
+      safe_copy_to_buffer(pStubMsg, &val, sizeof(UINT));
+      pMemory += sizeof(UINT_PTR);
+      break;
+    }
     case RPC_FC_FLOAT:
       TRACE("float=%f <= %p\n", *(float*)pMemory, pMemory);
       safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
@@ -2832,13 +2994,16 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
       pMemory += 2;
       break;
     case RPC_FC_ENUM16:
-      safe_copy_from_buffer(pStubMsg, pMemory, 2);
-      *(DWORD*)pMemory &= 0xffff;
+    {
+      WORD val;
+      safe_copy_from_buffer(pStubMsg, &val, 2);
+      *(DWORD*)pMemory = val;
       TRACE("enum16=%d => %p\n", *(DWORD*)pMemory, pMemory);
       if (32767 < *(DWORD*)pMemory)
         RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
       pMemory += 4;
       break;
+    }
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
     case RPC_FC_ENUM32:
@@ -2846,6 +3011,24 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
       TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory);
       pMemory += 4;
       break;
+    case RPC_FC_INT3264:
+    {
+      INT val;
+      safe_copy_from_buffer(pStubMsg, &val, 4);
+      *(INT_PTR *)pMemory = val;
+      TRACE("int3264=%ld => %p\n", *(INT_PTR*)pMemory, pMemory);
+      pMemory += sizeof(INT_PTR);
+      break;
+    }
+    case RPC_FC_UINT3264:
+    {
+      UINT val;
+      safe_copy_from_buffer(pStubMsg, &val, 4);
+      *(UINT_PTR *)pMemory = val;
+      TRACE("uint3264=%ld => %p\n", *(UINT_PTR*)pMemory, pMemory);
+      pMemory += sizeof(UINT_PTR);
+      break;
+    }
     case RPC_FC_FLOAT:
       safe_copy_from_buffer(pStubMsg, pMemory, sizeof(float));
       TRACE("float=%f => %p\n", *(float*)pMemory, pMemory);
@@ -2994,6 +3177,11 @@ static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
       safe_buffer_length_increment(pStubMsg, 4);
       pMemory += 4;
       break;
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+      safe_buffer_length_increment(pStubMsg, 4);
+      pMemory += sizeof(INT_PTR);
+      break;
     case RPC_FC_HYPER:
     case RPC_FC_DOUBLE:
       safe_buffer_length_increment(pStubMsg, 8);
@@ -3107,6 +3295,10 @@ static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
     case RPC_FC_FLOAT:
       pMemory += 4;
       break;
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+      pMemory += sizeof(INT_PTR);
+      break;
     case RPC_FC_HYPER:
     case RPC_FC_DOUBLE:
       pMemory += 8;
@@ -3207,6 +3399,11 @@ static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
       size += 4;
       safe_buffer_increment(pStubMsg, 4);
       break;
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+      size += sizeof(INT_PTR);
+      safe_buffer_increment(pStubMsg, 4);
+      break;
     case RPC_FC_HYPER:
     case RPC_FC_DOUBLE:
       size += 8;
@@ -3312,6 +3509,10 @@ ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
     case RPC_FC_FLOAT:
       size += 4;
       break;
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+      size += sizeof(INT_PTR);
+      break;
     case RPC_FC_HYPER:
     case RPC_FC_DOUBLE:
       size += 8;
@@ -3920,9 +4121,6 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
                                                unsigned char *pMemory,
                                                PFORMAT_STRING pFormat)
 {
-  ULONG i, count, def;
-  BOOL variance_present;
-  unsigned char alignment;
   int pointer_buffer_mark_set = 0;
 
   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
@@ -3934,8 +4132,6 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
       return NULL;
   }
 
-  alignment = pFormat[1] + 1;
-
   if (!pStubMsg->PointerBufferMark)
   {
     /* save buffer fields that may be changed by buffer sizer functions
@@ -3965,25 +4161,9 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
     pStubMsg->BufferLength = saved_buffer_length;
   }
 
-  def = *(const WORD*)&pFormat[2];
-  pFormat += 4;
-
-  pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
-  TRACE("conformance = %ld\n", pStubMsg->MaxCount);
-
-  variance_present = IsConformanceOrVariancePresent(pFormat);
-  pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
-  TRACE("variance = %d\n", pStubMsg->ActualCount);
-
-  WriteConformance(pStubMsg);
-  if (variance_present)
-    WriteVariance(pStubMsg);
-
-  align_pointer_clear(&pStubMsg->Buffer, alignment);
-
-  count = pStubMsg->ActualCount;
-  for (i = 0; i < count; i++)
-    pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL);
+  array_compute_and_write_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
+  array_write_variance_and_marshall(RPC_FC_BOGUS_ARRAY, pStubMsg,
+                                    pMemory, pFormat, TRUE /* fHasPointers */);
 
   STD_OVERFLOW_CHECK(pStubMsg);
 
@@ -4004,9 +4184,6 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
                                                  PFORMAT_STRING pFormat,
                                                  unsigned char fMustAlloc)
 {
-  ULONG i, count, size;
-  unsigned char alignment;
-  unsigned char *pMemory;
   unsigned char *saved_buffer;
   int pointer_buffer_mark_set = 0;
   int saved_ignore_embedded;
@@ -4020,8 +4197,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;
@@ -4030,7 +4205,6 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
   pStubMsg->IgnoreEmbeddedPointers = 1;
   pStubMsg->MemorySize = 0;
   NdrComplexArrayMemorySize(pStubMsg, pFormat);
-  size = pStubMsg->MemorySize;
   pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded;
 
   TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - saved_buffer));
@@ -4043,22 +4217,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)
   {
@@ -4076,9 +4237,6 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
                                       unsigned char *pMemory,
                                       PFORMAT_STRING pFormat)
 {
-  ULONG i, count, def;
-  unsigned char alignment;
-  BOOL variance_present;
   int pointer_length_set = 0;
 
   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
@@ -4090,8 +4248,6 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
       return;
   }
 
-  alignment = pFormat[1] + 1;
-
   if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
   {
     /* save buffer fields that may be changed by buffer sizer functions
@@ -4118,25 +4274,9 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
     pStubMsg->MaxCount = saved_max_count;
     pStubMsg->BufferLength = saved_buffer_length;
   }
-  def = *(const WORD*)&pFormat[2];
-  pFormat += 4;
 
-  pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def);
-  TRACE("conformance = %ld\n", pStubMsg->MaxCount);
-  SizeConformance(pStubMsg);
-
-  variance_present = IsConformanceOrVariancePresent(pFormat);
-  pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount);
-  TRACE("variance = %d\n", pStubMsg->ActualCount);
-
-  if (variance_present)
-    SizeVariance(pStubMsg);
-
-  align_length(&pStubMsg->BufferLength, alignment);
-
-  count = pStubMsg->ActualCount;
-  for (i = 0; i < count; i++)
-    pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL);
+  array_compute_and_size_conformance(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat);
+  array_buffer_size(RPC_FC_BOGUS_ARRAY, pStubMsg, pMemory, pFormat, TRUE /* fHasPointers */);
 
   if(pointer_length_set)
   {
@@ -4151,9 +4291,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)
@@ -4163,29 +4300,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;
 }
 
 /***********************************************************************
@@ -5524,6 +5641,9 @@ static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory)
     case RPC_FC_ULONG:
     case RPC_FC_ENUM32:
         return *(const ULONG *)pMemory;
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+        return *(const ULONG_PTR *)pMemory;
     default:
         FIXME("Unhandled base type: 0x%02x\n", fc);
         return 0;
@@ -6489,16 +6609,24 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
         TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
         break;
     case RPC_FC_ENUM16:
+    {
+        USHORT val = *(UINT *)pMemory;
         /* only 16-bits on the wire, so do a sanity check */
         if (*(UINT *)pMemory > SHRT_MAX)
             RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
         align_pointer_clear(&pStubMsg->Buffer, sizeof(USHORT));
-        if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
-            RpcRaiseException(RPC_X_BAD_STUB_DATA);
-        *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
-        pStubMsg->Buffer += sizeof(USHORT);
+        safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
         TRACE("value: 0x%04x\n", *(UINT *)pMemory);
         break;
+    }
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+    {
+        UINT val = *(UINT_PTR *)pMemory;
+        align_pointer_clear(&pStubMsg->Buffer, sizeof(UINT));
+        safe_copy_to_buffer(pStubMsg, &val, sizeof(val));
+        break;
+    }
     case RPC_FC_IGNORE:
         break;
     default:
@@ -6520,7 +6648,7 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall(
 {
     TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
 
-#define BASE_TYPE_UNMARSHALL(type) \
+#define BASE_TYPE_UNMARSHALL(type) do { \
         align_pointer(&pStubMsg->Buffer, sizeof(type)); \
         if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \
         { \
@@ -6534,7 +6662,8 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall(
                 *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \
             TRACE("*ppMemory: %p\n", *ppMemory); \
             safe_copy_from_buffer(pStubMsg, *ppMemory, sizeof(type)); \
-        }
+        } \
+    } while (0)
 
     switch(*pFormat)
     {
@@ -6571,19 +6700,49 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall(
         TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
         break;
     case RPC_FC_ENUM16:
+    {
+        USHORT val;
         align_pointer(&pStubMsg->Buffer, sizeof(USHORT));
         if (!fMustAlloc && !*ppMemory)
             fMustAlloc = TRUE;
         if (fMustAlloc)
             *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT));
-        if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd)
-            RpcRaiseException(RPC_X_BAD_STUB_DATA);
-        TRACE("*ppMemory: %p\n", *ppMemory);
+        safe_copy_from_buffer(pStubMsg, &val, sizeof(USHORT));
         /* 16-bits on the wire, but int in memory */
-        **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
-        pStubMsg->Buffer += sizeof(USHORT);
+        **(UINT **)ppMemory = val;
         TRACE("value: 0x%08x\n", **(UINT **)ppMemory);
         break;
+    }
+    case RPC_FC_INT3264:
+        if (sizeof(INT_PTR) == sizeof(INT)) BASE_TYPE_UNMARSHALL(INT);
+        else
+        {
+            INT val;
+            align_pointer(&pStubMsg->Buffer, sizeof(INT));
+            if (!fMustAlloc && !*ppMemory)
+                fMustAlloc = TRUE;
+            if (fMustAlloc)
+                *ppMemory = NdrAllocate(pStubMsg, sizeof(INT_PTR));
+            safe_copy_from_buffer(pStubMsg, &val, sizeof(INT));
+            **(INT_PTR **)ppMemory = val;
+            TRACE("value: 0x%08lx\n", **(INT_PTR **)ppMemory);
+        }
+        break;
+    case RPC_FC_UINT3264:
+        if (sizeof(UINT_PTR) == sizeof(UINT)) BASE_TYPE_UNMARSHALL(UINT);
+        else
+        {
+            UINT val;
+            align_pointer(&pStubMsg->Buffer, sizeof(UINT));
+            if (!fMustAlloc && !*ppMemory)
+                fMustAlloc = TRUE;
+            if (fMustAlloc)
+                *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT_PTR));
+            safe_copy_from_buffer(pStubMsg, &val, sizeof(UINT));
+            **(UINT_PTR **)ppMemory = val;
+            TRACE("value: 0x%08lx\n", **(UINT_PTR **)ppMemory);
+        }
+        break;
     case RPC_FC_IGNORE:
         break;
     default:
@@ -6624,6 +6783,8 @@ static void WINAPI NdrBaseTypeBufferSize(
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
     case RPC_FC_ENUM32:
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
         align_length(&pStubMsg->BufferLength, sizeof(ULONG));
         safe_buffer_length_increment(pStubMsg, sizeof(ULONG));
         break;
@@ -6714,6 +6875,13 @@ static ULONG WINAPI NdrBaseTypeMemorySize(
         align_length(&pStubMsg->MemorySize, sizeof(UINT));
         pStubMsg->MemorySize += sizeof(UINT);
         return sizeof(UINT);
+    case RPC_FC_INT3264:
+    case RPC_FC_UINT3264:
+        align_pointer(&pStubMsg->Buffer, sizeof(UINT));
+        safe_buffer_increment(pStubMsg, sizeof(UINT));
+        align_length(&pStubMsg->MemorySize, sizeof(UINT_PTR));
+        pStubMsg->MemorySize += sizeof(UINT_PTR);
+        return sizeof(UINT_PTR);
     case RPC_FC_IGNORE:
         align_length(&pStubMsg->MemorySize, sizeof(void *));
         pStubMsg->MemorySize += sizeof(void *);