oleaut32: Better handle secondary type when generating type descriptors.
This commit is contained in:
parent
fe7e384e07
commit
9fd7f392dc
|
@ -1080,65 +1080,49 @@ static int ctl2_encode_typedesc(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_PTR:
|
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:
|
case VT_SAFEARRAY:
|
||||||
/* FIXME: Make with the error checking. */
|
/* 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);
|
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) {
|
for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
|
||||||
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
|
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) {
|
if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
|
||||||
int mix_field;
|
int mix_field;
|
||||||
|
|
||||||
if (target_type & 0x80000000) {
|
if (target_type & 0x80000000) {
|
||||||
mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY;
|
mix_field = (target_type >> 16) & VT_TYPEMASK;
|
||||||
} else {
|
} else {
|
||||||
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
|
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);
|
typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
|
||||||
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
|
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;
|
typedata[1] = target_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,17 +1166,34 @@ static int ctl2_encode_typedesc(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VT_USERDEFINED:
|
case VT_USERDEFINED:
|
||||||
|
{
|
||||||
|
const MSFT_TypeInfoBase *basetype;
|
||||||
|
INT basevt = 0x7fff;
|
||||||
|
|
||||||
TRACE("USERDEFINED.\n");
|
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) {
|
for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
|
||||||
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
|
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) {
|
if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) {
|
||||||
typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
|
typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0);
|
||||||
typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
|
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;
|
typedata[1] = tdesc->u.hreftype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,6 +1201,7 @@ static int ctl2_encode_typedesc(
|
||||||
*width = 0;
|
*width = 0;
|
||||||
*alignment = 1;
|
*alignment = 1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME("Unrecognized type %d.\n", tdesc->vt);
|
FIXME("Unrecognized type %d.\n", tdesc->vt);
|
||||||
|
|
Loading…
Reference in New Issue