[OLE #94] Correctly marshal NULL ppUnk refptrs in NdrPointerMarshall

Mike Hearn mike at navi.cx
Sun Jun 5 17:05:59 CDT 2005


This corrects an attempt to demarshal garbage during InstallShield10
startup. For full InstallShield 10 support we need a stdole2.tlb

Mike Hearn <mh at codeweavers.com>
Correctly marshal NULL ppUnk refptrs in NdrPointerMarshall

Index: dlls/rpcrt4/ndr_marshall.c
===================================================================
RCS file: /home/wine/wine/dlls/rpcrt4/ndr_marshall.c,v
retrieving revision 1.24
diff -u -p -d -u -r1.24 ndr_marshall.c
--- dlls/rpcrt4/ndr_marshall.c	1 Jun 2005 11:04:03 -0000	1.24
+++ dlls/rpcrt4/ndr_marshall.c	5 Jun 2005 22:03:11 -0000
@@ -575,19 +575,19 @@ void WINAPI PointerMarshall(PMIDL_STUB_M
   TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat);
   TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr);
   pFormat += 2;
+  
   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
   else desc = pFormat + *(const SHORT*)pFormat;
+  
   if (attr & RPC_FC_P_DEREF) {
+    if (!Pointer)
+      RpcRaiseException(RPC_X_NULL_REF_POINTER);    
     Pointer = *(unsigned char**)Pointer;
     TRACE("deref => %p\n", Pointer);
   }
 
   switch (type) {
-  case RPC_FC_RP: /* ref pointer (always non-null) */
-#if 0 /* this causes problems for InstallShield so is disabled - we need more tests */
-    if (!Pointer)
-      RpcRaiseException(RPC_X_NULL_REF_POINTER);
-#endif
+  case RPC_FC_RP: /* ref pointer (always non-null but may point to null) */
     break;
   case RPC_FC_UP: /* unique pointer */
   case RPC_FC_OP: /* object pointer - same as unique here */
@@ -601,12 +601,16 @@ void WINAPI PointerMarshall(PMIDL_STUB_M
     RpcRaiseException(RPC_X_BAD_STUB_DATA);
   }
 
-  TRACE("calling marshaller for type 0x%x\n", (int)*desc);
-
   if (Pointer) {
+    TRACE("calling marshaller for type 0x%x\n", (int)*desc);
     m = NdrMarshaller[*desc & NDR_TABLE_MASK];
     if (m) m(pStubMsg, Pointer, desc);
     else FIXME("no marshaller for data type=%02x\n", *desc);
+  } else {
+    TRACE("marshalling NULL\n");
+    /* fixme: is this wire compatible? */
+    NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, NULL);
+    pStubMsg->Buffer += 4;
   }
 
   STD_OVERFLOW_CHECK(pStubMsg);
@@ -638,7 +642,11 @@ void WINAPI PointerUnmarshall(PMIDL_STUB
 
   switch (type) {
   case RPC_FC_RP: /* ref pointer (always non-null) */
-    pointer_id = ~0UL;
+    if (NDR_LOCAL_UINT32_READ(pStubMsg->Buffer))
+      pointer_id = ~0UL;
+    else
+      pointer_id = 0;           /* marshalled NULL */
+    pStubMsg->Buffer += 4;
     break;
   case RPC_FC_UP: /* unique pointer */
     pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer);
@@ -674,18 +682,21 @@ void WINAPI PointerBufferSize(PMIDL_STUB
   NDR_BUFFERSIZE m;
 
   TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat);
-  TRACE("type=%d, attr=%d\n", type, attr);
+  TRACE("type=0x%x, attr=%d\n", type, attr);
   pFormat += 2;
+  
   if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat;
   else desc = pFormat + *(const SHORT*)pFormat;
+  
   if (attr & RPC_FC_P_DEREF) {
+    if (!Pointer)
+      RpcRaiseException(RPC_X_NULL_REF_POINTER);          
     Pointer = *(unsigned char**)Pointer;
     TRACE("deref => %p\n", Pointer);
   }
 
   switch (type) {
-  case RPC_FC_RP: /* ref pointer (always non-null) */
-    break;
+  case RPC_FC_RP:
   case RPC_FC_OP:
   case RPC_FC_UP:
     pStubMsg->BufferLength += 4;



More information about the wine-patches mailing list