Sync to Wine-0_9_3:
Robert Shearman <rob@codeweavers.com>
- Return the correct error code from NdrProxyErrorHandler.
- Add a function to retrieve the MIDL_SERVER_INFO struct from an object.
- Make sure to fill out the MIDL_STUB_MESSAGE structure in
  NdrSendReceive like we do in NdrProxySendReceive.
- Fix the overflow check to not depend on pStubMsg->BufferStart and
  pStubMsg->BufferEnd being valid, because they aren't filled in when
  using MIDL-generated server stubs.
- Don't set the pointer to NULL on unmarshaling because we may want to
  unmarshal the value to an existing pointer instead of allocating a new
  one.
- Raise exceptions on failures.
  Replace references of pStubMsg->BufferEnd with RpcMsg->Buffer +
  pStubMsg->BufferLength.
- Fix buffer calculation when no interface data is marshaled to the
  stream.
- Implement conformant varying array functions.
- Implement conformant struct functions.
- Implement FC_STRUCTPAD2 for complex types.
- Add functions for marshaling base types (ints, floats, etc.).
- Extend conformance computation function to also compute variances.
  MSDN suggests that conformance and variance are pretty much the same,
  but there may be some subtleties to it.
- Fix NdrConformantArrayBufferSize to include the size of the
  conformance value.
  Make NdrConformantArrayMemorySize do something more useful, like
  actually return the required memory.
  Conformance offset can be negative and should only be two bytes.
- We should always allocate in NdrConformantStringUnmarshal if the
  memory pointer is NULL.
- The CLSID can be substituted by an IID present in one of the proxy
  file infos in NdrDllGetClassObject.
Ge van Geldorp <gvg@reactos.org>
- Match PSDK STATUS_* definitions.
Modified: trunk/reactos/lib/rpcrt4/cpsf.c
Modified: trunk/reactos/lib/rpcrt4/cpsf.h
Modified: trunk/reactos/lib/rpcrt4/cstub.c
Modified: trunk/reactos/lib/rpcrt4/ndr_marshall.c
Modified: trunk/reactos/lib/rpcrt4/ndr_midl.c
Modified: trunk/reactos/lib/rpcrt4/ndr_misc.h
Modified: trunk/reactos/lib/rpcrt4/ndr_ole.c

Modified: trunk/reactos/lib/rpcrt4/cpsf.c
--- trunk/reactos/lib/rpcrt4/cpsf.c	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/cpsf.c	2005-12-14 19:02:42 UTC (rev 20167)
@@ -133,6 +133,10 @@
                                    const CLSID *pclsid,
                                    CStdPSFactoryBuffer *pPSFactoryBuffer)
 {
+  TRACE("(%s, %s, %p, %p, %s, %p)\n", debugstr_guid(rclsid),
+    debugstr_guid(iid), ppv, pProxyFileList, debugstr_guid(pclsid),
+    pPSFactoryBuffer);
+
   *ppv = NULL;
   if (!pPSFactoryBuffer->lpVtbl) {
     pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl;
@@ -141,7 +145,17 @@
   }
   if (IsEqualGUID(rclsid, pclsid))
     return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
-  return CLASS_E_CLASSNOTAVAILABLE;
+  else {
+    const ProxyFileInfo *info;
+    int index;
+    /* otherwise, the dll may be using the iid as the clsid, so
+     * search for it in the proxy file list */
+    if (FindProxyInfo(pProxyFileList, rclsid, &info, &index))
+      return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv);
+
+    WARN("class %s not available\n", debugstr_guid(rclsid));
+    return CLASS_E_CLASSNOTAVAILABLE;
+  }
 }
 
 /***********************************************************************

Modified: trunk/reactos/lib/rpcrt4/cpsf.h
--- trunk/reactos/lib/rpcrt4/cpsf.h	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/cpsf.h	2005-12-14 19:02:42 UTC (rev 20167)
@@ -41,4 +41,6 @@
 					LPPSFACTORYBUFFER pPSFactory,
 					LPRPCSTUBBUFFER *ppStub);
 
+const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
+
 #endif  /* __WINE_CPSF_H */

Modified: trunk/reactos/lib/rpcrt4/cstub.c
--- trunk/reactos/lib/rpcrt4/cstub.c	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/cstub.c	2005-12-14 19:02:42 UTC (rev 20167)
@@ -177,3 +177,9 @@
   CStdStubBuffer *This = (CStdStubBuffer *)iface;
   TRACE("(%p)->DebugServerRelease(%p)\n",This,pv);
 }
+
+const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface)
+{
+  CStdStubBuffer *This = (CStdStubBuffer *)iface;
+  return STUB_HEADER(This).pServerInfo;
+}

Modified: trunk/reactos/lib/rpcrt4/ndr_marshall.c
--- trunk/reactos/lib/rpcrt4/ndr_marshall.c	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/ndr_marshall.c	2005-12-14 19:02:42 UTC (rev 20167)
@@ -97,18 +97,28 @@
 #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,
+  0,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
+  NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall,
   /* 0x10 */
-  0,
+  NdrBaseTypeMarshall,
   /* 0x11 */
   NdrPointerMarshall, NdrPointerMarshall,
   NdrPointerMarshall, NdrPointerMarshall,
@@ -139,10 +149,13 @@
   NdrUserMarshalMarshall
 };
 NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
+  0,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
+  NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall,
   /* 0x10 */
-  0,
+  NdrBaseTypeUnmarshall,
   /* 0x11 */
   NdrPointerUnmarshall, NdrPointerUnmarshall,
   NdrPointerUnmarshall, NdrPointerUnmarshall,
@@ -173,10 +186,13 @@
   NdrUserMarshalUnmarshall
 };
 NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
+  0,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
+  NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize,
   /* 0x10 */
-  0,
+  NdrBaseTypeBufferSize,
   /* 0x11 */
   NdrPointerBufferSize, NdrPointerBufferSize,
   NdrPointerBufferSize, NdrPointerBufferSize,
@@ -207,10 +223,13 @@
   NdrUserMarshalBufferSize
 };
 NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
+  0,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
+  NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize,
   /* 0x10 */
-  0,
+  NdrBaseTypeMemorySize,
   /* 0x11 */
   NdrPointerMemorySize, NdrPointerMemorySize,
   NdrPointerMemorySize, NdrPointerMemorySize,
@@ -234,10 +253,13 @@
   NdrUserMarshalMemorySize
 };
 NDR_FREE NdrFreer[NDR_TABLE_SIZE] = {
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
+  0,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
+  NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree,
   /* 0x10 */
-  0,
+  NdrBaseTypeFree,
   /* 0x11 */
   NdrPointerFree, NdrPointerFree,
   NdrPointerFree, NdrPointerFree,
@@ -286,46 +308,56 @@
   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;
     }
@@ -376,7 +408,7 @@
 done_conf_grab:
   switch (pFormat[1]) {
   case 0: /* no op */
-    pStubMsg->MaxCount = data;
+    *pCount = data;
     break;
   case RPC_FC_DEREFERENCE:
     /* already handled */
@@ -387,7 +419,7 @@
   }
 
 finish_conf:
-  TRACE("resulting conformance is %ld\n", pStubMsg->MaxCount);
+  TRACE("resulting conformance is %ld\n", *pCount);
   return pFormat+4;
 }
 
@@ -538,7 +570,6 @@
   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);
@@ -563,33 +594,18 @@
     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;
-  }
+  memcpy(*ppMemory, pStubMsg->Buffer, len*esize);
 
-  pMem = *ppMemory + ofs*esize;
-
-  if (pMem != pStubMsg->Buffer)
-    memcpy(pMem, pStubMsg->Buffer, len*esize);
-
   pStubMsg->Buffer += len*esize;
 
   if (*pFormat == RPC_FC_C_CSTRING) {
-    TRACE("string=%s\n", debugstr_a((char*)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? */
@@ -749,8 +765,6 @@
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
   }
 
-  *pPointer = NULL;
-
   if (pointer_id) {
     m = NdrUnmarshaller[*desc & NDR_TABLE_MASK];
     if (m) m(pStubMsg, pPointer, desc, fMustAlloc);
@@ -1449,6 +1463,9 @@
     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;
@@ -1512,6 +1529,9 @@
     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;
@@ -1569,6 +1589,9 @@
     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;
@@ -1622,6 +1645,9 @@
     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;
@@ -1669,6 +1695,9 @@
     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;
@@ -1901,7 +1930,8 @@
   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);
 }
@@ -1912,16 +1942,18 @@
 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;
 }
 
 /***********************************************************************
@@ -1945,7 +1977,35 @@
                                                          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;
 }
 
@@ -1958,7 +2018,29 @@
                                                            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;
 }
 
@@ -1980,7 +2062,26 @@
 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);
 }
 
 
@@ -2269,6 +2370,14 @@
      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.@]
  */
@@ -2276,7 +2385,32 @@
                                 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;
 }
 
@@ -2288,7 +2422,52 @@
                                 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;
 }
 
@@ -2299,7 +2478,30 @@
                                 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);
 }
 
 /***********************************************************************
@@ -2694,6 +2896,242 @@
 }
 
 /***********************************************************************
+ *           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
  */
 void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg,

Modified: trunk/reactos/lib/rpcrt4/ndr_midl.c
--- trunk/reactos/lib/rpcrt4/ndr_midl.c	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/ndr_midl.c	2005-12-14 19:02:42 UTC (rev 20167)
@@ -140,8 +140,12 @@
  */
 HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode)
 {
-  FIXME("(0x%08lx): semi-stub\n", dwExceptionCode);
-  return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_RPC, RPC_S_CALL_FAILED);
+  WARN("(0x%08lx): a proxy call failed\n", dwExceptionCode);
+
+  if (FAILED(dwExceptionCode))
+    return dwExceptionCode;
+  else
+    return HRESULT_FROM_WIN32(dwExceptionCode);
 }
 
 /***********************************************************************
@@ -234,12 +238,12 @@
 unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle)
 {
   TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle);
-
+  
   assert( stubmsg && stubmsg->RpcMsg );
 
   /* I guess this is our chance to put the binding handle into the RPC_MESSAGE */
   stubmsg->RpcMsg->Handle = handle;
-
+  
   stubmsg->RpcMsg->BufferLength = buflen;
   if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK)
     return NULL;
@@ -249,7 +253,6 @@
   stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;
   return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
 }
-
 /***********************************************************************
  *           NdrFreeBuffer [RPCRT4.@]
  */
@@ -264,30 +267,29 @@
 /************************************************************************
  *           NdrSendReceive [RPCRT4.@]
  */
-unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *pStubMsg, unsigned char *buffer  )
+unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer  )
 {
-  TRACE("(pStubMsg == ^%p, buffer == ^%p)\n", pStubMsg, buffer);
+  TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer);
 
   /* FIXME: how to handle errors? (raise exception?) */
-  if (!pStubMsg) {
+  if (!stubmsg) {
     ERR("NULL stub message.  No action taken.\n");
     return NULL;
   }
-  if (!pStubMsg->RpcMsg) {
+  if (!stubmsg->RpcMsg) {
     ERR("RPC Message not present in stub message.  No action taken.\n");
     return NULL;
   }
 
-  if (I_RpcSendReceive(pStubMsg->RpcMsg) != RPC_S_OK) {
+  if (I_RpcSendReceive(stubmsg->RpcMsg) != RPC_S_OK) {
     WARN("I_RpcSendReceive did not return success.\n");
     /* FIXME: raise exception? */
-    return NULL;
   }
 
-  pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength;
-  pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer;
-  pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength;
-  pStubMsg->Buffer = pStubMsg->BufferStart;
+  stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength;
+  stubmsg->BufferStart = stubmsg->RpcMsg->Buffer;
+  stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength;
+  stubmsg->Buffer = stubmsg->BufferStart;
 
   /* FIXME: is this the right return value? */
   return NULL;

Modified: trunk/reactos/lib/rpcrt4/ndr_misc.h
--- trunk/reactos/lib/rpcrt4/ndr_misc.h	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/ndr_misc.h	2005-12-14 19:02:42 UTC (rev 20167)
@@ -35,8 +35,11 @@
 
 HRESULT RPCRT4_GetPSFactory(REFIID riid, struct IPSFactoryBuffer **ppPS);
 
-PFORMAT_STRING ComputeConformance(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
-                                  PFORMAT_STRING pFormat, ULONG_PTR def);
+#define ComputeConformance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount)
+#define ComputeVariance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->ActualCount)
+PFORMAT_STRING ComputeConformanceOrVariance(
+    MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory,
+    PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount);
 
 typedef unsigned char* (WINAPI *NDR_MARSHALL)  (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING);
 typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char);

Modified: trunk/reactos/lib/rpcrt4/ndr_ole.c
--- trunk/reactos/lib/rpcrt4/ndr_ole.c	2005-12-14 18:55:57 UTC (rev 20166)
+++ trunk/reactos/lib/rpcrt4/ndr_ole.c	2005-12-14 19:02:42 UTC (rev 20167)
@@ -254,13 +254,17 @@
   TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat);
   pStubMsg->MaxCount = 0;
   if (!LoadCOM()) return NULL;
-  if (pStubMsg->Buffer + sizeof(DWORD) < pStubMsg->BufferEnd) {
+  if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
     stream = RpcStream_Create(pStubMsg, TRUE);
     if (stream) {
       hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory,
                                 pStubMsg->dwDestContext, pStubMsg->pvDestContext,
                                 MSHLFLAGS_NORMAL);
       IStream_Release(stream);
+      if (FAILED(hr)) {
+        IUnknown_Release((LPUNKNOWN)pMemory);
+        RpcRaiseException(hr);
+      }
     }
   }
   return NULL;
@@ -280,11 +284,13 @@
   TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
   if (!LoadCOM()) return NULL;
   *(LPVOID*)ppMemory = NULL;
-  if (pStubMsg->Buffer + sizeof(DWORD) < pStubMsg->BufferEnd) {
+  if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
     stream = RpcStream_Create(pStubMsg, FALSE);
     if (stream) {
       hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
       IStream_Release(stream);
+      if (FAILED(hr))
+        RpcRaiseException(hr);
     }
   }
[truncated at 1000 lines; 10 more skipped]