Andrey Turkin : oleaut32: Better handle secondary type when generating type descriptors.
Alexandre Julliard
julliard at winehq.org
Tue Jul 20 11:20:32 CDT 2010
Module: wine
Branch: master
Commit: 9fd7f392dc9bf9765d11e80957a4befe60891172
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9fd7f392dc9bf9765d11e80957a4befe60891172
Author: Andrey Turkin <andrey.turkin at gmail.com>
Date: Sat Jul 17 11:40:23 2010 +0400
oleaut32: Better handle secondary type when generating type descriptors.
---
dlls/oleaut32/typelib2.c | 84 +++++++++++++++++++++++----------------------
1 files changed, 43 insertions(+), 41 deletions(-)
diff --git a/dlls/oleaut32/typelib2.c b/dlls/oleaut32/typelib2.c
index 10e26fb..1096ea8 100644
--- a/dlls/oleaut32/typelib2.c
+++ b/dlls/oleaut32/typelib2.c
@@ -1080,65 +1080,49 @@ static int ctl2_encode_typedesc(
break;
case VT_PTR:
- /* FIXME: Make with the error checking. */
- FIXME("PTR vartype, may not work correctly.\n");
-
- ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
-
- for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
- typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
- if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break;
- }
-
- if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
- int mix_field;
-
- if (target_type & 0x80000000) {
- mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
- } else {
- typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
- mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
- }
-
- typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
- typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
-
- typedata[0] = (mix_field << 16) | VT_PTR;
- typedata[1] = target_type;
- }
-
- *encoded_tdesc = typeoffset;
-
- *width = 4;
- *alignment = 4;
- *decoded_size = sizeof(TYPEDESC) + child_size;
- break;
-
case VT_SAFEARRAY:
/* FIXME: Make with the error checking. */
- FIXME("SAFEARRAY vartype, may not work correctly.\n");
+ FIXME("PTR or SAFEARRAY vartype, may not work correctly.\n");
ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
- if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break;
+ if (((typedata[0] & 0xffff) == tdesc->vt) && (typedata[1] == target_type)) break;
}
if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
int mix_field;
if (target_type & 0x80000000) {
- mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY;
+ mix_field = (target_type >> 16) & VT_TYPEMASK;
} else {
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
- mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe;
+ switch((typedata[0]>>16) & ~VT_ARRAY)
+ {
+ case VT_UI1:
+ case VT_I1:
+ case VT_UI2:
+ case VT_I2:
+ case VT_I4:
+ case VT_UI4:
+ mix_field = typedata[0]>>16;
+ break;
+ default:
+ mix_field = 0x7fff;
+ break;
+ }
}
+ if (tdesc->vt == VT_PTR)
+ mix_field |= VT_BYREF;
+ else if (tdesc->vt == VT_SAFEARRAY)
+ mix_field |= VT_ARRAY;
+
typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
- typedata[0] = (mix_field << 16) | VT_SAFEARRAY;
+ typedata[0] = (mix_field << 16) | tdesc->vt;
typedata[1] = target_type;
}
@@ -1182,17 +1166,34 @@ static int ctl2_encode_typedesc(
break;
}
case VT_USERDEFINED:
+ {
+ const MSFT_TypeInfoBase *basetype;
+ INT basevt = 0x7fff;
+
TRACE("USERDEFINED.\n");
+ if (tdesc->u.hreftype % sizeof(*basetype) == 0 && tdesc->u.hreftype < This->typelib_segdir[MSFT_SEG_TYPEINFO].length)
+ {
+ basetype = (MSFT_TypeInfoBase*)&(This->typelib_segment_data[MSFT_SEG_TYPEINFO][tdesc->u.hreftype]);
+ switch(basetype->typekind & 0xf)
+ {
+ case TKIND_ENUM:
+ basevt = VT_I4;
+ break;
+ default:
+ FIXME("USERDEFINED basetype %d not handled\n", basetype->typekind & 0xf);
+ break;
+ }
+ }
for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
- if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
+ if ((typedata[0] == ((basevt << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break;
}
if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
- typedata[0] = (0x7fff << 16) | VT_USERDEFINED;
+ typedata[0] = (basevt << 16) | VT_USERDEFINED;
typedata[1] = tdesc->u.hreftype;
}
@@ -1200,6 +1201,7 @@ static int ctl2_encode_typedesc(
*width = 0;
*alignment = 1;
break;
+ }
default:
FIXME("Unrecognized type %d.\n", tdesc->vt);
More information about the wine-cvs
mailing list