Sync to Wine-0_9_3:
authorGé van Geldorp <ge@gse.nl>
Wed, 14 Dec 2005 19:02:42 +0000 (19:02 +0000)
committerGé van Geldorp <ge@gse.nl>
Wed, 14 Dec 2005 19:02:42 +0000 (19:02 +0000)
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.

svn path=/trunk/; revision=20167

reactos/lib/rpcrt4/cpsf.c
reactos/lib/rpcrt4/cpsf.h
reactos/lib/rpcrt4/cstub.c
reactos/lib/rpcrt4/ndr_marshall.c
reactos/lib/rpcrt4/ndr_midl.c
reactos/lib/rpcrt4/ndr_misc.h
reactos/lib/rpcrt4/ndr_ole.c

index 63ff851..3f0190c 100644 (file)
@@ -133,6 +133,10 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
                                    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 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv,
   }
   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;
+  }
 }
 
 /***********************************************************************
index bdb6503..60364d3 100644 (file)
@@ -41,4 +41,6 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid,
                                        LPPSFACTORYBUFFER pPSFactory,
                                        LPRPCSTUBBUFFER *ppStub);
 
+const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface);
+
 #endif  /* __WINE_CPSF_H */
index 13004dd..2633298 100644 (file)
@@ -177,3 +177,9 @@ void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface,
   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;
+}
index e5c8341..42b72e3 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,
@@ -139,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,
@@ -173,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,
@@ -207,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,
@@ -234,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,
@@ -286,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;
     }
@@ -376,7 +408,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 */
@@ -387,7 +419,7 @@ done_conf_grab:
   }
 
 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 *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);
@@ -563,33 +594,18 @@ 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((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 @@ void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg,
     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 @@ 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;
@@ -1512,6 +1529,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;
@@ -1569,6 +1589,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;
@@ -1622,6 +1645,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;
@@ -1669,6 +1695,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;
@@ -1901,7 +1930,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);
 }
@@ -1912,16 +1942,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;
 }
 
 /***********************************************************************
@@ -1945,7 +1977,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;
 }
 
@@ -1958,7 +2018,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;
 }
 
@@ -1980,7 +2062,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);
 }
 
 
@@ -2269,6 +2370,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.@]
  */
@@ -2276,7 +2385,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;
 }
 
@@ -2288,7 +2422,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;
 }
 
@@ -2299,7 +2478,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);
 }
 
 /***********************************************************************
@@ -2693,6 +2895,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
  */
index d7e7470..723c3c1 100644 (file)
@@ -140,8 +140,12 @@ void WINAPI NdrProxyFreeBuffer(void *This,
  */
 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 NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_M
 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 @@ unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buf
   stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength;
   return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer);
 }
-
 /***********************************************************************
  *           NdrFreeBuffer [RPCRT4.@]
  */
@@ -264,30 +267,29 @@ void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg)
 /************************************************************************
  *           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;
index b246b44..32f835d 100644 (file)
@@ -35,8 +35,11 @@ LONG_PTR RPCRT4_NdrClientCall2(PMIDL_STUB_DESC pStubDesc,
 
 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);
index a92b754..0919f9f 100644 (file)
@@ -254,13 +254,17 @@ unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
   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 @@ unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
   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);
     }
   }
   return NULL;
@@ -307,7 +313,7 @@ void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg,
                             pStubMsg->dwDestContext, pStubMsg->pvDestContext,
                             MSHLFLAGS_NORMAL);
   TRACE("size=%ld\n", size);
-  if (size) pStubMsg->BufferLength += sizeof(DWORD) + size;
+  pStubMsg->BufferLength += sizeof(DWORD) + size;
 }
 
 /***********************************************************************