comtypes icon indicating copy to clipboard operation
comtypes copied to clipboard

Extending IClassFactory Interface in comtypes.servers for IClassFactory2

Open markddavidoff opened this issue 8 years ago • 3 comments

I attempted this but I keep getting "Procedure probably called with too many arguments (16 bytes in excess).

Any help on this? if we can get it to work I'll be opening a pull request to bring this into comtypes.

class IClassFactory2(comtypes.IUnknown):
    _iid_ = comtypes.GUID("{B196B28F-BAB4-101A-B69C-00AA00341D07}")
    _methods_ = [
        comtypes.STDMETHOD(comtypes.HRESULT, "CreateInstance",
                           [ctypes.POINTER(comtypes.IUnknown),
                            ctypes.POINTER(comtypes.GUID),
                            ctypes.POINTER(ctypes.c_void_p)]),
        comtypes.STDMETHOD(comtypes.HRESULT, "LockServer",
                           [ctypes.c_int]),
        comtypes.STDMETHOD(comtypes.HRESULT, "CreateInstanceLic",
                           [ctypes.POINTER(comtypes.IUnknown),
                            ctypes.POINTER(comtypes.IUnknown),
                            ctypes.POINTER(comtypes.GUID),
                            ctypes.POINTER(comtypes.BSTR),
                            ctypes.POINTER(ctypes.c_void_p)])
        ]

    def CreateInstance(self, punkouter=None, interface=None, dynamic=False):
        # HRESULT CreateInstance(
        # [in]  IUnknown *pUnkOuter,
        # [in]  REFIID   riid,
        # [out] void     **ppvObject
        # );

        if dynamic:
            if interface is not None:
                raise ValueError("interface and dynamic are mutually exclusive")
            realInterface = comtypes.automation.IDispatch
        elif interface is None:
            realInterface = comtypes.IUnknown
        else:
            realInterface = interface
        obj = ctypes.POINTER(realInterface)()
        self.__com_CreateInstance(punkouter, realInterface._iid_, ctypes.byref(obj))
        if dynamic:
            return comtypes.client.dynamic.Dispatch(obj)
        elif interface is None:
            # An interface was not specified, so return the best.
            return comtypes.client.GetBestInterface(obj)
        # An interface was specified and obj is already that interface.
        return obj

    def CreateInstanceLic(self, punkouter=None, punkreserved=None, interface=None, key=''):
        # HRESULT CreateInstanceLic(
        # [in]  IUnknown *pUnkOuter,
        # [in]  IUnknown *pUnkReserved,
        # [in]  REFIID   riid,
        # [in]  BSTR     bstrKey,
        # [out] PVOID    *ppvObj
        # );

        # if interface is None:
            # realInterface = comtypes.IUnknown
        # else:
            # realInterface = interface

        #p = ctypes.POINTER(interface)()
        obj = ctypes.POINTER(interface)()
        addr = ctypes.byref(obj)
        iid = interface._iid_

        bstr = comtypes.byref(comtypes.BSTR())
        logger.info("CreateInstanceLic({}, {}, {}, {}, {})".format(punkouter, punkreserved, iid, bstr, addr))
        self.__com_CreateInstanceLic(punkouter, punkreserved, iid, bstr, addr)

        return obj

markddavidoff avatar Mar 25 '16 18:03 markddavidoff

@cfarrow

markddavidoff avatar Mar 29 '16 18:03 markddavidoff

I don't see anything blatantly wrong. (I don't have much experience with the server code, so I'm not sure I'd spot blatant wrongness if it was there.) Where is the error occurring? Please post a full traceback.

cfarrow avatar Mar 29 '16 18:03 cfarrow

I really couldn't figure out how to do it by writing a pretty-CreateObject-like class, but I got it to work with lower level stuff.

https://gist.github.com/markddavidoff/4f0f22e225d0520cfe18

Any interest in adding CreateLicensedObject support to comtypes? I can open a PR based on my gist. @cfarrow

markddavidoff avatar Aug 08 '16 18:08 markddavidoff