PATCH: ITypeLib::Invoke fixes

Marcus Meissner marcus at jet.franken.de
Tue Jun 7 15:38:24 CDT 2005


Hi,

ITypeInfo::Invoke was broken in regards to passing 8 byte parameters, like VT_DATE.

I also took the liberty and tried to make it a bit more readable and added some
FIXME()s for unexpected cases.

Ishield still works. CATS WinTuner now passes its (trivial) license timeout check.

Ciao, Marcus

Changelog:
	Fixed IType::Invoke in regards to handling propertyget variables longer
	than 4 byte  (like VT_DATE).

Index: dlls/oleaut32/typelib.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v
retrieving revision 1.150
diff -u -r1.150 typelib.c
--- dlls/oleaut32/typelib.c	6 Jun 2005 19:50:37 -0000	1.150
+++ dlls/oleaut32/typelib.c	7 Jun 2005 20:35:39 -0000
@@ -4783,13 +4783,19 @@
             memcpy(rgvarg,pDispParams->rgvarg,sizeof(VARIANT)*pDispParams->cArgs);
 
 	    hres = S_OK;
-	    numargs = 1; numargs2 = 0;
+	    numargs = 1; /* sizeof(thisptr) */
+	    numargs2 = 0;
 	    for (i = 0; i < func_desc->cParams; i++) {
-		if (i<pDispParams->cArgs)
-		    numargs += _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
-		else {
-		    numargs	+= 1; /* sizeof(lpvoid) */
-		    numargs2	+= _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
+                TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
+
+		numargs += _argsize(tdesc->vt);
+		if (i>=pDispParams->cArgs) { /* arguments to return */
+		    if (tdesc->vt == VT_PTR) {
+		    	numargs2	+= _argsize(tdesc->u.lptdesc->vt);
+		    } else {
+			FIXME("The variant type here should have been VT_PTR, not vt %d\n", tdesc->vt);
+		    	numargs2	+= _argsize(tdesc->vt);
+		    }
 		}
 	    }
 
@@ -4799,11 +4805,14 @@
 	    args[0] = (DWORD)pIUnk;
 	    argspos = 1; args2pos = 0;
 	    for (i = 0; i < func_desc->cParams; i++) {
-		int arglen = _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
+		ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i]);
+		TYPEDESC *tdesc = &(elemdesc->tdesc);
+		USHORT paramFlags = elemdesc->u.paramdesc.wParamFlags;
+		int arglen = _argsize(tdesc->vt);
+
 		if (i<pDispParams->cArgs) {
                     VARIANT *arg = &rgvarg[pDispParams->cArgs-i-1];
-                    TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
-                    USHORT paramFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+
                     if (paramFlags & PARAMFLAG_FOPT) {
                         if(i < func_desc->cParams - func_desc->cParamsOpt)
                             ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");
@@ -4822,13 +4831,14 @@
                     hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
                     if (FAILED(hres)) goto func_fail;
                     argspos += arglen;
-                } else if(func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FOPT) {
+                } else if (paramFlags & PARAMFLAG_FOPT) {
                     VARIANT *arg = &rgvarg[i];
-                    TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
-                    if(i < func_desc->cParams - func_desc->cParamsOpt)
+
+                    if (i < func_desc->cParams - func_desc->cParamsOpt)
                         ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");
-                    if(func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+                    if (paramFlags & PARAMFLAG_FHASDEFAULT)
                         FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n");
+
                     V_VT(arg) = VT_ERROR;
                     V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
                     arglen = _argsize(VT_ERROR);
@@ -4836,10 +4846,12 @@
                     if (FAILED(hres)) goto func_fail;
                     argspos += arglen;
 		} else {
-		    TYPEDESC *tdesc = &(func_desc->lprgelemdescParam[i].tdesc);
-		    if (tdesc->vt != VT_PTR)
+		    if (tdesc->vt == VT_PTR)
+			arglen = _argsize(tdesc->u.lptdesc->vt);
+		    else
 		    	FIXME("set %d to pointer for get (type is %d)\n",i,tdesc->vt);
-		    /*FIXME: give pointers for the rest, so propertyget works*/
+
+		    /* Supply pointers for the rest, so propertyget works*/
 		    args[argspos] = (DWORD)&args2[args2pos];
 
 		    /* If pointer to variant, pass reference it. */
@@ -4864,20 +4876,24 @@
 	    if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
 		args2pos = 0;
 		for (i = 0; i < func_desc->cParams - pDispParams->cArgs; i++) {
-		    int arglen = _argsize(func_desc->lprgelemdescParam[i].tdesc.vt);
-		    TYPEDESC *tdesc = &(func_desc->lprgelemdescParam[i + pDispParams->cArgs].tdesc);
-                    TYPEDESC i4_tdesc;
-                    i4_tdesc.vt = VT_I4;
+		    ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i+pDispParams->cArgs]);
+		    TYPEDESC *tdesc = &(elemdesc->tdesc);
+		    int arglen = _argsize(tdesc->vt);
+		    TYPEDESC i4_tdesc;
+		    i4_tdesc.vt = VT_I4;
 
 		    /* If we are a pointer to a variant, we are done already */
 		    if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT))
 			continue;
 
+		    if (tdesc->vt == VT_PTR) {
+			tdesc = tdesc->u.lptdesc;
+		        arglen = _argsize(tdesc->vt);
+		    }
+
 		    VariantInit(pVarResult);
 		    memcpy(&V_INT(pVarResult),&args2[args2pos],arglen*sizeof(DWORD));
 
-		    if (tdesc->vt == VT_PTR)
-			tdesc = tdesc->u.lptdesc;
 		    if (tdesc->vt == VT_USERDEFINED) {
 			ITypeInfo	*tinfo2;
 			TYPEATTR	*tattr;



More information about the wine-patches mailing list