Commits

Jason Scheirer committed 226061f

Set up .hgignore

Comments (0)

Files changed (55)

+glob:dist/*
+glob:build/*
+glob:*.pyc
+glob:*.*~

build/lib/comtypes/GUID.py

-from ctypes import *
-import sys
-
-if sys.version_info >= (2, 6):
-    def binary(obj):
-        return bytes(obj)
-else:
-    def binary(obj):
-        return buffer(obj)
-
-BYTE = c_byte
-WORD = c_ushort
-DWORD = c_ulong
-
-_ole32 = oledll.ole32
-
-_StringFromCLSID = _ole32.StringFromCLSID
-_CoTaskMemFree = windll.ole32.CoTaskMemFree
-_ProgIDFromCLSID = _ole32.ProgIDFromCLSID
-_CLSIDFromString = _ole32.CLSIDFromString
-_CLSIDFromProgID = _ole32.CLSIDFromProgID
-_CoCreateGuid = _ole32.CoCreateGuid
-
-# Note: Comparing GUID instances by comparing their buffers
-# is slightly faster than using ole32.IsEqualGUID.
-
-class GUID(Structure):
-    _fields_ = [("Data1", DWORD),
-                ("Data2", WORD),
-                ("Data3", WORD),
-                ("Data4", BYTE * 8)]
-
-    def __init__(self, name=None):
-        if name is not None:
-            _CLSIDFromString(unicode(name), byref(self))
-
-    def __repr__(self):
-        return u'GUID("%s")' % unicode(self)
-
-    def __unicode__(self):
-        p = c_wchar_p()
-        _StringFromCLSID(byref(self), byref(p))
-        result = p.value
-        _CoTaskMemFree(p)
-        return result
-    __str__ = __unicode__
-
-    def __cmp__(self, other):
-        if isinstance(other, GUID):
-            return cmp(binary(self), binary(other))
-        return -1
-
-    def __nonzero__(self):
-        return self != GUID_null
-
-    def __eq__(self, other):
-        return isinstance(other, GUID) and \
-               binary(self) == binary(other)
-
-    def __hash__(self):
-        # We make GUID instances hashable, although they are mutable.
-        return hash(binary(self))
-
-    def copy(self):
-        return GUID(unicode(self))
-
-    def from_progid(cls, progid):
-        """Get guid from progid, ...
-        """
-        if hasattr(progid, "_reg_clsid_"):
-            progid = progid._reg_clsid_
-        if isinstance(progid, cls):
-            return progid
-        elif isinstance(progid, basestring):
-            if progid.startswith("{"):
-                return cls(progid)
-            inst = cls()
-            _CLSIDFromProgID(unicode(progid), byref(inst))
-            return inst
-        else:
-            raise TypeError("Cannot construct guid from %r" % progid)
-    from_progid = classmethod(from_progid)
-
-    def as_progid(self):
-        "Convert a GUID into a progid"
-        progid = c_wchar_p()
-        _ProgIDFromCLSID(byref(self), byref(progid))
-        result = progid.value
-        _CoTaskMemFree(progid)
-        return result
-
-    def create_new(cls):
-        "Create a brand new guid"
-        guid = cls()
-        _CoCreateGuid(byref(guid))
-        return guid
-    create_new = classmethod(create_new)
-
-GUID_null = GUID()
-
-__all__ = ["GUID"]

build/lib/comtypes/__init__.py

-import types, sys, os
-
-# comtypes version numbers follow the setuptools convention:
-# http://peak.telecommunity.com/DevCenter/setuptools#specifying-your-project-s-version
-# 0.6.0dev < 0.6.0a < 0.6.0.b < 0.6.0c < 0.6.0
-__version__ = "0.6.3dev"
-
-import logging
-class NullHandler(logging.Handler):
-    """A Handler that does nothing."""
-    def emit(self, record):
-        pass
-
-logger = logging.getLogger(__name__)
-
-# Add a NULL handler to the comtypes logger.  This prevents getting a
-# message like this:
-#    No handlers could be found for logger "comtypes"
-# when logging is not configured and logger.error() is called.
-logger.addHandler(NullHandler())
-
-from ctypes import *
-from _ctypes import COMError
-from comtypes import partial
-
-def _check_version(actual):
-    from comtypes.tools.codegenerator import version as required
-    if actual != required:
-        raise ImportError("Wrong version")
-    if not hasattr(sys, "frozen"):
-        g = sys._getframe(1).f_globals
-        mod_path = g.get("__file__")
-        tlb_path = g.get("typelib_path")
-        try:
-            mod_mtime = os.stat(mod_path).st_mtime
-            tlib_mtime = os.stat(tlb_path).st_mtime
-        except (OSError, TypeError):
-            return
-        if mod_mtime < tlib_mtime:
-            raise ImportError("Typelib newer than module")
-
-try:
-    COMError()
-except TypeError:
-    pass
-else:
-    # Python 2.5 and 2.5.1 have a bug in the COMError implementation:
-    # The type has no __init__ method, and no hresult, text, and
-    # details instance vars.  Work around this bug by monkeypatching
-    # COMError.
-    def monkeypatch_COMError():
-        def __init__(self, hresult, text, details):
-            self.hresult = hresult
-            self.text = text
-            self.details = details
-            super(COMError, self).__init__(hresult, text, details)
-        COMError.__init__ = __init__
-    monkeypatch_COMError()
-    del monkeypatch_COMError
-
-if sys.version_info >= (3, 0):
-    pythonapi.PyInstanceMethod_New.argtypes = [py_object]
-    pythonapi.PyInstanceMethod_New.restype = py_object
-    PyInstanceMethod_Type = type(pythonapi.PyInstanceMethod_New(id))
-
-    def instancemethod(func, inst, cls):
-        mth = PyInstanceMethod_Type(func)
-        if inst is None:
-            return mth
-        return mth.__get__(inst)
-else:
-    def instancemethod(func, inst, cls):
-        return types.MethodType(func, inst, cls)
-
-class ReturnHRESULT(Exception):
-    """ReturnHRESULT(hresult, text)
-
-    Return a hresult code from a COM method implementation
-    without logging an error.
-    """
-
-##class IDLWarning(UserWarning):
-##    "Warn about questionable type information"
-
-from comtypes.GUID import GUID
-_GUID = GUID
-IID = GUID
-DWORD = c_ulong
-
-wireHWND = c_ulong
-
-################################################################
-# About COM apartments:
-# http://blogs.msdn.com/larryosterman/archive/2004/04/28/122240.aspx
-################################################################
-
-################################################################
-# constants for object creation
-CLSCTX_INPROC_SERVER = 1
-CLSCTX_INPROC_HANDLER = 2
-CLSCTX_LOCAL_SERVER = 4
-
-CLSCTX_INPROC = 3
-CLSCTX_SERVER = 5
-CLSCTX_ALL = 7
-
-CLSCTX_INPROC_SERVER16 = 8
-CLSCTX_REMOTE_SERVER = 16
-CLSCTX_INPROC_HANDLER16 = 32
-CLSCTX_RESERVED1 = 64
-CLSCTX_RESERVED2 = 128
-CLSCTX_RESERVED3 = 256
-CLSCTX_RESERVED4 = 512
-CLSCTX_NO_CODE_DOWNLOAD = 1024
-CLSCTX_RESERVED5 = 2048
-CLSCTX_NO_CUSTOM_MARSHAL = 4096
-CLSCTX_ENABLE_CODE_DOWNLOAD = 8192
-CLSCTX_NO_FAILURE_LOG = 16384
-CLSCTX_DISABLE_AAA = 32768
-CLSCTX_ENABLE_AAA = 65536
-CLSCTX_FROM_DEFAULT_CONTEXT = 131072
-
-tagCLSCTX = c_int # enum
-CLSCTX = tagCLSCTX
-
-################################################################
-# Initialization and shutdown
-_ole32 = oledll.ole32
-_ole32_nohresult = windll.ole32 # use this for functions that don't return a HRESULT
-
-COINIT_MULTITHREADED     = 0x0
-COINIT_APARTMENTTHREADED = 0x2
-COINIT_DISABLE_OLE1DDE   = 0x4
-COINIT_SPEED_OVER_MEMORY = 0x8
-
-def CoInitialize():
-    return CoInitializeEx(COINIT_APARTMENTTHREADED)
-
-def CoInitializeEx(flags=None):
-    if flags is None:
-        if os.name == "ce":
-            flags = getattr(sys, "coinit_flags", COINIT_MULTITHREADED)
-        else:
-            flags = getattr(sys, "coinit_flags", COINIT_APARTMENTTHREADED)
-    logger.debug("CoInitializeEx(None, %s)", flags)
-    _ole32.CoInitializeEx(None, flags)
-
-# COM is initialized automatically for the thread that imports this
-# module for the first time.  sys.coinit_flags is passed as parameter
-# to CoInitializeEx, if defined, otherwise COINIT_APARTMENTTHREADED
-# (COINIT_MULTITHREADED on Windows CE) is used.
-#
-# A shutdown function is registered with atexit, so that
-# CoUninitialize is called when Python is shut down.
-CoInitializeEx()
-
-# We need to have CoUninitialize for multithreaded model where we have
-# to initialize and uninitialize COM for every new thread (except main)
-# in which we are using COM
-def CoUninitialize():
-    logger.debug("CoUninitialize()")
-    _ole32_nohresult.CoUninitialize()
-
-def shutdown(func=_ole32_nohresult.CoUninitialize,
-             _debug=logger.debug,
-             _exc_clear=getattr(sys, "exc_clear", lambda: None)):
-    # Make sure no COM pointers stay in exception frames.
-    _exc_clear()
-    # Sometimes, CoUnititialize, running at Python shutdown,
-    # raises an exception.  We suppress this when __debug__ is
-    # False.
-    _debug("Calling CoUnititialize()")
-    if __debug__:
-        func()
-    else:
-        try: func()
-        except WindowsError: pass
-    # Set the flag which means that calling obj.Release() is no longer
-    # needed.
-    if _cominterface_meta is not None:
-        _cominterface_meta._com_shutting_down = True
-    _debug("CoUnititialize() done.")
-
-import atexit
-atexit.register(shutdown)
-del shutdown
-
-################################################################
-# global registries.
-
-# allows to find interface classes by guid strings (iid)
-com_interface_registry = {}
-
-# allows to find coclasses by guid strings (clsid)
-com_coclass_registry = {}
-
-def _is_object(obj):
-    """This function determines if the argument is a COM object.  It
-    is used in several places to determine whether propputref or
-    propput setters have to be used."""
-    from comtypes.automation import VARIANT
-    # A COM pointer is an 'Object'
-    if isinstance(obj, POINTER(IUnknown)):
-        return True
-    # A COM pointer in a VARIANT is an 'Object', too
-    elif isinstance(obj, VARIANT) and isinstance(obj.value, POINTER(IUnknown)):
-        return True
-    # It may be a dynamic dispatch object.
-    return hasattr(obj, "_comobj")
-
-################################################################
-# The metaclasses...
-
-class _cominterface_meta(type):
-    """Metaclass for COM interfaces.  Automatically creates high level
-    methods from COMMETHOD lists.
-    """
-
-    # This flag is set to True by the atexit handler which calls
-    # CoUnititialize.
-    _com_shutting_down = False
-
-    # Creates also a POINTER type for the newly created class.
-    def __new__(self, name, bases, namespace):
-        methods = namespace.pop("_methods_", None)
-        dispmethods = namespace.pop("_disp_methods_", None)
-        cls = type.__new__(self, name, bases, namespace)
-
-        if methods is not None:
-            cls._methods_ = methods
-        if dispmethods is not None:
-            cls._disp_methods_ = dispmethods
-
-        # If we sublass a COM interface, for example:
-        #
-        # class IDispatch(IUnknown):
-        #     ....
-        #
-        # then we need to make sure that POINTER(IDispatch) is a
-        # subclass of POINTER(IUnknown) because of the way ctypes
-        # typechecks work.
-        if bases == (object,):
-            _ptr_bases = (cls, _compointer_base)
-        else:
-            _ptr_bases = (cls, POINTER(bases[0]))
-
-        # The interface 'cls' is used as a mixin.
-        p = type(_compointer_base)("POINTER(%s)" % cls.__name__,
-                                   _ptr_bases,
-                                   {"__com_interface__": cls,
-                                    "_needs_com_addref_": None})
-
-        from ctypes import _pointer_type_cache
-        _pointer_type_cache[cls] = p
-
-        if cls._case_insensitive_:
-            class p(partial.partial, p):
-                # case insensitive attributes for COM methods and properties
-                def __getattr__(self, name):
-                    """Implement case insensitive access to methods and properties"""
-                    try:
-                        fixed_name = self.__map_case__[name.lower()]
-                    except KeyError:
-                        raise AttributeError(name)
-                    if fixed_name != name: # prevent unbounded recursion
-                        return getattr(self, fixed_name)
-                    raise AttributeError(name)
-
-                # __setattr__ is pretty heavy-weight, because it is called for
-                # EVERY attribute assignment.  Settings a non-com attribute
-                # through this function takes 8.6 usec, while without this
-                # function it takes 0.7 sec - 12 times slower.
-                #
-                # How much faster would this be if implemented in C?
-                def __setattr__(self, name, value):
-                    """Implement case insensitive access to methods and properties"""
-                    object.__setattr__(self,
-                                       self.__map_case__.get(name.lower(), name),
-                                       value)
-
-        class _(partial.partial, POINTER(p)):
-            def __setitem__(self, index, value):
-                # We override the __setitem__ method of the
-                # POINTER(POINTER(interface)) type, so that the COM
-                # reference count is managed correctly.
-                #
-                # This is so that we can implement COM methods that have to
-                # return COM pointers more easily and consistent.  Instead of
-                # using CopyComPointer in the method implementation, we can
-                # simply do:
-                #
-                # def GetTypeInfo(self, this, ..., pptinfo):
-                #     if not pptinfo: return E_POINTER
-                #     pptinfo[0] = a_com_interface_pointer
-                #     return S_OK
-                if index != 0:
-                    # CopyComPointer, which is in _ctypes, does only
-                    # handle an index of 0.  This code does what
-                    # CopyComPointer should do if index != 0.
-                    if bool(value):
-                        value.AddRef()
-                    super(_, self).__setitem__(index, value)
-                    return
-                from _ctypes import CopyComPointer
-                CopyComPointer(value, self)
-
-        return cls
-
-    def __setattr__(self, name, value):
-        if name == "_methods_":
-            # XXX I'm no longer sure why the code generator generates
-            # "_methods_ = []" in the interface definition, and later
-            # overrides this by "Interface._methods_ = [...]
-##            assert self.__dict__.get("_methods_", None) is None
-            self._make_methods(value)
-            self._make_specials()
-        elif name == "_disp_methods_":
-            assert self.__dict__.get("_disp_methods_", None) is None
-            self._make_dispmethods(value)
-            self._make_specials()
-        type.__setattr__(self, name, value)
-
-    def _make_specials(self):
-        # This call installs methods that forward the Python protocols
-        # to COM protocols.
-
-        def has_name(name):
-            # Determine whether a property or method named 'name'
-            # exists
-            if self._case_insensitive_:
-                return name.lower() in self.__map_case__
-            return hasattr(self, name)
-
-        # XXX These special methods should be generated by the code generator.
-        if has_name("Count"):
-            class _(partial.partial, self):
-                def __len__(self):
-                    "Return the the 'self.Count' property."
-                    return self.Count
-
-        if has_name("Item"):
-            class _(partial.partial, self):
-                # 'Item' is the 'default' value.  Make it available by
-                # calling the instance (Not sure this makes sense, but
-                # win32com does this also).
-                def __call__(self, *args, **kw):
-                    "Return 'self.Item(*args, **kw)'"
-                    return self.Item(*args, **kw)
-
-##                @partial.noreplace
-                # does this make sense? It seems that all standard typelibs I've
-                # seen so far that support .Item also support ._NewEnum
-                def __getitem__(self, index):
-                    "Return 'self.Item(index)'"
-                    try:
-                        result = self.Item(index)
-                    except COMError, err:
-                        (hresult, text, details) = err.args
-                        if hresult == -2147352565: # DISP_E_BADINDEX
-                            raise IndexError("invalid index")
-                        else:
-                            raise
-                    # Hm, this doesn't look correct...
-                    if not result: # we got a NULL com pointer
-                        raise IndexError("invalid index")
-                    # Hm, should we call __ctypes_from_outparam__ on the result?
-                    return result
-                __getitem__ = partial.noreplace(__getitem__)
-
-        if has_name("_NewEnum"):
-            class _(partial.partial, self):
-                def __iter__(self):
-                    "Return an iterator over the _NewEnum collection."
-                    # This method returns a pointer to _some_ _NewEnum interface.
-                    # It relies on the fact that the code generator creates next()
-                    # methods for them automatically.
-                    #
-                    # Better would maybe to return an object that
-                    # implements the Python iterator protocol, and
-                    # forwards the calls to the COM interface.
-                    enum = self._NewEnum
-                    if isinstance(enum, types.MethodType):
-                        # _NewEnum should be a propget property, with dispid -4.
-                        #
-                        # Sometimes, however, it is a method.
-                        enum = enum()
-                    if hasattr(enum, "Next"):
-                        return enum
-                    # _NewEnum returns an IUnknown pointer, QueryInterface() it to
-                    # IEnumVARIANT
-                    from comtypes.automation import IEnumVARIANT
-                    return enum.QueryInterface(IEnumVARIANT)
-
-    def _make_case_insensitive(self):
-        # The __map_case__ dictionary maps lower case names to the
-        # names in the original spelling to enable case insensitive
-        # method and attribute access.
-        try:
-            self.__dict__["__map_case__"]
-        except KeyError:
-            d = {}
-            d.update(getattr(self, "__map_case__", {}))
-            self.__map_case__ = d
-
-    def _make_dispmethods(self, methods):
-        if self._case_insensitive_:
-            self._make_case_insensitive()
-
-        # create dispinterface methods and properties on the interface 'self'
-        properties = {}
-        for m in methods:
-            what, name, idlflags, restype, argspec = m
-
-            # is it a property set or property get?
-            is_prop = False
-
-            # argspec is a sequence of tuples, each tuple is:
-            # ([paramflags], type, name)
-            try:
-                memid = [x for x in idlflags if isinstance(x, int)][0]
-            except IndexError:
-                raise TypeError("no dispid found in idlflags")
-            if what == "DISPPROPERTY": # DISPPROPERTY
-                assert not argspec # XXX does not yet work for properties with parameters
-                accessor = self._disp_property(memid, idlflags)
-                is_prop = True
-                setattr(self, name, accessor)
-            elif what == "DISPMETHOD": # DISPMETHOD
-                # argspec is a tuple of (idlflags, type, name[,
-                # defval]) items.
-                method = self._disp_method(memid, name, idlflags, restype, argspec)
-## not in 2.3                method.__name__ = name
-                if 'propget' in idlflags:
-                    nargs = len(argspec)
-                    properties.setdefault((name, nargs), [None, None, None])[0] = method
-                    is_prop = True
-                elif 'propput' in idlflags:
-                    nargs = len(argspec)-1
-                    properties.setdefault((name, nargs), [None, None, None])[1] = method
-                    is_prop = True
-                elif 'propputref' in idlflags:
-                    nargs = len(argspec)-1
-                    properties.setdefault((name, nargs), [None, None, None])[2] = method
-                    is_prop = True
-                else:
-                    setattr(self, name, method)
-            # COM is case insensitive.
-            #
-            # For a method, this is the real name.  For a property,
-            # this is the name WITHOUT the _set_ or _get_ prefix.
-            if self._case_insensitive_:
-                self.__map_case__[name.lower()] = name
-                if is_prop:
-                    self.__map_case__[name[5:].lower()] = name[5:]
-
-        for (name, nargs), methods in properties.items():
-            # methods contains [propget or None, propput or None, propputref or None]
-            if methods[1] is not None and methods[2] is not None:
-                # both propput and propputref.
-                #
-                # Create a setter method that examines the argument type
-                # and calls 'propputref' if it is an Object (in the VB
-                # sense), or call 'propput' otherwise.
-                propput = methods[1]
-                propputref = methods[2]
-                def put_or_putref(self, *args):
-                    if _is_object(args[-1]):
-                        return propputref(self, *args)
-                    else:
-                        return propput(self, *args)
-                methods[1] = put_or_putref
-                del methods[2]
-            elif methods[2] is not None:
-                # use propputref
-                del methods[1]
-            else:
-                # use propput (if any)
-                del methods[2]
-            if nargs:
-                setattr(self, name, named_property("%s.%s" % (self.__name__, name), *methods))
-            else:
-                assert len(methods) <= 2
-                setattr(self, name, property(*methods))
-
-            # COM is case insensitive
-            if self._case_insensitive_:
-                self.__map_case__[name.lower()] = name
-
-    # Some ideas, (not only) related to disp_methods:
-    #
-    # Should the functions/methods we create have restype and/or
-    # argtypes attributes?
-
-    def _disp_method(self, memid, name, idlflags, restype, argspec):
-        if 'propget' in idlflags:
-            def getfunc(obj, *args, **kw):
-                return self.Invoke(obj, memid, _invkind=2, *args, **kw) # DISPATCH_PROPERTYGET
-            return getfunc
-        elif 'propput' in idlflags:
-            def putfunc(obj, *args, **kw):
-                return self.Invoke(obj, memid, _invkind=4, *args, **kw) # DISPATCH_PROPERTYPUT
-            return putfunc
-        elif 'propputref' in idlflags:
-            def putfunc(obj, *args, **kw):
-                return self.Invoke(obj, memid, _invkind=8, *args, **kw) # DISPATCH_PROPERTYPUTREF
-            return putfunc
-        # a first attempt to make use of the restype.  Still, support
-        # for named arguments and default argument values should be
-        # added.
-        if hasattr(restype, "__com_interface__"):
-            interface = restype.__com_interface__
-            def func(s, *args, **kw):
-                result = self.Invoke(s, memid, _invkind=1, *args, **kw)
-                return result.QueryInterface(interface)
-        else:
-            def func(obj, *args, **kw):
-                return self.Invoke(obj, memid, _invkind=1, *args, **kw) # DISPATCH_METHOD
-        return func
-
-    def _disp_property(self, memid, idlflags):
-        # XXX doc string missing in property
-        def _get(obj):
-            return obj.Invoke(memid, _invkind=2) # DISPATCH_PROPERTYGET
-        if "readonly" in idlflags:
-            return property(_get)
-        def _set(obj, value):
-            return obj.Invoke(memid, value, _invkind=4) # DISPATCH_PROPERTYPUT
-        return property(_get, _set)
-
-    def __get_baseinterface_methodcount(self):
-        "Return the number of com methods in the base interfaces"
-        try:
-            result = 0
-            for itf in self.mro()[1:-1]:
-                result += len(itf.__dict__["_methods_"])
-            return result
-        except KeyError, err:
-            (name,) = err.args
-            if name == "_methods_":
-                raise TypeError("baseinterface '%s' has no _methods_" % itf.__name__)
-            raise
-
-    def _fix_inout_args(self, func, argtypes, paramflags):
-        # This function provides a workaround for a bug in ctypes.
-        # [in, out] parameters must be converted with the argtype's
-        # .from_param() method BEFORE they are passed to the _ctypes
-        # build_callargs() function in Modules/_ctypes/_ctypes.c.
-        #
-        # For details see below.
-        #
-        # TODO: The workaround should be disabled when a ctypes
-        # version is used where the bug is fixed.
-        SIMPLETYPE = type(c_int)
-        BYREFTYPE = type(byref(c_int()))
-        def call_with_inout(self_, *args, **kw):
-            args = list(args)
-            outargs = []
-            for i, info in enumerate(paramflags):
-                direction = info[0]
-                if direction & 3 == 3:
-                    # This is an [in, out] parameter.
-                    #
-                    # Determine name and required type of the parameter.
-                    name = info[1]
-                    # [in, out] parameters are passed as pointers,
-                    # this is the pointed-to type:
-                    atyp = argtypes[i]._type_
-
-                    # Get the actual parameter, either as positional or
-                    # keyword arg.
-                    try:
-                        try:
-                            v = args[i]
-                        except IndexError:
-                            v = kw[name]
-                    except KeyError:
-                        # no parameter was passed, make an empty one
-                        # of the required type
-                        v = atyp()
-                    else:
-                        # parameter was passed, call .from_param() to
-                        # convert it to a ctypes type.
-                        if getattr(v, "_type_", None) is atyp:
-                            # Array of or pointer to type 'atyp' was
-                            # passed, pointer to 'atyp' expected.
-                            pass
-                        elif type(atyp) is SIMPLETYPE:
-                            # The from_param method of simple types
-                            # (c_int, c_double, ...) returns a byref()
-                            # object which we cannot use since later
-                            # it will be wrapped in a pointer.  Simply
-                            # call the constructor with the argument
-                            # in that case.
-                            v = atyp(v)
-                        else:
-                            v = atyp.from_param(v)
-                            assert not isinstance(v, BYREFTYPE)
-                    outargs.append(v)
-                    if len(args) > i:
-                        args[i] = v
-                    else:
-                        kw[name] = v
-
-            rescode = func(self_, *args, **kw)
-            result = [o.__ctypes_from_outparam__() for o in outargs]
-            if len(result) > 1:
-                return tuple(result)
-            elif len(result) == 1:
-                return result[0]
-            return rescode
-        return call_with_inout
-
-    def _make_methods(self, methods):
-        if self._case_insensitive_:
-            self._make_case_insensitive()
-
-        # we insist on an _iid_ in THIS class!
-        try:
-            iid = self.__dict__["_iid_"]
-        except KeyError:
-            raise AttributeError("this class must define an _iid_")
-        else:
-            iid = str(iid)
-##            if iid in com_interface_registry:
-##                # Warn when multiple interfaces are defined with identical iids.
-##                # This would also trigger if we reload() a module that contains
-##                # interface types, so suppress the warning in this case.
-##                other = com_interface_registry[iid]
-##                if self.__name__ != other.__name__ or self.__module__ != other.__module__:
-##                    text = "Multiple interface defn: %s, %s" % (self, other)
-##                    warnings.warn(text, UserWarning)
-            com_interface_registry[iid] = self
-            del iid
-        vtbl_offset = self.__get_baseinterface_methodcount()
-
-        properties = {}
-
-        # create private low level, and public high level methods
-        for i, item in enumerate(methods):
-            restype, name, argtypes, paramflags, idlflags, doc = item
-            # the function prototype
-            prototype = WINFUNCTYPE(restype, *argtypes)
-
-            # a low level unbound method calling the com method.
-            # attach it with a private name (__com_AddRef, for example),
-            # so that custom method implementations can call it.
-
-            # If the method returns a HRESULT, we pass the interface iid,
-            # so that we can request error info for the interface.
-            if restype == HRESULT:
-##                print "%s.%s" % (self.__name__, name)
-                raw_func = prototype(i + vtbl_offset, name, None, self._iid_)
-                func = prototype(i + vtbl_offset, name, paramflags, self._iid_)
-            else:
-                raw_func = prototype(i + vtbl_offset, name, None, None)
-                func = prototype(i + vtbl_offset, name, paramflags, None)
-            setattr(self,
-                    "_%s__com_%s" % (self.__name__, name),
-                    instancemethod(raw_func, None, self))
-
-            if paramflags:
-                # see comment in the _fix_inout_args method
-                dirflags = [(p[0]&3) for p in paramflags]
-                if 3 in dirflags:
-##                    fullname = "%s::%s" % (self.__name__, name)
-##                    print "FIX %s" % fullname
-                    func = self._fix_inout_args(func, argtypes, paramflags)
-
-            # 'func' is a high level function calling the COM method
-            func.__doc__ = doc
-            try:
-                func.__name__ = name # for pyhelp
-            except TypeError:
-                # In Python 2.3, __name__ is a readonly attribute
-                pass
-            # make it an unbound method.  Remember, 'self' is a type here.
-            mth = instancemethod(func, None, self)
-
-            # is it a property set or property get?
-            is_prop = False
-
-            # XXX Hm.  What, when paramflags is None?
-            # Or does have '0' values?
-            # Seems we loose then, at least for properties...
-
-            # The following code assumes that the docstrings for
-            # propget and propput are identical.
-            if "propget" in idlflags:
-                assert name.startswith("_get_")
-                nargs = len([flags for flags in paramflags
-                             if flags[0] & 7 in (0, 1)])
-                # XXX or should we do this?
-                # nargs = len([flags for flags in paramflags
-                #             if (flags[0] & 1) or (flags[0] == 0)])
-                propname = name[len("_get_"):]
-                properties.setdefault((propname, doc, nargs), [None, None, None])[0] = func
-                is_prop = True
-            elif "propput" in idlflags:
-                assert name.startswith("_set_")
-                nargs = len([flags for flags in paramflags
-                              if flags[0] & 7 in (0, 1)]) - 1
-                propname = name[len("_set_"):]
-                properties.setdefault((propname, doc, nargs), [None, None, None])[1] = func
-                is_prop = True
-            elif "propputref" in idlflags:
-                assert name.startswith("_setref_")
-                nargs = len([flags for flags in paramflags
-                              if flags[0] & 7 in (0, 1)]) - 1
-                propname = name[len("_setref_"):]
-                properties.setdefault((propname, doc, nargs), [None, None, None])[2] = func
-                is_prop = True
-
-            # We install the method in the class, except when it's a
-            # property accessor.  And we make sure we don't overwrite
-            # a property that's already present in the class.
-            if not is_prop:
-                if hasattr(self, name):
-                    setattr(self, "_" + name, mth)
-                else:
-                    setattr(self, name, mth)
-
-            # COM is case insensitive.
-            #
-            # For a method, this is the real name.  For a property,
-            # this is the name WITHOUT the _set_ or _get_ prefix.
-            if self._case_insensitive_:
-                self.__map_case__[name.lower()] = name
-                if is_prop:
-                    self.__map_case__[name[5:].lower()] = name[5:]
-
-        # create public properties / attribute accessors
-        for (name, doc, nargs), methods in properties.items():
-            # methods contains [propget or None, propput or None, propputref or None]
-            if methods[1] is not None and methods[2] is not None:
-                # both propput and propputref.
-                #
-                # Create a setter method that examines the argument type
-                # and calls 'propputref' if it is an Object (in the VB
-                # sense), or call 'propput' otherwise.
-                propput = methods[1]
-                propputref = methods[2]
-                def put_or_putref(self, *args):
-                    if _is_object(args[-1]):
-                        return propputref(self, *args)
-                    else:
-                        return propput(self, *args)
-                methods[1] = put_or_putref
-                del methods[2]
-            elif methods[2] is not None:
-                # use propputref
-                del methods[1]
-            else:
-                # use propput (if any)
-                del methods[2]
-            if nargs == 0:
-                prop = property(*methods + [None, doc])
-            else:
-                # Hm, must be a descriptor where the __get__ method
-                # returns a bound object having __getitem__ and
-                # __setitem__ methods.
-                prop = named_property("%s.%s" % (self.__name__, name), *methods + [doc])
-            # Again, we should not overwrite class attributes that are
-            # already present.
-            if hasattr(self, name):
-                setattr(self, "_" + name, prop)
-            else:
-                setattr(self, name, prop)
-
-            # COM is case insensitive
-            if self._case_insensitive_:
-                self.__map_case__[name.lower()] = name
-
-
-################################################################
-# helper classes for COM propget / propput
-# Should they be implemented in C for speed?
-
-class bound_named_property(object):
-    def __init__(self, name, getter, setter, im_inst):
-        self.name = name
-        self.im_inst = im_inst
-        self.getter = getter
-        self.setter = setter
-
-    def __getitem__(self, index):
-        if self.getter is None:
-            raise TypeError("unsubscriptable object")
-        if isinstance(index, tuple):
-            return self.getter(self.im_inst, *index)
-        else:
-            return self.getter(self.im_inst, index)
-
-    def __call__(self, *args):
-        if self.getter is None:
-            raise TypeError("object is not callable")
-        return self.getter(self.im_inst, *args)
-
-    def __setitem__(self, index, value):
-        if self.setter is None:
-            raise TypeError("object does not support item assignment")
-        if isinstance(index, tuple):
-            self.setter(self.im_inst, *(index + (value,)))
-        else:
-            self.setter(self.im_inst, index, value)
-
-    def __repr__(self):
-        return "<bound_named_property %r at %x>" % (self.name, id(self))
-
-class named_property(object):
-    def __init__(self, name, fget=None, fset=None, doc=None):
-        self.name = name
-        self.getter = fget
-        self.setter = fset
-        self.__doc__ = doc
-
-    def __get__(self, im_inst, im_class=None):
-        if im_inst is None:
-            return self
-        return bound_named_property(self.name, self.getter, self.setter, im_inst)
-
-    # Make this a data descriptor
-    def __set__(self, obj):
-        raise AttributeError("Unsettable attribute")
-
-    def __repr__(self):
-        return "<named_property %r at %x>" % (self.name, id(self))
-
-################################################################
-
-class _compointer_meta(type(c_void_p), _cominterface_meta):
-    "metaclass for COM interface pointer classes"
-    # no functionality, but needed to avoid a metaclass conflict
-
-class _compointer_base(c_void_p):
-    "base class for COM interface pointer classes"
-    __metaclass__ = _compointer_meta
-    def __del__(self, _debug=logger.debug):
-        "Release the COM refcount we own."
-        if self:
-            # comtypes calls CoUnititialize() when the atexit handlers
-            # runs.  CoUninitialize() cleans up the COM objects that
-            # are still alive. Python COM pointers may still be
-            # present but we can no longer call Release() on them -
-            # this may give a protection fault.  So we need the
-            # _com_shutting_down flag.
-            #
-            if not type(self)._com_shutting_down:
-                _debug("Release %s", self)
-                self.Release()
-
-    def __cmp__(self, other):
-        """Compare pointers to COM interfaces."""
-        # COM identity rule
-        #
-        # XXX To compare COM interface pointers, should we
-        # automatically QueryInterface for IUnknown on both items, and
-        # compare the pointer values?
-        if not isinstance(other, _compointer_base):
-            return 1
-
-        # get the value property of the c_void_p baseclass, this is the pointer value
-        return cmp(super(_compointer_base, self).value, super(_compointer_base, other).value)
-
-    def __eq__(self, other):
-        if not isinstance(other, _compointer_base):
-            return False
-        # get the value property of the c_void_p baseclass, this is the pointer value
-        return super(_compointer_base, self).value == super(_compointer_base, other).value
-
-    def __hash__(self):
-        """Return the hash value of the pointer."""
-        # hash the pointer values
-        return hash(super(_compointer_base, self).value)
-
-    # redefine the .value property; return the object itself.
-    def __get_value(self):
-        return self
-    value = property(__get_value, doc="""Return self.""")
-
-    def __repr__(self):
-        ptr = super(_compointer_base, self).value
-        return "<%s ptr=0x%x at %x>" % (self.__class__.__name__, ptr or 0, id(self))
-
-    # This fixes the problem when there are multiple python interface types
-    # wrapping the same COM interface.  This could happen because some interfaces
-    # are contained in multiple typelibs.
-    #
-    # It also allows to pass a CoClass instance to an api
-    # expecting a COM interface.
-    def from_param(klass, value):
-        """Convert 'value' into a COM pointer to the interface.
-
-        This method accepts a COM pointer, or a CoClass instance
-        which is QueryInterface()d."""
-        if value is None:
-            return None
-        if isinstance(value, klass):
-            return value
-        # multiple python interface types for the same COM interface.
-        # Do we need more checks here?
-        if klass._iid_ == getattr(value, "_iid_", None):
-            return value
-        # Accept an CoClass instance which exposes the interface required.
-        try:
-            table = value._com_pointers_
-        except AttributeError:
-            pass
-        else:
-            try:
-                # a kind of QueryInterface
-                return table[klass._iid_]
-            except KeyError:
-                raise TypeError("Interface %s not supported" % klass._iid_)
-        return value.QueryInterface(klass.__com_interface__)
-    from_param = classmethod(from_param)
-
-################################################################
-
-from ctypes import _SimpleCData
-
-class BSTR(_SimpleCData):
-    "The windows BSTR data type"
-    _type_ = "X"
-    _needsfree = False
-    def __repr__(self):
-        return "%s(%r)" % (self.__class__.__name__, self.value)
-
-    def __ctypes_from_outparam__(self):
-        self._needsfree = True
-        return self.value
-
-    def __del__(self, _free=windll.oleaut32.SysFreeString):
-        # Free the string if self owns the memory
-        # or if instructed by __ctypes_from_outparam__.
-        if self._b_base_ is None \
-               or self._needsfree:
-            _free(self)
-
-    def from_param(cls, value):
-        """Convert into a foreign function call parameter."""
-        if isinstance(value, cls):
-            return value
-        # Although the builtin SimpleCData.from_param call does the
-        # right thing, it doesn't ensure that SysFreeString is called
-        # on destruction.
-        return cls(value)
-    from_param = classmethod(from_param)
-
-################################################################
-# IDL stuff
-
-class helpstring(unicode):
-    "Specifies the helpstring for a COM method or property."
-
-class defaultvalue(object):
-    "Specifies the default value for parameters marked optional."
-    def __init__(self, value):
-        self.value = value
-
-class dispid(int):
-    "Specifies the DISPID of a method or property."
-
-# XXX STDMETHOD, COMMETHOD, DISPMETHOD, and DISPPROPERTY should return
-# instances with methods, or at least accessors instead of tuple.
-
-def STDMETHOD(restype, name, argtypes=()):
-    "Specifies a COM method slot without idlflags"
-    # restype, name, argtypes, paramflags, idlflags, docstring
-    return restype, name, argtypes, None, (), None
-
-def DISPMETHOD(idlflags, restype, name, *argspec):
-    "Specifies a method of a dispinterface"
-    return "DISPMETHOD", name, idlflags, restype, argspec
-
-def DISPPROPERTY(idlflags, proptype, name):
-    "Specifies a property of a dispinterface"
-    return "DISPPROPERTY", name, idlflags, proptype, ()#, argspec
-
-# COMMETHOD returns:
-# restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext
-#
-# paramflags is a sequence of (flags (integer), paramname (string)
-# tuple(idlflags) is for the method itself: (dispid, 'readonly')
-#
-# Example: (HRESULT, 'Width', (c_long,), (2, 'rhs'), (4, 'readonly'), None)
-
-## sample generated code:
-##    DISPPROPERTY([5, 'readonly'], OLE_YSIZE_HIMETRIC, 'Height'),
-##    DISPMETHOD([6], None, 'Render',
-##               ( [], c_int, 'hdc' ),
-##               ( [], c_int, 'x' ),
-##               ( [], c_int, 'y' ))
-
-################################################################
-
-_PARAMFLAGS = {
-    "in": 1,
-    "out": 2,
-    "lcid": 4,
-    "retval": 8,
-    "optional": 16,
-    }
-
-def _encode_idl(names):
-    # sum up all values found in _PARAMFLAGS, ignoring all others.
-    return sum([_PARAMFLAGS.get(n, 0) for n in names])
-
-_NOTHING = object()
-def _unpack_argspec(idl, typ, name=None, defval=_NOTHING):
-    return idl, typ, name, defval
-
-def COMMETHOD(idlflags, restype, methodname, *argspec):
-    """Specifies a COM method slot with idlflags.
-
-    XXX should explain the sematics of the arguments.
-    """
-    paramflags = []
-    argtypes = []
-
-    # collect all helpstring instances
-    # We should suppress docstrings when Python is started with -OO
-    helptext = [t for t in idlflags if isinstance(t, helpstring)]
-    # join them together(does this make sense?) and replace by None if empty.
-    helptext = "".join(helptext) or None
-
-    from comtypes.automation import VARIANT
-
-    for item in argspec:
-        idl, typ, argname, defval = _unpack_argspec(*item)
-        pflags = _encode_idl(idl)
-        if "optional" in idl:
-            if defval is _NOTHING:
-                if typ is VARIANT:
-                    defval = VARIANT.missing
-                elif typ is POINTER(VARIANT):
-                    defval = pointer(VARIANT.missing)
-                else:
-##                    msg = ("'optional' only allowed for VARIANT and VARIANT*, not for %s"
-##                           % typ.__name__)
-##                    warnings.warn(msg, IDLWarning, stacklevel=2)
-                    defval = typ()
-        if defval is _NOTHING:
-            paramflags.append((pflags, argname))
-        else:
-            paramflags.append((pflags, argname, defval))
-        argtypes.append(typ)
-    if "propget" in idlflags:
-        methodname = "_get_%s" % methodname
-    elif "propput" in idlflags:
-        methodname = "_set_%s" % methodname
-    elif "propputref" in idlflags:
-        methodname = "_setref_%s" % methodname
-    return restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext
-
-################################################################
-# IUnknown, the root of all evil...
-
-class IUnknown(object):
-    """The most basic COM interface.
-
-    Each subclasses of IUnknown must define these class attributes:
-
-    _iid_ - a GUID instance defining the identifier of this interface
-
-    _methods_ - a list of methods for this interface.
-
-    The _methods_ list must in VTable order.  Methods are specified
-    with STDMETHOD or COMMETHOD calls.
-    """
-    _case_insensitive_ = False
-    __metaclass__ = _cominterface_meta
-    _iid_ = GUID("{00000000-0000-0000-C000-000000000046}")
-
-    _methods_ = [
-        STDMETHOD(HRESULT, "QueryInterface",
-                  [POINTER(GUID), POINTER(c_void_p)]),
-        STDMETHOD(c_ulong, "AddRef"),
-        STDMETHOD(c_ulong, "Release")
-    ]
-
-    def QueryInterface(self, interface, iid=None):
-        "QueryInterface(interface) -> instance"
-        p = POINTER(interface)()
-        if iid is None:
-            iid = interface._iid_
-        self.__com_QueryInterface(byref(iid), byref(p))
-        clsid = self.__dict__.get('__clsid')
-        if clsid is not None:
-            p.__dict__['__clsid'] = clsid
-        return p
-
-    # these are only so that they get a docstring.
-    # XXX There should be other ways to install a docstring.
-    def AddRef(self):
-        "Increase the internal refcount by one and return it."
-        return self.__com_AddRef()
-
-    def Release(self):
-        "Decrease the internal refcount by one and return it."
-        return self.__com_Release()
-
-# IPersist is a trivial interface, which allows to ask an object about
-# its clsid.
-class IPersist(IUnknown):
-    _iid_ = GUID('{0000010C-0000-0000-C000-000000000046}')
-    _idlflags_ = []
-    _methods_ = [
-        COMMETHOD([], HRESULT, 'GetClassID',
-                  ( ['out'], POINTER(GUID), 'pClassID' )),
-        ]
-
-class IServiceProvider(IUnknown):
-    _iid_ = GUID('{6D5140C1-7436-11CE-8034-00AA006009FA}')
-
-    # Overridden QueryService to make it nicer to use (passing it an
-    # interface and it returns a pointer to that interface)
-    def QueryService(self, serviceIID, interface):
-        p = POINTER(interface)()
-        self._QueryService(byref(serviceIID), byref(interface._iid_), byref(p))
-        return p
-
-    _methods_ = [
-        COMMETHOD([], HRESULT, 'QueryService',
-                  ( ['in'], POINTER(GUID), 'guidService' ),
-                  ( ['in'], POINTER(GUID), 'riid' ),
-                  ( ['in'], POINTER(c_void_p), 'ppvObject' ))
-        ]
-
-################################################################
-def CoGetObject(displayname, interface):
-    """Convert a displayname to a moniker, then bind and return the object
-    identified by the moniker."""
-    if interface is None:
-        interface = IUnknown
-    punk = POINTER(interface)()
-    # Do we need a way to specify the BIND_OPTS parameter?
-    _ole32.CoGetObject(unicode(displayname),
-                       None,
-                       byref(interface._iid_),
-                       byref(punk))
-    return punk
-
-def CoCreateInstance(clsid, interface=None, clsctx=None, punkouter=None):
-    """The basic windows api to create a COM class object and return a
-    pointer to an interface.
-    """
-    if clsctx is None:
-        clsctx = CLSCTX_SERVER
-    if interface is None:
-        interface = IUnknown
-    p = POINTER(interface)()
-    iid = interface._iid_
-    _ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p))
-    return p
-
-def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
-    if clsctx is None:
-        clsctx = CLSCTX_SERVER
-    if interface is None:
-        import comtypes.server
-        interface = comtypes.server.IClassFactory
-    p = POINTER(interface)()
-    _CoGetClassObject(clsid,
-                      clsctx,
-                      pServerInfo,
-                      interface._iid_,
-                      byref(p))
-    return p
-
-def GetActiveObject(clsid, interface=None):
-    """Retrieves a pointer to a running object"""
-    p = POINTER(IUnknown)()
-    oledll.oleaut32.GetActiveObject(byref(clsid), None, byref(p))
-    if interface is not None:
-        p = p.QueryInterface(interface)
-    return p
-
-class MULTI_QI(Structure):
-    _fields_ = [("pIID", POINTER(GUID)),
-                ("pItf", POINTER(c_void_p)),
-                ("hr", HRESULT)]
-
-class _COAUTHIDENTITY(Structure):
-    _fields_ = [
-        ('User', POINTER(c_ushort)),
-        ('UserLength', c_ulong),
-        ('Domain', POINTER(c_ushort)),
-        ('DomainLength', c_ulong),
-        ('Password', POINTER(c_ushort)),
-        ('PasswordLength', c_ulong),
-        ('Flags', c_ulong),
-    ]
-COAUTHIDENTITY = _COAUTHIDENTITY
-
-class _COAUTHINFO(Structure):
-    _fields_ = [
-        ('dwAuthnSvc', c_ulong),
-        ('dwAuthzSvc', c_ulong),
-        ('pwszServerPrincName', c_wchar_p),
-        ('dwAuthnLevel', c_ulong),
-        ('dwImpersonationLevel', c_ulong),
-        ('pAuthIdentityData', POINTER(_COAUTHIDENTITY)),
-        ('dwCapabilities', c_ulong),
-    ]
-COAUTHINFO = _COAUTHINFO
-
-class _COSERVERINFO(Structure):
-    _fields_ = [
-        ('dwReserved1', c_ulong),
-        ('pwszName', c_wchar_p),
-        ('pAuthInfo', POINTER(_COAUTHINFO)),
-        ('dwReserved2', c_ulong),
-    ]
-COSERVERINFO = _COSERVERINFO
-_CoGetClassObject = _ole32.CoGetClassObject
-_CoGetClassObject.argtypes = [POINTER(GUID), DWORD, POINTER(COSERVERINFO),
-                              POINTER(GUID), POINTER(c_void_p)]
-
-class tagBIND_OPTS(Structure):
-    _fields_ = [
-        ('cbStruct', c_ulong),
-        ('grfFlags', c_ulong),
-        ('grfMode', c_ulong),
-        ('dwTickCountDeadline', c_ulong)
-    ]
-# XXX Add __init__ which sets cbStruct?
-BIND_OPTS = tagBIND_OPTS
-
-class tagBIND_OPTS2(Structure):
-    _fields_ = [
-        ('cbStruct', c_ulong),
-        ('grfFlags', c_ulong),
-        ('grfMode', c_ulong),
-        ('dwTickCountDeadline', c_ulong),
-        ('dwTrackFlags', c_ulong),
-        ('dwClassContext', c_ulong),
-        ('locale', c_ulong),
-        ('pServerInfo', POINTER(_COSERVERINFO)),
-    ]
-# XXX Add __init__ which sets cbStruct?
-BINDOPTS2 = tagBIND_OPTS2
-
-def CoCreateInstanceEx(clsid, interface=None,
-                       clsctx=None,
-                       machine=None):
-    """The basic windows api to create a COM class object and return a
-    pointer to an interface, possibly on another machine.
-    """
-    if clsctx is None:
-        clsctx=CLSCTX_LOCAL_SERVER|CLSCTX_REMOTE_SERVER
-    if machine:
-        serverinfo = COSERVERINFO()
-        serverinfo.pwszName = machine
-        psi = byref(serverinfo)
-    else:
-        psi = None
-    if interface is None:
-        interface = IUnknown
-    multiqi = MULTI_QI()
-    multiqi.pIID = pointer(interface._iid_)
-    _ole32.CoCreateInstanceEx(byref(clsid),
-                             None,
-                             clsctx,
-                             psi,
-                             1,
-                             byref(multiqi))
-    return cast(multiqi.pItf, POINTER(interface))
-
-################################################################
-from comtypes._comobject import COMObject
-
-# What's a coclass?
-# a POINTER to a coclass is allowed as parameter in a function declaration:
-# http://msdn.microsoft.com/library/en-us/midl/midl/oleautomation.asp
-
-from comtypes._meta import _coclass_meta
-
-class CoClass(COMObject):
-    __metaclass__ = _coclass_meta
-################################################################

build/lib/comtypes/_comobject.py

-from ctypes import *
-from comtypes.hresult import *
-
-import os
-import logging
-logger = logging.getLogger(__name__)
-_debug = logger.debug
-_warning = logger.warning
-_error = logger.error
-
-################################################################
-# COM object implementation
-from _ctypes import CopyComPointer
-
-from comtypes import COMError, ReturnHRESULT, instancemethod
-from comtypes.errorinfo import ISupportErrorInfo, ReportException, ReportError
-from comtypes.typeinfo import IProvideClassInfo, IProvideClassInfo2
-from comtypes import IPersist
-
-# so we don't have to import comtypes.automation
-DISPATCH_METHOD = 1
-DISPATCH_PROPERTYGET = 2
-DISPATCH_PROPERTYPUT = 4
-DISPATCH_PROPERTYPUTREF = 8
-
-class E_NotImplemented(Exception):
-    """COM method is not implemented"""
-
-def HRESULT_FROM_WIN32(errcode):
-    "Convert a Windows error code into a HRESULT value."
-    if errcode is None:
-        return 0x80000000
-    if errcode & 0x80000000:
-        return errcode
-    return (errcode & 0xFFFF) | 0x80070000
-
-def winerror(exc):
-    """Return the windows error code from a WindowsError or COMError
-    instance."""
-    try:
-        code = exc[0]
-        if isinstance(code, (int, long)):
-            return code
-    except IndexError:
-        pass
-    # Sometimes, a WindowsError instance has no error code.  An access
-    # violation raised by ctypes has only text, for example.  In this
-    # cases we return a generic error code.
-    return E_FAIL
-
-def _do_implement(interface_name, method_name):
-    def _not_implemented(*args):
-        """Return E_NOTIMPL because the method is not implemented."""
-        _debug("unimplemented method %s_%s called", interface_name, method_name)
-        return E_NOTIMPL
-    return _not_implemented
-
-def catch_errors(obj, mth, paramflags, interface, mthname):
-    clsid = getattr(obj, "_reg_clsid_", None)
-    def call_with_this(*args, **kw):
-        try:
-            result = mth(*args, **kw)
-        except ReturnHRESULT, err:
-            (hresult, text) = err.args
-            return ReportError(text, iid=interface._iid_, clsid=clsid, hresult=hresult)
-        except (COMError, WindowsError), details:
-            _error("Exception in %s.%s implementation:", interface.__name__, mthname, exc_info=True)
-            return HRESULT_FROM_WIN32(winerror(details))
-        except E_NotImplemented:
-            _warning("Unimplemented method %s.%s called", interface.__name__, mthname)
-            return E_NOTIMPL
-        except:
-            _error("Exception in %s.%s implementation:", interface.__name__, mthname, exc_info=True)
-            return ReportException(E_FAIL, interface._iid_, clsid=clsid)
-        if result is None:
-            return S_OK
-        return result
-    if paramflags == None:
-        has_outargs = False
-    else:
-        has_outargs = bool([x[0] for x in paramflags
-                            if x[0] & 2])
-    call_with_this.has_outargs = has_outargs
-    return call_with_this
-
-################################################################
-
-def hack(inst, mth, paramflags, interface, mthname):
-    if paramflags is None:
-        return catch_errors(inst, mth, paramflags, interface, mthname)
-    code = mth.func_code
-    if code.co_varnames[1:2] == ("this",):
-        return catch_errors(inst, mth, paramflags, interface, mthname)
-    dirflags = [f[0] for f in paramflags]
-    # An argument is an input arg either if flags are NOT set in the
-    # idl file, or if the flags contain 'in'. In other words, the
-    # direction flag is either exactly '0' or has the '1' bit set:
-    # Output arguments have flag '2'
-
-    args_out_idx=[]
-    args_in_idx=[]
-    for i,a in enumerate(dirflags):
-        if a&2:
-            args_out_idx.append(i)
-        if a&1 or a==0:
-            args_in_idx.append(i)
-    args_out = len(args_out_idx)
-
-    ## XXX Remove this:
-##    if args_in != code.co_argcount - 1:
-##        return catch_errors(inst, mth, interface, mthname)
-
-    clsid = getattr(inst, "_reg_clsid_", None)
-    def call_without_this(this, *args):
-        # Method implementations could check for and return E_POINTER
-        # themselves.  Or an error will be raised when
-        # 'outargs[i][0] = value' is executed.
-##        for a in outargs:
-##            if not a:
-##                return E_POINTER
-
-        #make argument list for handler by index array built above
-        inargs=[]
-        for a in args_in_idx:
-            inargs.append(args[a])
-        try:
-            result = mth(*inargs)
-            if args_out == 1:
-                args[args_out_idx[0]][0] = result
-            elif args_out != 0:
-                if len(result) != args_out:
-                    raise ValueError("Method should have returned a %s-tuple" % args_out)
-                for i, value in enumerate(result):
-                    args[args_out_idx[i]][0] = value
-        except ReturnHRESULT, err:
-            (hresult, text) = err.args
-            return ReportError(text, iid=interface._iid_, clsid=clsid, hresult=hresult)
-        except COMError, err:
-            (hr, text, details) = err.args
-            _error("Exception in %s.%s implementation:", interface.__name__, mthname, exc_info=True)
-            try:
-                descr, source, helpfile, helpcontext, progid = details
-            except (ValueError, TypeError):
-                msg = str(details)
-            else:
-                msg = "%s: %s" % (source, descr)
-            hr = HRESULT_FROM_WIN32(hr)
-            return ReportError(msg, iid=interface._iid_, clsid=clsid, hresult=hr)
-        except WindowsError, details:
-            _error("Exception in %s.%s implementation:", interface.__name__, mthname, exc_info=True)
-            hr = HRESULT_FROM_WIN32(winerror(details))
-            return ReportException(hr, interface._iid_, clsid=clsid)
-        except E_NotImplemented:
-            _warning("Unimplemented method %s.%s called", interface.__name__, mthname)
-            return E_NOTIMPL
-        except:
-            _error("Exception in %s.%s implementation:", interface.__name__, mthname, exc_info=True)
-            return ReportException(E_FAIL, interface._iid_, clsid=clsid)
-        return S_OK
-    if args_out:
-        call_without_this.has_outargs = True
-    return call_without_this
-
-class _MethodFinder(object):
-    def __init__(self, inst):
-        self.inst = inst
-        # map lower case names to names with correct spelling.
-        self.names = dict([(n.lower(), n) for n in dir(inst)])
-
-    def get_impl(self, interface, mthname, paramflags, idlflags):
-        mth = self.find_impl(interface, mthname, paramflags, idlflags)
-        if mth is None:
-            return _do_implement(interface.__name__, mthname)
-        return hack(self.inst, mth, paramflags, interface, mthname)
-
-    def find_method(self, fq_name, mthname):
-        # Try to find a method, first with the fully qualified name
-        # ('IUnknown_QueryInterface'), if that fails try the simple
-        # name ('QueryInterface')
-        try:
-            return getattr(self.inst, fq_name)
-        except AttributeError:
-            pass
-        return getattr(self.inst, mthname)
-
-    def find_impl(self, interface, mthname, paramflags, idlflags):
-        fq_name = "%s_%s" % (interface.__name__, mthname)
-        if interface._case_insensitive_:
-            # simple name, like 'QueryInterface'
-            mthname = self.names.get(mthname.lower(), mthname)
-            # qualified name, like 'IUnknown_QueryInterface'
-            fq_name = self.names.get(fq_name.lower(), fq_name)
-
-        try:
-            return self.find_method(fq_name, mthname)
-        except AttributeError:
-            pass
-        propname = mthname[5:] # strip the '_get_' or '_set' prefix
-        if interface._case_insensitive_:
-            propname = self.names.get(propname.lower(), propname)
-        # propput and propget is done with 'normal' attribute access,
-        # but only for COM properties that do not take additional
-        # arguments:
-
-        if "propget" in idlflags and len(paramflags) == 1:
-            return self.getter(propname)
-        if "propput" in idlflags and len(paramflags) == 1:
-            return self.setter(propname)
-        _debug("%r: %s.%s not implemented", self.inst, interface.__name__, mthname)
-        return None
-
-    def setter(self, propname):
-        #
-        def set(self, value):
-            try:
-                # XXX this may not be correct is the object implements
-                # _get_PropName but not _set_PropName
-                setattr(self, propname, value)
-            except AttributeError:
-                raise E_NotImplemented()
-        return instancemethod(set, self.inst, type(self.inst))
-
-    def getter(self, propname):
-        #
-        def get(self):
-            try:
-                return getattr(self, propname)
-            except AttributeError:
-                raise E_NotImplemented()
-        return instancemethod(get, self.inst, type(self.inst))
-
-def _create_vtbl_type(fields, itf):
-    try:
-        return _vtbl_types[fields]
-    except KeyError:
-        class Vtbl(Structure):
-            _fields_ = fields
-        Vtbl.__name__ = "Vtbl_%s" % itf.__name__
-        _vtbl_types[fields] = Vtbl
-        return Vtbl
-
-# Ugh. Another type cache to avoid leaking types.
-_vtbl_types = {}
-
-################################################################
-
-try:
-    if os.name == "ce":
-        _InterlockedIncrement = windll.coredll.InterlockedIncrement
-        _InterlockedDecrement = windll.coredll.InterlockedDecrement
-    else:
-        _InterlockedIncrement = windll.kernel32.InterlockedIncrement
-        _InterlockedDecrement = windll.kernel32.InterlockedDecrement
-except AttributeError:
-    import threading
-    _lock = threading.Lock()
-    _acquire = _lock.acquire
-    _release = _lock.release
-    # win 64 doesn't have these functions
-    def _InterlockedIncrement(ob):
-        _acquire()
-        refcnt = ob.value + 1
-        ob.value = refcnt
-        _release()
-        return refcnt
-    def _InterlockedDecrement(ob):
-        _acquire()
-        refcnt = ob.value - 1
-        ob.value = refcnt
-        _release()
-        return refcnt
-else:
-    _InterlockedIncrement.argtypes = [POINTER(c_long)]
-    _InterlockedDecrement.argtypes = [POINTER(c_long)]
-    _InterlockedIncrement.restype = c_long
-    _InterlockedDecrement.restype = c_long
-
-class LocalServer(object):
-
-    _queue = None
-    def run(self, classobjects):
-        # Use windll instead of oledll so that we don't get an
-        # exception on a FAILED hresult:
-        result = windll.ole32.CoInitialize(None)
-        if RPC_E_CHANGED_MODE == result:
-            # we're running in MTA: no message pump needed
-            _debug("Server running in MTA")
-            self.run_mta()
-        else:
-            # we're running in STA: need a message pump
-            _debug("Server running in STA")
-            if result >= 0:
-                # we need a matching CoUninitialize() call for a successful CoInitialize().
-                windll.ole32.CoUninitialize()
-            self.run_sta()
-
-        for obj in classobjects:
-            obj._revoke_class()
-
-    def run_sta(self):
-        from comtypes import messageloop
-        messageloop.run()
-
-    def run_mta(self):
-        import Queue
-        self._queue = Queue.Queue()
-        self._queue.get()
-
-    def Lock(self):
-        oledll.ole32.CoAddRefServerProcess()
-
-    def Unlock(self):
-        rc = oledll.ole32.CoReleaseServerProcess()
-        if rc == 0:
-            if self._queue:
-                self._queue.put(42)
-            else:
-                windll.user32.PostQuitMessage(0)
-
-class InprocServer(object):
-
-    def __init__(self):
-        self.locks = c_long(0)
-
-    def Lock(self):
-        _InterlockedIncrement(self.locks)
-
-    def Unlock(self):
-        _InterlockedDecrement(self.locks)
-
-    def DllCanUnloadNow(self):
-        if self.locks.value:
-            return S_FALSE
-        if COMObject._instances_:
-            return S_FALSE
-        return S_OK
-
-class COMObject(object):
-    _instances_ = {}
-
-    def __new__(cls, *args, **kw):
-        self = super(COMObject, cls).__new__(cls)
-        if isinstance(self, c_void_p):
-            # We build the VTables only for direct instances of
-            # CoClass, not for POINTERs to CoClass.
-            return self
-        if hasattr(self, "_com_interfaces_"):
-            self.__prepare_comobject()
-        return self
-
-    def __prepare_comobject(self):
-        # When a CoClass instance is created, COM pointers to all
-        # interfaces are created.  Also, the CoClass must be kept alive as
-        # until the COM reference count drops to zero, even if no Python
-        # code keeps a reference to the object.
-        #
-        # The _com_pointers_ instance variable maps string interface iids
-        # to C compatible COM pointers.
-        self._com_pointers_ = {}
-        # COM refcount starts at zero.
-        self._refcnt = c_long(0)
-
-        # Some interfaces have a default implementation in COMObject:
-        # - ISupportErrorInfo
-        # - IPersist (if the subclass has a _reg_clsid_ attribute)
-        # - IProvideClassInfo (if the subclass has a _reg_clsid_ attribute)
-        # - IProvideClassInfo2 (if the subclass has a _outgoing_interfaces_ attribute)
-        #
-        # Add these if they are not listed in _com_interfaces_.
-        interfaces = tuple(self._com_interfaces_)
-        if ISupportErrorInfo not in interfaces:
-            interfaces += (ISupportErrorInfo,)
-        if hasattr(self, "_reg_typelib_"):
-            from comtypes.typeinfo import LoadRegTypeLib
-            self._COMObject__typelib = LoadRegTypeLib(*self._reg_typelib_)
-            if hasattr(self, "_reg_clsid_"):
-                if IProvideClassInfo not in interfaces:
-                    interfaces += (IProvideClassInfo,)
-                if hasattr(self, "_outgoing_interfaces_") and \
-                   IProvideClassInfo2 not in interfaces:
-                    interfaces += (IProvideClassInfo2,)
-        if hasattr(self, "_reg_clsid_"):
-            if IPersist not in interfaces:
-                interfaces += (IPersist,)
-        for itf in interfaces[::-1]:
-            self.__make_interface_pointer(itf)
-
-    def __make_interface_pointer(self, itf):
-        methods = [] # method implementations
-        fields = [] # (name, prototype) for virtual function table
-        iids = [] # interface identifiers.
-        # iterate over interface inheritance in reverse order to build the
-        # virtual function table, and leave out the 'object' base class.
-        finder = self._get_method_finder_(itf)
-        for interface in itf.__mro__[-2::-1]:
-            iids.append(interface._iid_)
-            for m in interface._methods_:
-                restype, mthname, argtypes, paramflags, idlflags, helptext = m
-                proto = WINFUNCTYPE(restype, c_void_p, *argtypes)
-                fields.append((mthname, proto))
-                mth = finder.get_impl(interface, mthname, paramflags, idlflags)
-                methods.append(proto(mth))
-        Vtbl = _create_vtbl_type(tuple(fields), itf)
-        vtbl = Vtbl(*methods)
-        for iid in iids:
-            self._com_pointers_[iid] = pointer(pointer(vtbl))
-        if hasattr(itf, "_disp_methods_"):
-            self._dispimpl_ = {}
-            for m in itf._disp_methods_:
-                what, mthname, idlflags, restype, argspec = m
-                #################
-                # What we have:
-                #
-                # restypes is a ctypes type or None
-                # argspec is seq. of (['in'], paramtype, paramname) tuples (or lists?)
-                #################
-                # What we need:
-                #
-                # idlflags must contain 'propget', 'propset' and so on:
-                # Must be constructed by converting disptype
-                #
-                # paramflags must be a sequence
-                # of (F_IN|F_OUT|F_RETVAL, paramname[, default-value]) tuples
-                #
-                # comtypes has this function which helps:
-                #    def _encode_idl(names):
-                #        # convert to F_xxx and sum up "in", "out",
-                #        # "retval" values found in _PARAMFLAGS, ignoring
-                #        # other stuff.
-                #        return sum([_PARAMFLAGS.get(n, 0) for n in names])
-                #################
-
-                if what == "DISPMETHOD":
-                    if 'propget' in idlflags:
-                        invkind = 2 # DISPATCH_PROPERTYGET
-                        mthname = "_get_" + mthname
-                    elif 'propput' in idlflags:
-                        invkind = 4 # DISPATCH_PROPERTYPUT
-                        mthname = "_set_" + mthname
-                    elif 'propputref' in idlflags:
-                        invkind = 8 # DISPATCH_PROPERTYPUTREF
-                        mthname = "_setref_" + mthname
-                    else:
-                        invkind = 1 # DISPATCH_METHOD
-                        if restype:
-                            argspec = argspec + ((['out'], restype, ""),)
-                    self.__make_dispentry(finder, interface, mthname,
-                                          idlflags, argspec, invkind)
-                elif what == "DISPPROPERTY":
-                    self.__make_dispentry(finder, interface,
-                                          "_get_" + mthname,
-                                          idlflags, argspec,
-                                          2 # DISPATCH_PROPERTYGET
-                                          )
-                    if not 'readonly' in idlflags:
-                        self.__make_dispentry(finder, interface,
-                                              "_set_" + mthname,
-                                              idlflags, argspec,
-                                              4) # DISPATCH_PROPERTYPUT
-                        # Add DISPATCH_PROPERTYPUTREF also?
-
-
-    def __make_dispentry(self,
-                         finder, interface, mthname,
-                         idlflags, argspec, invkind):
-        # We build a _dispmap_ entry now that maps invkind and
-        # dispid to implementations that the finder finds;
-        # IDispatch_Invoke will later call it.
-        from comtypes import _encode_idl
-        paramflags = [((_encode_idl(x[0]), x[1]) + tuple(x[3:])) for x in argspec]
-
-        dispid = idlflags[0] # XXX can the dispid be at a different index?  Check codegenerator.
-        impl = finder.get_impl(interface, mthname, paramflags, idlflags)
-        self._dispimpl_[(dispid, invkind)] = impl
-        # invkind is really a set of flags; we allow both
-        # DISPATCH_METHOD and DISPATCH_PROPERTYGET (win32com uses
-        # this, maybe other languages too?)
-        if invkind in (1, 2):
-            self._dispimpl_[(dispid, 3)] = impl
-
-    def _get_method_finder_(self, itf):
-        # This method can be overridden to customize how methods are
-        # found.
-        return _MethodFinder(self)
-
-    ################################################################
-    # LocalServer / InprocServer stuff
-    __server__ = None
-##2.3    @staticmethod
-    def __run_inprocserver__():
-        if COMObject.__server__ is None:
-            COMObject.__server__ = InprocServer()
-        elif isinstance(COMObject.__server__, InprocServer):
-            pass
-        else:
-            raise RuntimeError("Wrong server type")
-    __run_inprocserver__ = staticmethod(__run_inprocserver__)
-
-##2.3    @staticmethod
-    def __run_localserver__(classobjects):
-        assert COMObject.__server__ is None
-        # XXX Decide whether we are in STA or MTA
-        server = COMObject.__server__ = LocalServer()
-        server.run(classobjects)
-        COMObject.__server__ = None
-    __run_localserver__ = staticmethod(__run_localserver__)
-
-##2.3    @staticmethod
-    def __keep__(obj):
-        COMObject._instances_[obj] = None
-        _debug("%d active COM objects: Added   %r", len(COMObject._instances_), obj)
-        if COMObject.__server__:
-            COMObject.__server__.Lock()
-    __keep__ = staticmethod(__keep__)
-
-##2.3    @staticmethod
-    def __unkeep__(obj):
-        try:
-            del COMObject._instances_[obj]
-        except AttributeError:
-            _debug("? active COM objects: Removed %r", obj)
-        else:
-            _debug("%d active COM objects: Removed %r", len(COMObject._instances_), obj)
-        _debug("Remaining: %s", COMObject._instances_.keys())
-        if COMObject.__server__:
-            COMObject.__server__.Unlock()
-    __unkeep__ = staticmethod(__unkeep__)
-    #
-    ################################################################
-
-    #########################################################
-    # IUnknown methods implementations
-    def IUnknown_AddRef(self, this,
-                        __InterlockedIncrement=_InterlockedIncrement,
-                        _debug=_debug):
-        result = __InterlockedIncrement(self._refcnt)
-        if result == 1:
-            self.__keep__(self)
-        _debug("%r.AddRef() -> %s", self, result)
-        return result
-
-    def _final_release_(self):
-        """This method may be overridden in subclasses
-        to free allocated resources or so."""
-        pass
-
-    def IUnknown_Release(self, this,
-                         __InterlockedDecrement=_InterlockedDecrement,
-                        _debug=_debug):
-        # If this is called at COM shutdown, _InterlockedDecrement()
-        # must still be available, although module level variables may
-        # have been deleted already - so we supply it as default
-        # argument.
-        result = __InterlockedDecrement(self._refcnt)
-        _debug("%r.Release() -> %s", self, result)
-        if result == 0:
-            self._final_release_()
-            self.__unkeep__(self)
-            # Hm, why isn't this cleaned up by the cycle gc?
-            self._com_pointers_ = {}
-        return result
-
-    def IUnknown_QueryInterface(self, this, riid, ppvObj,
-                        _debug=_debug):
-        # XXX This is probably too slow.
-        # riid[0].hashcode() alone takes 33 us!
-        iid = riid[0]
-        ptr = self._com_pointers_.get(iid, None)
-        if ptr is not None:
-            # CopyComPointer(src, dst) calls AddRef!
-            _debug("%r.QueryInterface(%s) -> S_OK", self, iid)
-            return CopyComPointer(ptr, ppvObj)
-        _debug("%r.QueryInterface(%s) -> E_NOINTERFACE", self, iid)
-        return E_NOINTERFACE
-
-    def QueryInterface(self, interface):
-        "Query the object for an interface pointer"
-        # This method is NOT the implementation of
-        # IUnknown::QueryInterface, instead it is supposed to be
-        # called on an COMObject by user code.  It allows to get COM
-        # interface pointers from COMObject instances.
-        ptr = self._com_pointers_.get(interface._iid_, None)
-        if ptr is None:
-            raise COMError(E_NOINTERFACE, FormatError(E_NOINTERFACE),
-                           (None, None, 0, None, None))
-        # CopyComPointer(src, dst) calls AddRef!
-        result = POINTER(interface)()
-        CopyComPointer(ptr, byref(result))
-        return result
-
-    ################################################################
-    # ISupportErrorInfo::InterfaceSupportsErrorInfo implementation
-    def ISupportErrorInfo_InterfaceSupportsErrorInfo(self, this, riid):
-        if riid[0] in self._com_pointers_:
-            return S_OK
-        return S_FALSE
-
-    ################################################################
-    # IProvideClassInfo::GetClassInfo implementation
-    def IProvideClassInfo_GetClassInfo(self):
-        try:
-            self.__typelib
-        except AttributeError:
-            raise WindowsError(E_NOTIMPL)
-        return self.__typelib.GetTypeInfoOfGuid(self._reg_clsid_)
-
-    ################################################################
-    # IProvideClassInfo2::GetGUID implementation
-
-    def IProvideClassInfo2_GetGUID(self, dwGuidKind):
-        # GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1
-        if dwGuidKind != 1:
-            raise WindowsError(E_INVALIDARG)
-        return self._outgoing_interfaces_[0]._iid_
-
-    ################################################################
-    # IDispatch methods
-##2.3    @property
-    def __typeinfo(self):
-        # XXX Looks like this better be a static property, set by the
-        # code that sets __typelib also...
-        iid = self._com_interfaces_[0]._iid_
-        return self.__typelib.GetTypeInfoOfGuid(iid)
-    __typeinfo = property(__typeinfo)
-
-    def IDispatch_GetTypeInfoCount(self):
-        try:
-            self.__typelib
-        except AttributeError:
-            return 0
-        else:
-            return 1
-
-    def IDispatch_GetTypeInfo(self, this, itinfo, lcid, ptinfo):
-        if itinfo != 0:
-            return DISP_E_BADINDEX
-        try:
-            ptinfo[0] = self.__typeinfo
-            return S_OK
-        except AttributeError:
-            return E_NOTIMPL
-
-    def IDispatch_GetIDsOfNames(self, this, riid, rgszNames, cNames, lcid, rgDispId):
-        # This call uses windll instead of oledll so that a failed
-        # call to DispGetIDsOfNames will return a HRESULT instead of
-        # raising an error.
-        try:
-            tinfo = self.__typeinfo
-        except AttributeError:
-            return E_NOTIMPL
-        return windll.oleaut32.DispGetIDsOfNames(tinfo,
-                                                 rgszNames, cNames, rgDispId)
-
-    def IDispatch_Invoke(self, this, dispIdMember, riid, lcid, wFlags,
-                         pDispParams, pVarResult, pExcep