Beispiel #1
0
    def ParseRecord(self, tinfo, ta):
        members = []  # will be filled later
        struct_name, doc, helpcntext, helpfile = tinfo.GetDocumentation(-1)
        struct = typedesc.Structure(struct_name,
                                    align=ta.cbAlignment * 8,
                                    members=members,
                                    bases=[],
                                    size=ta.cbSizeInstance * 8)
        self._register(struct_name, struct)

        if ta.guid:
            tlib, _ = tinfo.GetContainingTypeLib()
            tlib_ta = tlib.GetLibAttr()
            struct._recordinfo_ = (str(tlib_ta.guid), tlib_ta.wMajorVerNum,
                                   tlib_ta.wMinorVerNum, tlib_ta.lcid,
                                   str(ta.guid))

        for i in range(ta.cVars):
            vd = tinfo.GetVarDesc(i)
            name = tinfo.GetDocumentation(vd.memid)[0]
            offset = vd._.oInst * 8
            assert vd.varkind == typeinfo.VAR_PERINSTANCE
            typ = self.make_type(vd.elemdescVar.tdesc, tinfo)
            field = typedesc.Field(
                name,
                typ,
                None,  # bits
                offset)
            members.append(field)
        return struct
    def make_type(self, tdesc, tinfo):
        try:
            return COMTYPES[tdesc.vt]
        except KeyError:
            pass

        if tdesc.vt == automation.VT_CARRAY:
            typ = self.make_type(tdesc._.lpadesc[0].tdescElem, tinfo)
            for i in range(tdesc._.lpadesc[0].cDims):
                typ = typedesc.ArrayType(
                    typ, tdesc._.lpadesc[0].rgbounds[i].lLbound,
                    tdesc._.lpadesc[0].rgbounds[i].cElements - 1)
            return typ

        elif tdesc.vt == automation.VT_PTR:
            typ = self.make_type(tdesc._.lptdesc[0], tinfo)
            return PTR(typ)

        elif tdesc.vt == automation.VT_USERDEFINED:
            try:
                ti = tinfo.GetRefTypeInfo(tdesc._.hreftype)
            except COMError as details:
                type_name = "__error_hreftype_%d__" % tdesc._.hreftype
                tlib_name = get_tlib_filename(self.tlib)
                if tlib_name is None:
                    tlib_name = "unknown typelib"
                message = "\n\tGetRefTypeInfo failed in %s: %s\n\tgenerating type '%s' instead" % \
                          (tlib_name, details, type_name)
                import warnings
                warnings.warn(message, UserWarning)
                result = typedesc.Structure(type_name,
                                            align=8,
                                            members=[],
                                            bases=[],
                                            size=0)
                return result
            result = self.parse_typeinfo(ti)
            assert result is not None, ti.GetDocumentation(-1)[0]
            return result

        elif tdesc.vt == automation.VT_SAFEARRAY:
            # SAFEARRAY(<type>), see Don Box pp.331f
            itemtype = self.make_type(tdesc._.lptdesc[0], tinfo)
            return midlSAFEARRAY(itemtype)

        raise NotImplementedError(tdesc.vt)
Beispiel #3
0
    def ParseRecord(self, tinfo, ta):
        members = [] # will be filled later
        struct_name, doc, helpcntext, helpfile = tinfo.GetDocumentation(-1)
        struct = typedesc.Structure(struct_name,
                                    align=ta.cbAlignment*8,
                                    members=members,
                                    bases=[],
                                    size=ta.cbSizeInstance*8)
        self._register(struct_name, struct)

        tlib, _ = tinfo.GetContainingTypeLib()
        tlib_ta = tlib.GetLibAttr()
        # If this is a 32-bit typlib being loaded in a 64-bit process, then the
        # size and alignment are incorrect. Set the size to None to disable
        # size checks and correct the alignment.
        if is_64bits and tlib_ta.syskind == typeinfo.SYS_WIN32:
            struct.size = None
            struct.align = 64

        if ta.guid:
            struct._recordinfo_ = (str(tlib_ta.guid),
                                   tlib_ta.wMajorVerNum, tlib_ta.wMinorVerNum,
                                   tlib_ta.lcid,
                                   str(ta.guid))

        for i in range(ta.cVars):
            vd = tinfo.GetVarDesc(i)
            name = tinfo.GetDocumentation(vd.memid)[0]
            offset = vd._.oInst * 8
            assert vd.varkind == typeinfo.VAR_PERINSTANCE
            typ = self.make_type(vd.elemdescVar.tdesc, tinfo)
            field = typedesc.Field(name,
                                   typ,
                                   None, # bits
                                   offset)
            members.append(field)
        return struct
    def make_type(self, tdesc, tinfo):
        try:
            return COMTYPES[tdesc.vt]
        except KeyError:
            pass

        if tdesc.vt == automation.VT_CARRAY:
            typ = self.make_type(tdesc._.lpadesc[0].tdescElem, tinfo)
            for i in range(tdesc._.lpadesc[0].cDims):
                typ = typedesc.ArrayType(
                    typ, tdesc._.lpadesc[0].rgbounds[i].lLbound,
                    tdesc._.lpadesc[0].rgbounds[i].cElements - 1)
            return typ

        elif tdesc.vt == automation.VT_PTR:
            typ = self.make_type(tdesc._.lptdesc[0], tinfo)
            return PTR(typ)

        elif tdesc.vt == automation.VT_USERDEFINED:
            try:
                ti = tinfo.GetRefTypeInfo(tdesc._.hreftype)
            except COMError, details:
                type_name = "__error_hreftype_%d__" % tdesc._.hreftype
                message = "\n\tGetRefTypeInfo failed: %s\n\tgenerating type '%s' instead" % \
                          (details, type_name)
                import warnings
                warnings.warn(message, UserWarning)
                result = typedesc.Structure(type_name,
                                            align=8,
                                            members=[],
                                            bases=[],
                                            size=0)
                return result
            result = self.parse_typeinfo(ti)
            assert result is not None, ti.GetDocumentation(-1)[0]
            return result
Beispiel #5
0
uint_type = typedesc.FundamentalType("unsigned int", 32, 32)
long_type = typedesc.FundamentalType("long int", 32, 32)
ulong_type = typedesc.FundamentalType("long unsigned int", 32, 32)
longlong_type = typedesc.FundamentalType("long long int", 64, 64)
ulonglong_type = typedesc.FundamentalType("long long unsigned int", 64, 64)
float_type = typedesc.FundamentalType("float", 32, 32)
double_type = typedesc.FundamentalType("double", 64, 64)

# basic COM data types
BSTR_type = typedesc.Typedef("BSTR", PTR(wchar_t_type))
SCODE_type = typedesc.Typedef("SCODE", int_type)
VARIANT_BOOL_type = typedesc.Typedef("VARIANT_BOOL", short_type)
HRESULT_type = typedesc.Typedef("HRESULT", ulong_type)

VARIANT_type = typedesc.Structure("VARIANT",
                                  align=alignment(automation.VARIANT)*8,
                                  members=[], bases=[],
                                  size=sizeof(automation.VARIANT)*8)
IDISPATCH_type = typedesc.Typedef("IDispatch", None)
IUNKNOWN_type = typedesc.Typedef("IUnknown", None)
DECIMAL_type = typedesc.Structure("DECIMAL",
                                  align=alignment(automation.DECIMAL)*8,
                                  members=[], bases=[],
                                  size=sizeof(automation.DECIMAL)*8)

def midlSAFEARRAY(typ):
    return typedesc.SAFEARRAYType(typ)

# faked COM data types
CURRENCY_type = longlong_type # slightly wrong; should be scaled by 10000 - use subclass of longlong?
DATE_type = double_type # not *that* wrong...