PATCH: oleaut32 / vb6 rollup
Marcus Meissner
mm at lst.de
Tue Dec 24 07:49:00 CST 2002
Hi,
this is a oleaut32 rollup patch.
After this, one larger VB6 application called AccuTerm 2000 runs up to the
point where it displays the main screen. It still has more failures, but
I am working on it.
Ciao, Marcus
Changelog:
Added some wstr to .spec entries which get BSTR arguments.
In OleCreatePictureEx icons have width/height to query.
DispCallFunc should pass the interface ptr during the call.
VariantCopy does not check the result of VariantClear. (added testcase)
VariantCopyInd does copy VT_DISPATCH and VT_UNKNOWN (and no longer
just silently fails).
VT_ARRAY|VT_UI1 -> VT_BSTR coercion is just a memcpy apparently
(added testcase).
VarBstrCat enhanced a bit.
Index: oleaut32.spec
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/oleaut32.spec,v
retrieving revision 1.46
diff -u -r1.46 oleaut32.spec
--- oleaut32.spec 23 Dec 2002 02:02:50 -0000 1.46
+++ oleaut32.spec 24 Dec 2002 13:35:43 -0000
@@ -2,7 +2,7 @@
2 stdcall SysAllocString(wstr) SysAllocString
3 stdcall SysReAllocString(ptr wstr) SysReAllocString
4 stdcall SysAllocStringLen(wstr long) SysAllocStringLen
-5 stdcall SysReAllocStringLen(ptr ptr long) SysReAllocStringLen
+5 stdcall SysReAllocStringLen(ptr wstr long) SysReAllocStringLen
6 stdcall SysFreeString(wstr) SysFreeString
7 stdcall SysStringLen(wstr) SysStringLen
8 stdcall VariantInit(ptr) VariantInit
@@ -145,8 +145,8 @@
146 stdcall DispCallFunc(ptr long long long long ptr ptr ptr) DispCallFunc
147 stdcall VariantChangeTypeEx(ptr ptr long long long) VariantChangeTypeEx
148 stdcall SafeArrayPtrOfIndex(ptr ptr ptr) SafeArrayPtrOfIndex
-149 stdcall SysStringByteLen(ptr) SysStringByteLen
-150 stdcall SysAllocStringByteLen(ptr long) SysAllocStringByteLen
+149 stdcall SysStringByteLen(wstr) SysStringByteLen
+150 stdcall SysAllocStringByteLen(wstr long) SysAllocStringByteLen
152 stub VarEqv # stdcall (ptr ptr ptr)
153 stub VarIdiv # stdcall (ptr ptr ptr)
154 stub VarImp # stdcall (ptr ptr ptr)
Index: olepicture.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/olepicture.c,v
retrieving revision 1.20
diff -u -r1.20 olepicture.c
--- olepicture.c 11 Nov 2002 19:54:22 -0000 1.20
+++ olepicture.c 24 Dec 2002 13:35:53 -0000
@@ -997,6 +997,8 @@
} else {
This->desc.picType = PICTYPE_ICON;
This->desc.u.icon.hicon = hicon;
+ This->himetricWidth = cifd->idEntries[i].bWidth;
+ This->himetricHeight = cifd->idEntries[i].bHeight;
hr = S_OK;
}
break;
Index: typelib.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v
retrieving revision 1.84
diff -u -r1.84 typelib.c
--- typelib.c 12 Dec 2002 22:59:25 -0000 1.84
+++ typelib.c 24 Dec 2002 13:36:56 -0000
@@ -4113,7 +4108,7 @@
argsize += _argsize(prgvt[i]);
}
args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
- args[0]=0; /* this is the fake IDispatch interface pointer */
+ args[0] = pvInstance; /* this is the fake IDispatch interface pointer */
argspos = 1;
for (i=0;i<cActuals;i++) {
int arglen;
Index: variant.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/variant.c,v
retrieving revision 1.50
diff -u -r1.50 variant.c
--- variant.c 23 Dec 2002 02:03:10 -0000 1.50
+++ variant.c 24 Dec 2002 13:37:28 -0000
@@ -1919,64 +1920,61 @@
*/
if( pvargDest != pvargSrc && res == S_OK )
{
- res = VariantClear( pvargDest );
+ VariantClear( pvargDest ); /* result is not checked */
- if( res == S_OK )
+ if( V_VT(pvargSrc) & VT_BYREF )
+ {
+ /* In the case of byreference we only need
+ * to copy the pointer.
+ */
+ pvargDest->n1.n2.n3 = pvargSrc->n1.n2.n3;
+ V_VT(pvargDest) = V_VT(pvargSrc);
+ }
+ else
{
- if( V_VT(pvargSrc) & VT_BYREF )
+ /*
+ * The VT_ARRAY flag is another way to designate a safe array.
+ */
+ if (V_VT(pvargSrc) & VT_ARRAY)
{
- /* In the case of byreference we only need
- * to copy the pointer.
- */
- pvargDest->n1.n2.n3 = pvargSrc->n1.n2.n3;
- V_VT(pvargDest) = V_VT(pvargSrc);
+ SafeArrayCopy(V_UNION(pvargSrc,parray), &V_UNION(pvargDest,parray));
}
else
{
- /*
- * The VT_ARRAY flag is another way to designate a safe array.
+ /* In the case of by value we need to
+ * copy the actual value. In the case of
+ * VT_BSTR a copy of the string is made,
+ * if VT_DISPATCH or VT_IUNKNOWN AddRef is
+ * called to increment the object's reference count.
*/
- if (V_VT(pvargSrc) & VT_ARRAY)
- {
- SafeArrayCopy(V_UNION(pvargSrc,parray), &V_UNION(pvargDest,parray));
- }
- else
+ switch( V_VT(pvargSrc) & VT_TYPEMASK )
{
- /* In the case of by value we need to
- * copy the actual value. In the case of
- * VT_BSTR a copy of the string is made,
- * if VT_DISPATCH or VT_IUNKNOWN AddRef is
- * called to increment the object's reference count.
- */
- switch( V_VT(pvargSrc) & VT_TYPEMASK )
- {
- case( VT_BSTR ):
- V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( V_UNION(pvargSrc,bstrVal) );
- break;
- case( VT_DISPATCH ):
- V_UNION(pvargDest,pdispVal) = V_UNION(pvargSrc,pdispVal);
- if (V_UNION(pvargDest,pdispVal)!=NULL)
- ICOM_CALL(AddRef,V_UNION(pvargDest,pdispVal));
- break;
- case( VT_VARIANT ):
- VariantCopy(V_UNION(pvargDest,pvarVal),V_UNION(pvargSrc,pvarVal));
- break;
- case( VT_UNKNOWN ):
- V_UNION(pvargDest,punkVal) = V_UNION(pvargSrc,punkVal);
- if (V_UNION(pvargDest,pdispVal)!=NULL)
- ICOM_CALL(AddRef,V_UNION(pvargDest,punkVal));
- break;
- case( VT_SAFEARRAY ):
- SafeArrayCopy(V_UNION(pvargSrc,parray), &V_UNION(pvargDest,parray));
- break;
- default:
- pvargDest->n1.n2.n3 = pvargSrc->n1.n2.n3;
- break;
- }
+ case( VT_BSTR ):
+ V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( V_UNION(pvargSrc,bstrVal) );
+ break;
+ case( VT_DISPATCH ):
+ V_UNION(pvargDest,pdispVal) = V_UNION(pvargSrc,pdispVal);
+ if (V_UNION(pvargDest,pdispVal)!=NULL)
+ ICOM_CALL(AddRef,V_UNION(pvargDest,pdispVal));
+ break;
+ case( VT_VARIANT ):
+ VariantCopy(V_UNION(pvargDest,pvarVal),V_UNION(pvargSrc,pvarVal));
+ break;
+ case( VT_UNKNOWN ):
+ V_UNION(pvargDest,punkVal) = V_UNION(pvargSrc,punkVal);
+ if (V_UNION(pvargDest,pdispVal)!=NULL)
+ ICOM_CALL(AddRef,V_UNION(pvargDest,punkVal));
+ break;
+ case( VT_SAFEARRAY ):
+ SafeArrayCopy(V_UNION(pvargSrc,parray), &V_UNION(pvargDest,parray));
+ break;
+ default:
+ pvargDest->n1.n2.n3 = pvargSrc->n1.n2.n3;
+ break;
}
-
- V_VT(pvargDest) = V_VT(pvargSrc);
}
+ V_VT(pvargDest) = V_VT(pvargSrc);
+ dump_Variant(pvargDest);
}
}
@@ -2043,6 +2041,9 @@
V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( *(V_UNION(pvargSrc,pbstrVal)) );
break;
case( VT_DISPATCH ):
+ V_UNION(pvargDest,pdispVal) = *V_UNION(pvargSrc,ppdispVal);
+ if (V_UNION(pvargDest,pdispVal)!=NULL)
+ ICOM_CALL(AddRef,V_UNION(pvargDest,pdispVal));
break;
case( VT_VARIANT ):
{
@@ -2079,6 +2080,9 @@
}
break;
case( VT_UNKNOWN ):
+ V_UNION(pvargDest,punkVal) = *V_UNION(pvargSrc,ppunkVal);
+ if (V_UNION(pvargDest,pdispVal)!=NULL)
+ ICOM_CALL(AddRef,V_UNION(pvargDest,punkVal));
break;
case( VT_SAFEARRAY ):
SafeArrayCopy(*V_UNION(pvargSrc,pparray), &V_UNION(pvargDest,parray));
@@ -2118,53 +2122,37 @@
*/
static HRESULT
coerce_array(
- VARIANTARG* src, SAFEARRAY **narr, LCID lcid, USHORT wFlags, VARTYPE vt
+ VARIANTARG* src, VARIANTARG *dst, LCID lcid, USHORT wFlags, VARTYPE vt
) {
- int elems,i,j;
- SAFEARRAY *darr, *sarr = V_ARRAY(src);
- long *addr;
+ SAFEARRAY *sarr = V_ARRAY(src);
HRESULT hres;
+ LPVOID data;
- hres = SafeArrayAllocDescriptor( sarr->cDims, &darr);
- if (FAILED(hres)) return hres;
- memcpy(
- darr->rgsabound,
- sarr->rgsabound,
- sizeof(sarr->rgsabound[0])*sarr->cDims
- );
- hres = SafeArrayAllocData(darr);
- if (FAILED(hres)) {
- SafeArrayDestroyDescriptor(darr);
- return hres;
- }
- elems = 1;
- for (i=0;i<sarr->cDims;i++)
- elems *= sarr->rgsabound[i].cElements;
- addr = HeapAlloc(GetProcessHeap(),0,sizeof(long)*sarr->cDims);
- for (i=0;i<elems;i++) {
- VARIANT tmpvar,newvar;
- int tmpi = i;
- /* convert absolute value in array address */
- for (j=0;j<sarr->cDims;j++) {
- addr[j] = (tmpi % sarr->rgsabound[j].cElements) + sarr->rgsabound[j].lLbound;
- tmpi /= sarr->rgsabound[j].cElements;
- }
- V_VT(&tmpvar) = V_VT(src) & VT_TYPEMASK;
- hres = SafeArrayGetElement(sarr, addr, &V_UNION(&tmpvar,lVal));
- if (FAILED(hres)) {
- FIXME("Did not get element %d\n",i);
+ switch (vt) {
+ case VT_BSTR:
+ if (sarr->cDims != 1) {
+ FIXME("Can not coerce array with dim %d into BSTR\n", sarr->cDims);
return E_FAIL;
}
- hres = Coerce( &newvar, lcid, wFlags, &tmpvar, vt );
- if (FAILED(hres)) return E_FAIL;
- hres = SafeArrayPutElement( darr, addr, &V_UNION(&newvar,lVal));
- if (FAILED(hres)) {
- FIXME("SAPE failed for element %d, %lx\n",i,hres);
+ switch (V_VT(src) & VT_TYPEMASK) {
+ case VT_UI1:
+ hres = SafeArrayAccessData(sarr, &data);
+ if (FAILED(hres)) return hres;
+
+ /* Yes, just memcpied apparently. */
+ V_BSTR(dst) = SysAllocStringByteLen(data, sarr->rgsabound[0].cElements);
+ hres = SafeArrayUnaccessData(sarr);
+ if (FAILED(hres)) return hres;
+ break;
+ default:
+ FIXME("Cannot coerce array of %d into BSTR yet. Please report!\n", V_VT(src) & VT_TYPEMASK);
return E_FAIL;
}
+ break;
+ default:
+ FIXME("Cannot coerce array into vt %d yet. Please report/implement!\n", vt);
+ return E_FAIL;
}
- HeapFree(GetProcessHeap(),0,addr);
- *narr = darr;
return S_OK;
}
@@ -2239,7 +2227,6 @@
*/
VariantClear( &Variant );
}
-
} else {
if (V_VT(pvargSrc) & VT_ARRAY) {
if ((V_VT(pvargSrc) & 0xf000) != VT_ARRAY) {
@@ -2247,7 +2234,7 @@
return E_FAIL;
}
V_VT(pvargDest) = VT_ARRAY | vt;
- res = coerce_array(pvargSrc, &V_ARRAY(pvargDest), lcid, wFlags, vt);
+ res = coerce_array(pvargSrc, pvargDest, lcid, wFlags, vt);
} else {
if ((V_VT(pvargSrc) & 0xf000)) {
FIXME("VT_TYPEMASK %x is unhandled in normal case.\n",V_VT(pvargSrc) & VT_TYPEMASK);
@@ -5022,14 +5010,40 @@
V_VT(out) = VT_NULL;
return S_OK;
}
- else if (V_VT(left) == VT_BSTR && V_VT(right) == VT_BSTR)
+
+ if (V_VT(left) == VT_BSTR && V_VT(right) == VT_BSTR)
{
V_VT(out) = VT_BSTR;
VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out));
return S_OK;
}
- else
- FIXME ("types not supported\n");
+ if (V_VT(left) == VT_BSTR) {
+ VARIANT bstrvar;
+ HRESULT hres;
+
+ V_VT(out) = VT_BSTR;
+ hres = VariantChangeTypeEx(&bstrvar,right,0,0,VT_BSTR);
+ if (hres) {
+ FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
+ return hres;
+ }
+ VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar), &V_BSTR(out));
+ return S_OK;
+ }
+ if (V_VT(right) == VT_BSTR) {
+ VARIANT bstrvar;
+ HRESULT hres;
+
+ V_VT(out) = VT_BSTR;
+ hres = VariantChangeTypeEx(&bstrvar,left,0,0,VT_BSTR);
+ if (hres) {
+ FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right));
+ return hres;
+ }
+ VarBstrCat (V_BSTR(&bstrvar), V_BSTR(right), &V_BSTR(out));
+ return S_OK;
+ }
+ FIXME ("types %d / %d not supported\n",V_VT(left)&VT_TYPEMASK, V_VT(right)&VT_TYPEMASK);
return S_OK;
}
Index: tests/safearray.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/tests/safearray.c,v
retrieving revision 1.1
diff -u -r1.1 safearray.c
--- tests/safearray.c 23 Dec 2002 02:02:49 -0000 1.1
+++ tests/safearray.c 24 Dec 2002 13:37:30 -0000
@@ -37,7 +37,7 @@
#include "oleauto.h"
#define VARTYPE_NOT_SUPPORTED 0
-static int vttypes[] = {
+static UINT vttypes[] = {
/* this is taken from wtypes.h. Only [S]es are supported by the SafeArray */
VARTYPE_NOT_SUPPORTED, /* VT_EMPTY [V] [P] nothing */
VARTYPE_NOT_SUPPORTED, /* VT_NULL [V] [P] SQL style Nul */
@@ -88,9 +88,11 @@
START_TEST(safearray)
{
SAFEARRAY *a;
- int i;
+ unsigned int i;
HRESULT hres;
SAFEARRAYBOUND bound;
+ VARIANT v;
+ LPVOID data;
hres = SafeArrayAllocDescriptor(0,&a);
ok(E_INVALIDARG == hres,"SAAD(0) failed with hres %lx",hres);
@@ -100,12 +102,12 @@
for (i=1;i<100;i++) {
hres=SafeArrayAllocDescriptor(i,&a);
- ok(S_OK == hres,"SAAD(%d) failed with %lx\n",i,hres);
+ ok(S_OK == hres,"SAAD(%d) failed with %lx",i,hres);
- ok(a->cDims == i,"a->cDims not initialised?\n");
+ ok(a->cDims == i,"a->cDims not initialised?");
hres=SafeArrayDestroyDescriptor(a);
- ok(S_OK == hres,"SADD failed with %lx\n",hres);
+ ok(S_OK == hres,"SADD failed with %lx",hres);
}
hres=SafeArrayAllocDescriptor(65535,&a);
@@ -124,13 +126,29 @@
bound.cElements = 1;
bound.lLbound = 0;
a = SafeArrayCreate(-1, 1, &bound);
- ok(NULL == a,"SAC(-1,1,[1,0]) not failed?\n");
+ ok(NULL == a,"SAC(-1,1,[1,0]) not failed?");
for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
a = SafeArrayCreate(i, 1, &bound);
ok( ((a == NULL) && (vttypes[i] == 0)) ||
((a != NULL) && (vttypes[i] == a->cbElements)),
- "SAC(%d,1,[1,0]), result %ld, expected %d\n",i,(a?a->cbElements:0),vttypes[i]
+ "SAC(%d,1,[1,0]), result %ld, expected %d",i,(a?a->cbElements:0),vttypes[i]
);
}
+
+
+ /* Test conversion of type|VT_ARRAY <-> VT_BSTR */
+ bound.lLbound = 0;
+ bound.cElements = 10;
+ a = SafeArrayCreate(VT_UI1, 1, &bound);
+ ok(a != NULL, "SAC failed.");
+ ok(S_OK == SafeArrayAccessData(a, &data),"SACD failed");
+ memcpy(data,"Hello World",10);
+ ok(S_OK == SafeArrayUnaccessData(a),"SAUD failed");
+ V_VT(&v) = VT_ARRAY|VT_UI1;
+ V_ARRAY(&v) = a;
+ hres = VariantChangeTypeEx(&v, &v, 0, 0, VT_BSTR);
+ ok(hres==S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %lx",hres);
+ ok(V_VT(&v) == VT_BSTR,"CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.",V_VT(&v));
+ ok(V_BSTR(&v)[0] == 0x6548,"First letter are not 'He', but %x", V_BSTR(&v)[0]);
}
Index: tests/vartest.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/tests/vartest.c,v
retrieving revision 1.5
diff -u -r1.5 vartest.c
--- tests/vartest.c 24 Dec 2002 00:49:27 -0000 1.5
+++ tests/vartest.c 24 Dec 2002 13:37:41 -0000
@@ -2610,12 +2610,20 @@
sprintf(msg,"vt %d, return value %lx, expected was %lx",vartypes[i].ind,rc,vartypes[i].vcex1);
ok(vartypes[i].vcex2 == rc, msg);
- V_VT(&va) = 99;
- d = 4.123;
- V_UNION(&va,dblVal) = d;
- ok(DISP_E_BADVARTYPE == VariantClear( &va ), "should give DISP_E_BADVARTYPE");
}
#endif
+
+ V_VT(&va) = 99;
+ d = 4.123;
+ V_UNION(&va,dblVal) = d;
+ ok(DISP_E_BADVARTYPE == VariantClear( &va ), "should give DISP_E_BADVARTYPE");
+
+ V_VT(&va) = VT_BOOL;
+ V_BOOL(&va) = VARIANT_TRUE;
+ V_BOOL(&vb) = 99;
+
+ ok(S_OK == VariantCopy(&va, &vb),"VariantCopy to illegal variant did not return S_OK");
+
VariantClear( &va );
VariantClear( &vb );
VariantClear( &vc );
More information about the wine-patches
mailing list