Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
universal.py227 linesDownload Raw Back to win32com
1# Code that packs and unpacks the Univgw structures.2 3# See if we have a special directory for the binaries (for developers)4 5import pythoncom6from win32com.client import gencache7 8com_error = pythoncom.com_error9_univgw = pythoncom._univgw10 11 12def RegisterInterfaces(typelibGUID, lcid, major, minor, interface_names=None):13    ret = []  # return a list of (dispid, funcname for our policy's benefit14    # First see if we have makepy support.  If so, we can probably satisfy the request without loading the typelib.15    try:16        mod = gencache.GetModuleForTypelib(typelibGUID, lcid, major, minor)17    except ImportError:18        mod = None19    if mod is None:20        import win32com.client.build21 22        # Load up the typelib and build (but don't cache) it now23        tlb = pythoncom.LoadRegTypeLib(typelibGUID, major, minor, lcid)24        typecomp_lib = tlb.GetTypeComp()25        if interface_names is None:26            interface_names = []27            for i in range(tlb.GetTypeInfoCount()):28                info = tlb.GetTypeInfo(i)29                doc = tlb.GetDocumentation(i)30                attr = info.GetTypeAttr()31                if attr.typekind == pythoncom.TKIND_INTERFACE or (32                    attr.typekind == pythoncom.TKIND_DISPATCH33                    and attr.wTypeFlags & pythoncom.TYPEFLAG_FDUAL34                ):35                    interface_names.append(doc[0])36        for name in interface_names:37            type_info, type_comp = typecomp_lib.BindType(38                name,39            )40            # Not sure why we don't get an exception here - BindType's C41            # impl looks correct..42            if type_info is None:43                raise ValueError("The interface '%s' can not be located" % (name,))44            # If we got back a Dispatch interface, convert to the real interface.45            attr = type_info.GetTypeAttr()46            if attr.typekind == pythoncom.TKIND_DISPATCH:47                refhtype = type_info.GetRefTypeOfImplType(-1)48                type_info = type_info.GetRefTypeInfo(refhtype)49                attr = type_info.GetTypeAttr()50            item = win32com.client.build.VTableItem(51                type_info, attr, type_info.GetDocumentation(-1)52            )53            _doCreateVTable(54                item.clsid, item.python_name, item.bIsDispatch, item.vtableFuncs55            )56            for info in item.vtableFuncs:57                names, dispid, desc = info58                invkind = desc[4]59                ret.append((dispid, invkind, names[0]))60    else:61        # Cool - can used cached info.62        if not interface_names:63            interface_names = list(mod.VTablesToClassMap.values())64        for name in interface_names:65            try:66                iid = mod.NamesToIIDMap[name]67            except KeyError:68                raise ValueError(69                    "Interface '%s' does not exist in this cached typelib" % (name,)70                )71            #            print "Processing interface", name72            sub_mod = gencache.GetModuleForCLSID(iid)73            is_dispatch = getattr(sub_mod, name + "_vtables_dispatch_", None)74            method_defs = getattr(sub_mod, name + "_vtables_", None)75            if is_dispatch is None or method_defs is None:76                raise ValueError("Interface '%s' is IDispatch only" % (name,))77 78            # And create the univgw defn79            _doCreateVTable(iid, name, is_dispatch, method_defs)80            for info in method_defs:81                names, dispid, desc = info82                invkind = desc[4]83                ret.append((dispid, invkind, names[0]))84    return ret85 86 87def _doCreateVTable(iid, interface_name, is_dispatch, method_defs):88    defn = Definition(iid, is_dispatch, method_defs)89    vtbl = _univgw.CreateVTable(defn, is_dispatch)90    _univgw.RegisterVTable(vtbl, iid, interface_name)91 92 93def _CalcTypeSize(typeTuple):94    t = typeTuple[0]95    if t & (pythoncom.VT_BYREF | pythoncom.VT_ARRAY):96        # Its a pointer.97        cb = _univgw.SizeOfVT(pythoncom.VT_PTR)[1]98    elif t == pythoncom.VT_RECORD:99        # Just because a type library uses records doesn't mean the user100        # is trying to.  We need to better place to warn about this, but it101        # isn't here.102        # try:103        #    import warnings104        #    warnings.warn("warning: records are known to not work for vtable interfaces")105        # except ImportError:106        #    print "warning: records are known to not work for vtable interfaces"107        cb = _univgw.SizeOfVT(pythoncom.VT_PTR)[1]108        # cb = typeInfo.GetTypeAttr().cbSizeInstance109    else:110        cb = _univgw.SizeOfVT(t)[1]111    return cb112 113 114class Arg:115    def __init__(self, arg_info, name=None):116        self.name = name117        self.vt, self.inOut, self.default, self.clsid = arg_info118        self.size = _CalcTypeSize(arg_info)119        # Offset from the beginning of the arguments of the stack.120        self.offset = 0121 122 123class Method:124    def __init__(self, method_info, isEventSink=0):125        all_names, dispid, desc = method_info126        name = all_names[0]127        names = all_names[1:]128        invkind = desc[4]129        arg_defs = desc[2]130        ret_def = desc[8]131 132        self.dispid = dispid133        self.invkind = invkind134        # We dont use this ATM.135        #        self.ret = Arg(ret_def)136        if isEventSink and name[:2] != "On":137            name = "On%s" % name138        self.name = name139        cbArgs = 0140        self.args = []141        for argDesc in arg_defs:142            arg = Arg(argDesc)143            arg.offset = cbArgs144            cbArgs = cbArgs + arg.size145            self.args.append(arg)146        self.cbArgs = cbArgs147        self._gw_in_args = self._GenerateInArgTuple()148        self._gw_out_args = self._GenerateOutArgTuple()149 150    def _GenerateInArgTuple(self):151        # Given a method, generate the in argument tuple152        l = []153        for arg in self.args:154            if arg.inOut & pythoncom.PARAMFLAG_FIN or arg.inOut == 0:155                l.append((arg.vt, arg.offset, arg.size))156        return tuple(l)157 158    def _GenerateOutArgTuple(self):159        # Given a method, generate the out argument tuple160        l = []161        for arg in self.args:162            if (163                arg.inOut & pythoncom.PARAMFLAG_FOUT164                or arg.inOut & pythoncom.PARAMFLAG_FRETVAL165                or arg.inOut == 0166            ):167                l.append((arg.vt, arg.offset, arg.size, arg.clsid))168        return tuple(l)169 170 171class Definition:172    def __init__(self, iid, is_dispatch, method_defs):173        self._iid = iid174        self._methods = []175        self._is_dispatch = is_dispatch176        for info in method_defs:177            entry = Method(info)178            self._methods.append(entry)179 180    def iid(self):181        return self._iid182 183    def vtbl_argsizes(self):184        return [m.cbArgs for m in self._methods]185 186    def vtbl_argcounts(self):187        return [len(m.args) for m in self._methods]188 189    def dispatch(190        self,191        ob,192        index,193        argPtr,194        ReadFromInTuple=_univgw.ReadFromInTuple,195        WriteFromOutTuple=_univgw.WriteFromOutTuple,196    ):197        "Dispatch a call to an interface method."198        meth = self._methods[index]199        # Infer S_OK if they don't return anything bizarre.200        hr = 0201        args = ReadFromInTuple(meth._gw_in_args, argPtr)202        # If ob is a dispatcher, ensure a policy203        ob = getattr(ob, "policy", ob)204        # Ensure the correct dispid is setup205        ob._dispid_to_func_[meth.dispid] = meth.name206        retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, None, None)207        # None is an allowed return value stating that208        # the code doesn't want to touch any output arguments.209        if type(retVal) == tuple:  # Like pythoncom, we special case a tuple.210            # However, if they want to return a specific HRESULT,211            # then they have to return all of the out arguments212            # AND the HRESULT.213            if len(retVal) == len(meth._gw_out_args) + 1:214                hr = retVal[0]215                retVal = retVal[1:]216            else:217                raise TypeError(218                    "Expected %s return values, got: %s"219                    % (len(meth._gw_out_args) + 1, len(retVal))220                )221        else:222            retVal = [retVal]223            retVal.extend([None] * (len(meth._gw_out_args) - 1))224            retVal = tuple(retVal)225        WriteFromOutTuple(retVal, meth._gw_out_args, argPtr)226        return hr227 
codekingpro/portable-devtools · Team Ai