Hi.

I've tryed to run game Project Entropia and I got segmentation fault because of a bug in OLE.
I've hacked code and I found two bugs:


1. ITypeInfo has back pointer to ITypeLib, but it's possible (and happened) that ITypeLib is
destroyed and later ITypeInfo calls its function. I've solve this problem by call ITypeLib_AddRef
while creating ITypeInfo (and ITypeLib_Release while destroying ITypeInfo).


2. ITypeInfo_Invoke doesn't support optional parameters. I've added support for cParamsOpt>0.
MSDN says that optional parameter is when VARTYPE equals VT_EMPTY, but in my case
it was a VT_BYREF | VT_VARIANT type but the pointer was NULL. When I treated it as
VT_EMPTY, it was OK.


I enclose my patch. My knownlage about OLE is sparse so I'm not able to test this.

Thanks,
Jacek
Index: dlls/oleaut32/typelib.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v
retrieving revision 1.116
diff -u -r1.116 typelib.c
--- dlls/oleaut32/typelib.c	6 Jul 2004 21:28:13 -0000	1.116
+++ dlls/oleaut32/typelib.c	6 Aug 2004 22:47:20 -0000
@@ -1999,6 +1999,7 @@
     MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
                       pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
 /* this is where we are coming from */
+    ITypeLib2_AddRef((ITypeLib*)pLibInfo);
     ptiRet->pTypeLib = pLibInfo;
     ptiRet->index=count;
 /* fill in the typeattr fields */
@@ -3265,6 +3266,7 @@
 	return NULL;
       }
       *ppTypeInfoImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
+      pTypeLibImpl->ref++;
       (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl;
       (*ppTypeInfoImpl)->index = i;
       (*ppTypeInfoImpl)->Name = TLB_MultiByteToBSTR(
@@ -4116,6 +4118,9 @@
         ITypeInfo_Release((ITypeInfo*)This->next);
       }
 
+      if (This->pTypeLib)
+        ITypeLib2_Release((ITypeLib*)This->pTypeLib);
+
       HeapFree(GetProcessHeap(),0,This);
       return 0;
     }
@@ -4736,6 +4741,14 @@
 		if (i<pDispParams->cArgs) {
 		    VARIANT *arg = &pDispParams->rgvarg[pDispParams->cArgs-i-1];
 		    TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
+                    if (pFDesc->funcdesc.cParamsOpt>0 && i>=pFDesc->funcdesc.cParams-pFDesc->funcdesc.cParamsOpt) {
+                        if(V_VT(arg) == VT_EMPTY
+                          || ((V_VT(arg) & VT_BYREF) && !V_BYREF(arg))) {  /* I'm not sure if it's correct but it works */
+                            V_VT(arg) = VT_ERROR;
+                            V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
+                            arglen = _argsize(VT_ERROR);
+                        }
+                    }
 		    hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
 		    if (FAILED(hres)) return hres;
 		    argspos += arglen;
@@ -4756,7 +4769,7 @@
 		    args2pos	+= arglen;
 		}
 	    }
-	    if (pFDesc->funcdesc.cParamsOpt)
+	    if (pFDesc->funcdesc.cParamsOpt<0)
 		FIXME("Does not support optional parameters (%d)\n",
 			pFDesc->funcdesc.cParamsOpt
 		);

Reply via email to