Sync to Wine-0_9_5:
[reactos.git] / reactos / lib / rpcrt4 / ndr_marshall.c
index 72cce6f..4156a0e 100644 (file)
@@ -97,18 +97,28 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
 #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
 
 #define STD_OVERFLOW_CHECK(_Msg) do { \
-    TRACE("buffer=%d/%ld\n", _Msg->Buffer - _Msg->BufferStart, _Msg->BufferLength); \
-    if (_Msg->Buffer > _Msg->BufferEnd) ERR("buffer overflow %d bytes\n", _Msg->Buffer - _Msg->BufferEnd); \
+    TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \
+    if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \
+        ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \
   } while (0)
 
 #define NDR_TABLE_SIZE 128
 #define NDR_TABLE_MASK 127
 
+static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
+static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char);
+static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
+static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING);
+static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING);
+
 NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  /* 0x10 */
   0,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  /* 0x10 */
+  NdrBaseTypeMarshall,
   /* 0x11 */
   NdrPointerMarshall, NdrPointerMarshall,
   NdrPointerMarshall, NdrPointerMarshall,
@@ -125,7 +135,8 @@ NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
   NdrComplexArrayMarshall,
   /* 0x22 */
   NdrConformantStringMarshall, 0, 0,
-  NdrConformantStringMarshall, 0, 0, 0, 0,
+  NdrConformantStringMarshall,
+  NdrNonConformantStringMarshall, 0, 0, 0,
   /* 0x2a */
   NdrEncapsulatedUnionMarshall,
   NdrNonEncapsulatedUnionMarshall,
@@ -138,10 +149,13 @@ NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = {
   NdrUserMarshalMarshall
 };
 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  /* 0x10 */
   0,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  /* 0x10 */
+  NdrBaseTypeUnmarshall,
   /* 0x11 */
   NdrPointerUnmarshall, NdrPointerUnmarshall,
   NdrPointerUnmarshall, NdrPointerUnmarshall,
@@ -158,7 +172,8 @@ NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
   NdrComplexArrayUnmarshall,
   /* 0x22 */
   NdrConformantStringUnmarshall, 0, 0,
-  NdrConformantStringUnmarshall, 0, 0, 0, 0,
+  NdrConformantStringUnmarshall,
+  NdrNonConformantStringUnmarshall, 0, 0, 0,
   /* 0x2a */
   NdrEncapsulatedUnionUnmarshall,
   NdrNonEncapsulatedUnionUnmarshall,
@@ -171,10 +186,13 @@ NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
   NdrUserMarshalUnmarshall
 };
 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  /* 0x10 */
   0,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  /* 0x10 */
+  NdrBaseTypeBufferSize,
   /* 0x11 */
   NdrPointerBufferSize, NdrPointerBufferSize,
   NdrPointerBufferSize, NdrPointerBufferSize,
@@ -191,7 +209,8 @@ NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
   NdrComplexArrayBufferSize,
   /* 0x22 */
   NdrConformantStringBufferSize, 0, 0,
-  NdrConformantStringBufferSize, 0, 0, 0, 0,
+  NdrConformantStringBufferSize,
+  NdrNonConformantStringBufferSize, 0, 0, 0,
   /* 0x2a */
   NdrEncapsulatedUnionBufferSize,
   NdrNonEncapsulatedUnionBufferSize,
@@ -204,10 +223,13 @@ NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
   NdrUserMarshalBufferSize
 };
 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  /* 0x10 */
   0,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  /* 0x10 */
+  NdrBaseTypeMemorySize,
   /* 0x11 */
   NdrPointerMemorySize, NdrPointerMemorySize,
   NdrPointerMemorySize, NdrPointerMemorySize,
@@ -220,7 +242,8 @@ NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
   NdrComplexArrayMemorySize,
   /* 0x22 */
   NdrConformantStringMemorySize, 0, 0,
-  NdrConformantStringMemorySize, 0, 0, 0, 0,
+  NdrConformantStringMemorySize,
+  NdrNonConformantStringMemorySize, 0, 0, 0,
   /* 0x2a */
   0, 0, 0, 0, 0,
   /* 0x2f */
@@ -230,10 +253,13 @@ NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
   NdrUserMarshalMemorySize
 };
 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  /* 0x10 */
   0,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  /* 0x10 */
+  NdrBaseTypeFree,
   /* 0x11 */
   NdrPointerFree, NdrPointerFree,
   NdrPointerFree, NdrPointerFree,
@@ -282,46 +308,56 @@ PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pForm
   return pFormat+4;
 }
 
-PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
-                                  PFORMAT_STRING pFormat, ULONG_PTR def)
+static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat)
+{
+  pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
+  pStubMsg->Buffer += 4;
+  TRACE("unmarshalled variance is %ld\n", pStubMsg->ActualCount);
+  return pFormat+4;
+}
+
+PFORMAT_STRING ComputeConformanceOrVariance(
+    MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
+    PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount)
 {
   BYTE dtype = pFormat[0] & 0xf;
-  DWORD ofs = (DWORD)pFormat[2] | ((DWORD)pFormat[3] << 8);
+  short ofs = *(short *)&pFormat[2];
   LPVOID ptr = NULL;
   DWORD data = 0;
 
+  /* FIXME: is this correct? */
   if (pFormat[0] == 0xff) {
     /* null descriptor */
-    pStubMsg->MaxCount = def;
+    *pCount = def;
     goto finish_conf;
   }
 
   switch (pFormat[0] & 0xf0) {
   case RPC_FC_NORMAL_CONFORMANCE:
-    TRACE("normal conformance, ofs=%ld\n", ofs);
+    TRACE("normal conformance, ofs=%d\n", ofs);
     ptr = pMemory + ofs;
     break;
   case RPC_FC_POINTER_CONFORMANCE:
-    TRACE("pointer conformance, ofs=%ld\n", ofs);
+    TRACE("pointer conformance, ofs=%d\n", ofs);
     ptr = pStubMsg->Memory + ofs;
     break;
   case RPC_FC_TOP_LEVEL_CONFORMANCE:
-    TRACE("toplevel conformance, ofs=%ld\n", ofs);
+    TRACE("toplevel conformance, ofs=%d\n", ofs);
     if (pStubMsg->StackTop) {
       ptr = pStubMsg->StackTop + ofs;
     }
     else {
-      /* -Os mode, MaxCount is already set */
+      /* -Os mode, *pCount is already set */
       goto finish_conf;
     }
     break;
   case RPC_FC_CONSTANT_CONFORMANCE:
     data = ofs | ((DWORD)pFormat[1] << 16);
     TRACE("constant conformance, val=%ld\n", data);
-    pStubMsg->MaxCount = data;
+    *pCount = data;
     goto finish_conf;
   case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE:
-    FIXME("toplevel multidimensional conformance, ofs=%ld\n", ofs);
+    FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs);
     if (pStubMsg->StackTop) {
       ptr = pStubMsg->StackTop + ofs;
     }
@@ -339,9 +375,17 @@ PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pM
     ptr = *(LPVOID*)ptr;
     break;
   case RPC_FC_CALLBACK:
+  {
+    unsigned char *old_stack_top = pStubMsg->StackTop;
+    pStubMsg->StackTop = ptr;
+
     /* ofs is index into StubDesc->apfnExprEval */
-    FIXME("handle callback\n");
+    TRACE("callback conformance into apfnExprEval[%d]\n", ofs);
+    pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg);
+
+    pStubMsg->StackTop = old_stack_top;
     goto finish_conf;
+  }
   default:
     break;
   }
@@ -372,7 +416,7 @@ PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pM
 done_conf_grab:
   switch (pFormat[1]) {
   case 0: /* no op */
-    pStubMsg->MaxCount = data;
+    *pCount = data;
     break;
   case RPC_FC_DEREFERENCE:
     /* already handled */
@@ -383,7 +427,7 @@ done_conf_grab:
   }
 
 finish_conf:
-  TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
+  TRACE("resulting conformance is %ld\n", *pCount);
   return pFormat+4;
 }
 
@@ -478,8 +522,8 @@ void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
   }
   else if (*pFormat == RPC_FC_C_CSTRING) {
     /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
-    TRACE("string=%s\n", debugstr_a(pMemory));
-    pStubMsg->BufferLength += strlen(pMemory) + 13 + BUFFER_PARANOIA;
+    TRACE("string=%s\n", debugstr_a((char*)pMemory));
+    pStubMsg->BufferLength += strlen((char*)pMemory) + 13 + BUFFER_PARANOIA;
   }
   else if (*pFormat == RPC_FC_C_WSTRING) {
     /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */
@@ -534,7 +578,6 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
   unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc )
 {
   unsigned long len, esize, ofs;
-  unsigned char *pMem;
 
   TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
     pStubMsg, *ppMemory, pFormat, fMustAlloc);
@@ -559,38 +602,66 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
     FIXME("sized string format=%d\n", pFormat[1]);
   }
 
-  if (fMustAlloc) {
+  if (fMustAlloc || !*ppMemory)
     *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA);
-  } else {
-    if (pStubMsg->ReuseBuffer && !*ppMemory)
-      /* for servers, we may just point straight into the RPC buffer, I think
-       * (I guess that's what MS does since MIDL code doesn't try to free) */
-      *ppMemory = pStubMsg->Buffer - ofs*esize;
-    /* for clients, memory should be provided by caller */
-  }
 
-  if (len == 0) {
-    *ppMemory = NULL;
-    return NULL;
-  }
-
-  pMem = *ppMemory + ofs*esize;
-
-  if (pMem != pStubMsg->Buffer)
-    memcpy(pMem, pStubMsg->Buffer, len*esize);
+  memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
 
   pStubMsg->Buffer += len*esize;
 
   if (*pFormat == RPC_FC_C_CSTRING) {
-    TRACE("string=%s\n", debugstr_a(pMem));
+    TRACE("string=%s\n", debugstr_a((char*)*ppMemory));
   }
   else if (*pFormat == RPC_FC_C_WSTRING) {
-    TRACE("string=%s\n", debugstr_w((LPWSTR)pMem));
+    TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory));
   }
 
   return NULL; /* FIXME: is this always right? */
 }
 
+/***********************************************************************
+ *           NdrNonConformantStringMarshall [RPCRT4.@]
+ */
+unsigned char *  WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                unsigned char *pMemory,
+                                PFORMAT_STRING pFormat)
+{
+    FIXME("stub\n");
+    return NULL;
+}
+
+/***********************************************************************
+ *           NdrNonConformantStringUnmarshall [RPCRT4.@]
+ */
+unsigned char *  WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                unsigned char **ppMemory,
+                                PFORMAT_STRING pFormat,
+                                unsigned char fMustAlloc)
+{
+    FIXME("stub\n");
+    return NULL;
+}
+
+/***********************************************************************
+ *           NdrNonConformantStringBufferSize [RPCRT4.@]
+ */
+void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
+                                unsigned char *pMemory,
+                                PFORMAT_STRING pFormat)
+{
+    FIXME("stub\n");
+}
+
+/***********************************************************************
+ *           NdrNonConformantStringMemorySize [RPCRT4.@]
+ */
+unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
+                                PFORMAT_STRING pFormat)
+{
+    FIXME("stub\n");
+    return 0;
+}
+
 static inline void dump_pointer_attr(unsigned char attr)
 {
     if (attr & RPC_FC_P_ALLOCALLNODES)
@@ -691,14 +762,17 @@ void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
     pStubMsg->Buffer += 4;
     break;
   case RPC_FC_OP: /* object pointer - we must free data before overwriting it */
+    pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
+    pStubMsg->Buffer += 4;
+    if (*pPointer)
+        FIXME("free object pointer %p\n", *pPointer);
+    break;
   case RPC_FC_FP:
   default:
     FIXME("unhandled ptr type=%02x\n", type);
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
   }
 
-  *pPointer = NULL;
-
   if (pointer_id) {
     m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
     if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
@@ -1379,6 +1453,7 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
       break;
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
+    case RPC_FC_ENUM32:
       TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory);
       memcpy(pStubMsg->Buffer, pMemory, 4);
       pStubMsg->Buffer += 4;
@@ -1396,6 +1471,9 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
     case RPC_FC_ALIGNM8:
       ALIGN_POINTER(pMemory, 7);
       break;
+    case RPC_FC_STRUCTPAD2:
+      pMemory += 2;
+      break;
     case RPC_FC_EMBEDDED_COMPLEX:
       pMemory += pFormat[1];
       pFormat += 2;
@@ -1440,6 +1518,7 @@ unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
       break;
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
+    case RPC_FC_ENUM32:
       memcpy(pMemory, pStubMsg->Buffer, 4);
       TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory);
       pStubMsg->Buffer += 4;
@@ -1458,6 +1537,9 @@ unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
     case RPC_FC_ALIGNM8:
       ALIGN_POINTER(pMemory, 7);
       break;
+    case RPC_FC_STRUCTPAD2:
+      pMemory += 2;
+      break;
     case RPC_FC_EMBEDDED_COMPLEX:
       pMemory += pFormat[1];
       pFormat += 2;
@@ -1500,6 +1582,7 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
       break;
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
+    case RPC_FC_ENUM32:
       pStubMsg->BufferLength += 4;
       pMemory += 4;
       break;
@@ -1514,6 +1597,9 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
     case RPC_FC_ALIGNM8:
       ALIGN_POINTER(pMemory, 7);
       break;
+    case RPC_FC_STRUCTPAD2:
+      pMemory += 2;
+      break;
     case RPC_FC_EMBEDDED_COMPLEX:
       pMemory += pFormat[1];
       pFormat += 2;
@@ -1553,6 +1639,7 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
       break;
     case RPC_FC_LONG:
     case RPC_FC_ULONG:
+    case RPC_FC_ENUM32:
       pMemory += 4;
       break;
     case RPC_FC_POINTER:
@@ -1566,6 +1653,9 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg,
     case RPC_FC_ALIGNM8:
       ALIGN_POINTER(pMemory, 7);
       break;
+    case RPC_FC_STRUCTPAD2:
+      pMemory += 2;
+      break;
     case RPC_FC_EMBEDDED_COMPLEX:
       pMemory += pFormat[1];
       pFormat += 2;
@@ -1613,6 +1703,9 @@ unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg,
     case RPC_FC_ALIGNM8:
       ALIGN_LENGTH(size, 7);
       break;
+    case RPC_FC_STRUCTPAD2:
+      size += 2;
+      break;
     case RPC_FC_EMBEDDED_COMPLEX:
       size += pFormat[1];
       pFormat += 2;
@@ -1818,18 +1911,10 @@ unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
   pFormat = ReadConformance(pStubMsg, pFormat+4);
   size = pStubMsg->MaxCount;
 
-  if (fMustAlloc) {
+  if (fMustAlloc || !*ppMemory)
     *ppMemory = NdrAllocate(pStubMsg, size*esize);
-    memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
-  } else {
-    if (pStubMsg->ReuseBuffer && !*ppMemory)
-      /* for servers, we may just point straight into the RPC buffer, I think
-       * (I guess that's what MS does since MIDL code doesn't try to free) */
-      *ppMemory = pStubMsg->Buffer;
-    else
-      /* for clients, memory should be provided by caller */
-      memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
-  }
+
+  memcpy(*ppMemory, pStubMsg->Buffer, size*esize);
 
   pStubMsg->BufferMark = pStubMsg->Buffer;
   pStubMsg->Buffer += size*esize;
@@ -1853,7 +1938,8 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
   pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0);
   size = pStubMsg->MaxCount;
 
-  pStubMsg->BufferLength += size*esize;
+  /* conformance value plus array */
+  pStubMsg->BufferLength += sizeof(DWORD) + size*esize;
 
   EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
 }
@@ -1864,16 +1950,18 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
 unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg,
                                                   PFORMAT_STRING pFormat)
 {
-  DWORD size = 0;
-  FIXME("(%p,%p): stub\n", pStubMsg, pFormat);
+  DWORD size = 0, esize = *(const WORD*)(pFormat+2);
+  unsigned char *buffer;
+
+  TRACE("(%p,%p)\n", pStubMsg, pFormat);
   if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]);
 
+  buffer = pStubMsg->Buffer;
   pFormat = ReadConformance(pStubMsg, pFormat+4);
+  pStubMsg->Buffer = buffer;
   size = pStubMsg->MaxCount;
 
-  EmbeddedPointerMemorySize(pStubMsg, pFormat);
-
-  return 0;
+  return size*esize;
 }
 
 /***********************************************************************
@@ -1897,7 +1985,35 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu
                                                          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;
 }
 
@@ -1910,7 +2026,29 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS
                                                            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;
 }
 
@@ -1932,7 +2070,26 @@ void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg,
 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);
 }
 
 
@@ -2221,6 +2378,14 @@ void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, lo
      is to raise an exception */
 }
 
+typedef struct _NDR_CSTRUCT_FORMAT
+{
+    unsigned char type;
+    unsigned char alignment;
+    unsigned short memory_size;
+    short offset_to_array_description;
+} NDR_CSTRUCT_FORMAT;
+
 /***********************************************************************
  *           NdrConformantStructMarshall [RPCRT4.@]
  */
@@ -2228,7 +2393,32 @@ unsigned char *  WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
                                 unsigned char *pMemory,
                                 PFORMAT_STRING pFormat)
 {
-    FIXME("stub\n");
+    const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
+    pFormat += sizeof(NDR_CSTRUCT_FORMAT);
+
+    TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
+
+    if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
+    {
+        ERR("invalid format type %x\n", pCStructFormat->type);
+        RpcRaiseException(RPC_S_INTERNAL_ERROR);
+        return NULL;
+    }
+
+    TRACE("memory_size = %d\n", pCStructFormat->memory_size);
+
+    /* copy constant sized part of struct */
+    memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size);
+    pStubMsg->Buffer += pCStructFormat->memory_size;
+
+    if (pCStructFormat->offset_to_array_description)
+    {
+        PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
+            pCStructFormat->offset_to_array_description;
+        NdrConformantArrayMarshall(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat);
+    }
+    if (pCStructFormat->type == RPC_FC_CPSTRUCT)
+        EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
     return NULL;
 }
 
@@ -2240,7 +2430,52 @@ unsigned char *  WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMs
                                 PFORMAT_STRING pFormat,
                                 unsigned char fMustAlloc)
 {
-    FIXME("stub\n");
+    const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
+    pFormat += sizeof(NDR_CSTRUCT_FORMAT);
+
+    TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
+
+    if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
+    {
+        ERR("invalid format type %x\n", pCStructFormat->type);
+        RpcRaiseException(RPC_S_INTERNAL_ERROR);
+        return NULL;
+    }
+
+    TRACE("memory_size = %d\n", pCStructFormat->memory_size);
+
+    /* work out how much memory to allocate if we need to do so */
+    if (!*ppMemory || fMustAlloc)
+    {
+        SIZE_T size = pCStructFormat->memory_size;
+    
+        if (pCStructFormat->offset_to_array_description)
+        {
+            unsigned char *buffer;
+            PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
+                pCStructFormat->offset_to_array_description;
+            buffer = pStubMsg->Buffer;
+            pStubMsg->Buffer += pCStructFormat->memory_size;
+            size += NdrConformantArrayMemorySize(pStubMsg, pArrayFormat);
+            pStubMsg->Buffer = buffer;
+        }
+        *ppMemory = NdrAllocate(pStubMsg, size);
+    }
+
+    /* now copy the data */
+    memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size);
+    pStubMsg->Buffer += pCStructFormat->memory_size;
+    if (pCStructFormat->offset_to_array_description)
+    {
+        PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
+            pCStructFormat->offset_to_array_description;
+        unsigned char *pMemoryArray = *ppMemory + pCStructFormat->memory_size;
+        /* note that we pass fMustAlloc as 0 as we have already allocated the
+         * memory */
+        NdrConformantArrayUnmarshall(pStubMsg, &pMemoryArray, pArrayFormat, 0);
+    }
+    if (pCStructFormat->type == RPC_FC_CPSTRUCT)
+        EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc);
     return NULL;
 }
 
@@ -2251,7 +2486,30 @@ void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
                                 unsigned char *pMemory,
                                 PFORMAT_STRING pFormat)
 {
-    FIXME("stub\n");
+    const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat;
+    pFormat += sizeof(NDR_CSTRUCT_FORMAT);
+    TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat);
+
+    if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT))
+    {
+        ERR("invalid format type %x\n", pCStructFormat->type);
+        RpcRaiseException(RPC_S_INTERNAL_ERROR);
+        return;
+    }
+
+    TRACE("memory_size = %d\n", pCStructFormat->memory_size);
+
+    /* add constant sized part of struct to buffer size */
+    pStubMsg->BufferLength += pCStructFormat->memory_size;
+
+    if (pCStructFormat->offset_to_array_description)
+    {
+        PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description +
+            pCStructFormat->offset_to_array_description;
+        NdrConformantArrayBufferSize(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat);
+    }
+    if (pCStructFormat->type == RPC_FC_CPSTRUCT)
+        EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
 }
 
 /***********************************************************************
@@ -2645,6 +2903,242 @@ void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg,
     FIXME("stub\n");
 }
 
+/***********************************************************************
+ *           NdrBaseTypeMarshall [internal]
+ */
+static unsigned char *WINAPI NdrBaseTypeMarshall(
+    PMIDL_STUB_MESSAGE pStubMsg,
+    unsigned char *pMemory,
+    PFORMAT_STRING pFormat)
+{
+    TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
+
+    switch(*pFormat)
+    {
+    case RPC_FC_BYTE:
+    case RPC_FC_CHAR:
+    case RPC_FC_SMALL:
+    case RPC_FC_USMALL:
+        *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory;
+        pStubMsg->Buffer += sizeof(UCHAR);
+        TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
+        break;
+    case RPC_FC_WCHAR:
+    case RPC_FC_SHORT:
+    case RPC_FC_USHORT:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1);
+        *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory;
+        pStubMsg->Buffer += sizeof(USHORT);
+        TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
+        break;
+    case RPC_FC_LONG:
+    case RPC_FC_ULONG:
+    case RPC_FC_ERROR_STATUS_T:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1);
+        *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory;
+        pStubMsg->Buffer += sizeof(ULONG);
+        TRACE("value: 0x%08lx\n", *(ULONG *)pMemory);
+        break;
+    case RPC_FC_FLOAT:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1);
+        *(float *)pStubMsg->Buffer = *(float *)pMemory;
+        pStubMsg->Buffer += sizeof(float);
+        break;
+    case RPC_FC_DOUBLE:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1);
+        *(double *)pStubMsg->Buffer = *(double *)pMemory;
+        pStubMsg->Buffer += sizeof(double);
+        break;
+    case RPC_FC_HYPER:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1);
+        *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory;
+        pStubMsg->Buffer += sizeof(ULONGLONG);
+        TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
+        break;
+    case RPC_FC_ENUM16:
+    case RPC_FC_ENUM32:
+    default:
+        FIXME("Unhandled base type: 0x%02x\n", *pFormat);
+    }
+
+    STD_OVERFLOW_CHECK(pStubMsg);
+
+    /* FIXME: what is the correct return value? */
+    return NULL;
+}
+
+/***********************************************************************
+ *           NdrBaseTypeUnmarshall [internal]
+ */
+static unsigned char *WINAPI NdrBaseTypeUnmarshall(
+    PMIDL_STUB_MESSAGE pStubMsg,
+    unsigned char **ppMemory,
+    PFORMAT_STRING pFormat,
+    unsigned char fMustAlloc)
+{
+    TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false");
+
+    if (fMustAlloc || !*ppMemory)
+        *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat));
+
+    TRACE("*ppMemory: %p\n", *ppMemory);
+
+    switch(*pFormat)
+    {
+    case RPC_FC_BYTE:
+    case RPC_FC_CHAR:
+    case RPC_FC_SMALL:
+    case RPC_FC_USMALL:
+        **(UCHAR **)ppMemory = *(UCHAR *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(UCHAR);
+        TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory);
+        break;
+    case RPC_FC_WCHAR:
+    case RPC_FC_SHORT:
+    case RPC_FC_USHORT:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1);
+        **(USHORT **)ppMemory = *(USHORT *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(USHORT);
+        TRACE("value: 0x%04x\n", **(USHORT **)ppMemory);
+        break;
+    case RPC_FC_LONG:
+    case RPC_FC_ULONG:
+    case RPC_FC_ERROR_STATUS_T:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1);
+        **(ULONG **)ppMemory = *(ULONG *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(ULONG);
+        TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory);
+        break;
+   case RPC_FC_FLOAT:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1);
+        **(float **)ppMemory = *(float *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(float);
+        TRACE("value: %f\n", **(float **)ppMemory);
+        break;
+    case RPC_FC_DOUBLE:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1);
+        **(double **)ppMemory = *(double*)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(double);
+        TRACE("value: %f\n", **(double **)ppMemory);
+        break;
+    case RPC_FC_HYPER:
+        ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1);
+        **(ULONGLONG **)ppMemory = *(ULONGLONG *)pStubMsg->Buffer;
+        pStubMsg->Buffer += sizeof(ULONGLONG);
+        TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory));
+        break;
+    case RPC_FC_ENUM16:
+    case RPC_FC_ENUM32:
+    default:
+        FIXME("Unhandled base type: 0x%02x\n", *pFormat);
+    }
+
+    /* FIXME: what is the correct return value? */
+
+    return NULL;
+}
+
+/***********************************************************************
+ *           NdrBaseTypeBufferSize [internal]
+ */
+static void WINAPI NdrBaseTypeBufferSize(
+    PMIDL_STUB_MESSAGE pStubMsg,
+    unsigned char *pMemory,
+    PFORMAT_STRING pFormat)
+{
+    TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat);
+
+    switch(*pFormat)
+    {
+    case RPC_FC_BYTE:
+    case RPC_FC_CHAR:
+    case RPC_FC_SMALL:
+    case RPC_FC_USMALL:
+        pStubMsg->BufferLength += sizeof(UCHAR);
+        break;
+    case RPC_FC_WCHAR:
+    case RPC_FC_SHORT:
+    case RPC_FC_USHORT:
+        ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT) - 1);
+        pStubMsg->BufferLength += sizeof(USHORT);
+        break;
+    case RPC_FC_LONG:
+    case RPC_FC_ULONG:
+        ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG) - 1);
+        pStubMsg->BufferLength += sizeof(ULONG);
+        break;
+    case RPC_FC_FLOAT:
+        ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float) - 1);
+        pStubMsg->BufferLength += sizeof(float);
+        break;
+    case RPC_FC_DOUBLE:
+        ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double) - 1);
+        pStubMsg->BufferLength += sizeof(double);
+        break;
+    case RPC_FC_HYPER:
+        ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG) - 1);
+        pStubMsg->BufferLength += sizeof(ULONGLONG);
+        break;
+    case RPC_FC_ERROR_STATUS_T:
+        ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t) - 1);
+        pStubMsg->BufferLength += sizeof(error_status_t);
+        break;
+    case RPC_FC_ENUM16:
+    case RPC_FC_ENUM32:
+    default:
+        FIXME("Unhandled base type: 0x%02x\n", *pFormat);
+    }
+}
+
+/***********************************************************************
+ *           NdrBaseTypeMemorySize [internal]
+ */
+static unsigned long WINAPI NdrBaseTypeMemorySize(
+    PMIDL_STUB_MESSAGE pStubMsg,
+    PFORMAT_STRING pFormat)
+{
+    switch(*pFormat)
+    {
+    case RPC_FC_BYTE:
+    case RPC_FC_CHAR:
+    case RPC_FC_SMALL:
+    case RPC_FC_USMALL:
+        return sizeof(UCHAR);
+    case RPC_FC_WCHAR:
+    case RPC_FC_SHORT:
+    case RPC_FC_USHORT:
+        return sizeof(USHORT);
+    case RPC_FC_LONG:
+    case RPC_FC_ULONG:
+        return sizeof(ULONG);
+    case RPC_FC_FLOAT:
+        return sizeof(float);
+    case RPC_FC_DOUBLE:
+        return sizeof(double);
+    case RPC_FC_HYPER:
+        return sizeof(ULONGLONG);
+    case RPC_FC_ERROR_STATUS_T:
+        return sizeof(error_status_t);
+    case RPC_FC_ENUM16:
+    case RPC_FC_ENUM32:
+    default:
+        FIXME("Unhandled base type: 0x%02x\n", *pFormat);
+       return 0;
+    }
+}
+
+/***********************************************************************
+ *           NdrBaseTypeFree [internal]
+ */
+static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg,
+                                unsigned char *pMemory,
+                                PFORMAT_STRING pFormat)
+{
+   TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat);
+
+   /* nothing to do */
+}
+
 /***********************************************************************
  *           NdrClientContextMarshall
  */
@@ -2659,8 +3153,56 @@ void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
  *           NdrClientContextUnmarshall
  */
 void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
-                                  NDR_CCONTEXT * pContextHandle,
-                                  RPC_BINDING_HANDLE BindHandle)
+                                       NDR_CCONTEXT * pContextHandle,
+                                       RPC_BINDING_HANDLE BindHandle)
 {
     FIXME("(%p, %p, %p): stub\n", pStubMsg, pContextHandle, BindHandle);
 }
+
+void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                     NDR_SCONTEXT ContextHandle,
+                                     NDR_RUNDOWN RundownRoutine )
+{
+    FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine);
+}
+
+NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg)
+{
+    FIXME("(%p): stub\n", pStubMsg);
+    return NULL;
+}
+
+void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg,
+                                 unsigned char* pMemory,
+                                 PFORMAT_STRING pFormat)
+{
+    FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat);
+}
+
+NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg,
+                                               PFORMAT_STRING pFormat)
+{
+    FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
+    return NULL;
+}
+
+void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                        NDR_SCONTEXT ContextHandle,
+                                        NDR_RUNDOWN RundownRoutine,
+                                        PFORMAT_STRING pFormat)
+{
+    FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat);
+}
+
+NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
+                                                  PFORMAT_STRING pFormat)
+{
+    FIXME("(%p, %p): stub\n", pStubMsg, pFormat);
+    return NULL;
+}
+
+RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext)
+{
+    FIXME("(%p): stub\n", CContext);
+    return NULL;
+}