Commits

Jason Scheirer committed 334efbf

0.6.0

Comments (0)

Files changed (33)

+2008-12-19  Thomas Heller  <theller@python.net>
+
+	* Bumped version number to 0.6.0.
+
+	* comtypes.client.lazybind.Dipatch:
+	If __getitem__ fails the get the indexed default value, try
+	NewENUM.  Implement __eq__ for Python 3 compatibility.
+
+	* Fix a problem with SAFEARRAYs where the contained data was
+	released too early.
+
+	* Fix property get handling for FUNC_PUREVIRTUAL functions in
+	lazybind.py
+
+2008-12-18  Thomas Heller  <theller@python.net>
+
+	* Fix memoryleak in IEnumVARIANT.
+
 2008-12-12  Thomas Heller  <theller@python.net>
+	
+	* Merged changes from the dyndispatch branch:
 
+	    * Add a comtypes.client.Constants class that provides a way to
+	    access constants in the type library for an object, even when
+	    no wrapper has been created for the type library.  The
+	    contants can be accessed as attributes like this, assuming
+	    'obj' is a COM object that exposes type information at runtime
+	    via the dispatch interface:
+		Constants(obj).MyConstant
+
+	    * New comtypes.client.lazybind module.
+
+	    * Implement NamedProperty.__call__().  Extend
+	    NamedProperty.__getitem__() and NamedProperty.__setitem__() so
+	    that they accept a tuple, which make lazy bound objects more
+	    compatible with early bound objects.
+
+	    * Finished (for now) the comtypes.client.lazybind module.
+	    IEnumVARIANT instances get a _dynamic attribute which defaults
+	    to False.  The values returned from next() calls are retrived
+	    by calling ._set_value(self._dynamic) on the VARIANT result.
+
+	    * comtypes.client.dynamic:
+
+	    * Started changes based on ideas from Michael Curran: better
+	    dynamic dispatch support, and a way to disable the
+	    time-consuming wrapper code generation on demand.
+	
+	    * comtypes\client: Add a new 'dynamic=False' parameter to the
+	    CreateObject function.  This parameter allows to create a
+	    dynamic dispatch object, bypassing the code generation.
+
+	    * comtypes\automation.py: Add a new parameter to the
+	    VARIANT._get_value(dynamic=False) method.  This allows to
+	    retrieve the current value as a _Dispatch() instance if the
+	    typecode is VT_DISPATCH, bypassing the code generation on the
+	    result.  The IDispatch.Invoke implementation now uses this to
+	    ensure that dynamic objects are returned when possible.
+
+	    * comtypes\client\dynamic.py: Implement _Dispatch.__eq__ so
+	    that we can compare instances for equality.
+
+
+2008-12-12  Thomas Heller  <theller@python.net>
+	
 	* Bumped version number to 0.5.3.
 
 	* Added VARIANT support for VT_I8 and VT_UI8 typecodes.

comtypes/__init__.py

 # 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.5.3"
+__version__ = "0.6.0"
 
 import logging
 class NullHandler(logging.Handler):

comtypes/automation.py

         elif isinstance(getattr(value, "_comobj", None), POINTER(IDispatch)):
             CopyComPointer(value._comobj, byref(self._))
             self.vt = VT_DISPATCH
+        elif isinstance(value, VARIANT):
+            windll.oleaut32.VariantCopy(byref(self), byref(value))
         else:
             raise TypeError("Cannot put %r in VARIANT" % value)
         # buffer ->  SAFEARRAY of VT_UI1 ?
 
     # c:/sf/pywin32/com/win32com/src/oleargs.cpp 197
-    def _get_value(self):
+    def _get_value(self, dynamic=False):
         vt = self.vt
         if vt in (VT_EMPTY, VT_NULL):
             return None
             ptr = cast(val, POINTER(IDispatch))
             # cast doesn't call AddRef (it should, imo!)
             ptr.AddRef()
-            return ptr.__ctypes_from_outparam__()
+            if not dynamic:
+                return ptr.__ctypes_from_outparam__()
+            else:
+                from comtypes.client.dynamic import Dispatch
+                return Dispatch(ptr)
         # see also c:/sf/pywin32/com/win32com/src/oleargs.cpp
         elif self.vt & VT_BYREF:
             return self
 class IEnumVARIANT(IUnknown):
     _iid_ = GUID('{00020404-0000-0000-C000-000000000046}')
     _idlflags_ = ['hidden']
+    _dynamic = False
     def __iter__(self):
         return self
 
         raise IndexError
 
     def Next(self, celt):
+        fetched = c_ulong()
         if celt == 1:
-            return self._Next(1)
-        fetched = c_ulong()
+            v = VARIANT()
+            self.__com_Next(celt, v, fetched)
+            return v._get_value(dynamic=self._dynamic), fetched.value
         array = (VARIANT * celt)()
         self.__com_Next(celt, array, fetched)
-        return [v.__ctypes_from_outparam__() for v in array[:fetched.value]]
+        result = [v._get_value(dynamic=self._dynamic) for v in array[:fetched.value]]
+        for v in array:
+            v.value = None
+        return result
 
 IEnumVARIANT._methods_ = [
     COMMETHOD([], HRESULT, 'Next',
         self.__com_GetIDsOfNames(riid_null, arr, len(names), lcid, ids)
         return ids[:]
 
+    def _invoke(self, memid, invkind, lcid, *args):
+        var = VARIANT()
+        argerr = c_uint()
+        dp = DISPPARAMS()
+
+        if args:
+            array = (VARIANT * len(args))()
+
+            for i, a in enumerate(args[::-1]):
+                array[i].value = a
+
+            dp.cArgs = len(args)
+            if invkind in (DISPATCH_PROPERTYPUT, DISPATCH_PROPERTYPUTREF):
+                dp.cNamedArgs = 1
+                dp.rgdispidNamedArgs = pointer(DISPID(DISPID_PROPERTYPUT))
+            dp.rgvarg = array
+
+        self.__com_Invoke(memid, riid_null, lcid, invkind,
+                          dp, var, None, argerr)
+        return var._get_value(dynamic=True)
+
     def Invoke(self, dispid, *args, **kw):
         """Invoke a method or property."""
 
                                ("TypeError: Parameter %s" % (argerr.value + 1),
                                 args))
             raise
-        return result.value
+        return result._get_value(dynamic=True)
 
     # XXX Would separate methods for _METHOD, _PROPERTYGET and _PROPERTYPUT be better?
 

comtypes/client/__init__.py

 
 ################################################################
 #
+# Typelib constants
+#
+class Constants(object):
+    """This class loads the type library from the supplied object,
+    then exposes constants in the type library as attributes."""
+    def __init__(self, obj):
+        obj = obj.QueryInterface(comtypes.automation.IDispatch)
+        tlib, index = obj.GetTypeInfo(0).GetContainingTypeLib()
+        self.tcomp = tlib.GetTypeComp()
+
+    def __getattr__(self, name):
+        try:
+            kind, desc = self.tcomp.Bind(name)
+        except (WindowsError, comtypes.COMError):
+            raise AttributeError(name)
+        if kind != "variable":
+            raise AttributeError(name)
+        return desc._.lpvarValue[0].value
+
+    def _bind_type(self, name):
+        return self.tcomp.BindType(name)
+
+################################################################
+#
 # Object creation
 #
 def GetActiveObject(progid, interface=None):
 def CreateObject(progid,                  # which object to create
                  clsctx=None,             # how to create the object
                  machine=None,            # where to create the object
-                 interface=None):         # the interface we want
+                 interface=None,          # the interface we want
+                 dynamic=False):          # use dynamic dispatch
     """Create a COM object from 'progid', and try to QueryInterface()
     it to the most useful interface, generating typelib support on
     demand.  A pointer to this interface is returned.
     """
     clsid = comtypes.GUID.from_progid(progid)
     logger.debug("%s -> %s", progid, clsid)
-    if interface is None:
+    if dynamic:
+        if interface:
+            raise ValueError("interface and dynamic are mutually exclusive")
+        interface = comtypes.automation.IDispatch
+    elif interface is None:
         interface = getattr(progid, "_com_interfaces_", [None])[0]
     if machine is None:
         logger.debug("CoCreateInstance(%s, clsctx=%s, interface=%s)",
         logger.debug("CoCreateInstanceEx(%s, clsctx=%s, interface=%s, machine=%s)",
                      clsid, clsctx, interface, machine)
         obj = comtypes.CoCreateInstanceEx(clsid, clsctx=clsctx, interface=interface, machine=machine)
+    if dynamic:
+        return comtypes.client.dynamic.Dispatch(obj)
     return _manage(obj, clsid, interface=interface)
 
 def CoGetObject(displayname, interface=None):

comtypes/client/dynamic.py

 import comtypes.automation
 import comtypes.typeinfo
 import comtypes.client
+import comtypes.client.lazybind
 
 from comtypes import COMError, IUnknown, _is_object
 import comtypes.hresult as hres
     if isinstance(obj, _Dispatch):
         return obj
     if isinstance(obj, ctypes.POINTER(comtypes.automation.IDispatch)):
-        return _Dispatch(obj)
+        try:
+            tinfo = obj.GetTypeInfo(0)
+        except (comtypes.COMError, WindowsError):
+            return _Dispatch(obj)
+        return comtypes.client.lazybind.Dispatch(obj, tinfo)
     return obj
 
 class MethodCaller:
         e = self._comobj.Invoke(-4) # DISPID_NEWENUM
         return e.QueryInterface(comtypes.automation.IEnumVARIANT)
 
+    def __cmp__(self, other): 	 
+        if not isinstance(other, _Dispatch): 	 
+            return 1 	 
+        return cmp(self._comobj, other._comobj)
+
     def __getitem__(self, index):
         enum = self.__enum()
         if index > 0:

comtypes/client/lazybind.py

+from ctypes import c_uint, pointer
+import comtypes
+import comtypes.automation
+
+from comtypes.automation import VARIANT, DISPPARAMS
+from comtypes.automation import IEnumVARIANT
+from comtypes.automation import DISPATCH_METHOD
+from comtypes.automation import DISPATCH_PROPERTYGET
+from comtypes.automation import DISPATCH_PROPERTYPUT
+from comtypes.automation import DISPATCH_PROPERTYPUTREF
+
+from comtypes.automation import DISPID
+from comtypes.automation import DISPID_PROPERTYPUT
+from comtypes.automation import DISPID_VALUE
+from comtypes.automation import DISPID_NEWENUM
+
+from comtypes.typeinfo import FUNC_PUREVIRTUAL, FUNC_DISPATCH
+
+class FuncDesc(object):
+    """Stores important FUNCDESC properties by copying them from a
+    real FUNCDESC instance.
+    """
+    def __init__(self, **kw):
+        self.__dict__.update(kw)
+
+# What is missing?
+#
+# Should NamedProperty support __call__()?
+
+class NamedProperty(object):
+    def __init__(self, disp, get, put, putref):
+        self.get = get
+        self.put = put
+        self.putref = putref
+        self.disp = disp
+
+    def __getitem__(self, arg):
+        if isinstance(arg, tuple):
+            return self.disp._comobj._invoke(self.get.memid,
+                                             self.get.invkind,
+                                             0,
+                                             *arg)
+        return self.disp._comobj._invoke(self.get.memid,
+                                         self.get.invkind,
+                                         0,
+                                         *[arg])
+
+    def __call__(self, *args):
+            return self.disp._comobj._invoke(self.get.memid,
+                                             self.get.invkind,
+                                             0,
+                                             *args)
+
+    def __setitem__(self, name, value):
+        # See discussion in Dispatch.__setattr__ below.
+        if not self.put and not self.putref:
+            raise AttributeError(name) # XXX IndexError?
+        if comtypes._is_object(value):
+            descr = self.putref or self.put
+        else:
+            descr = self.put or self.putref
+        if isinstance(name, tuple):
+            self.disp._comobj._invoke(descr.memid,
+                                      descr.invkind,
+                                      0,
+                                      *(name + (value,)))
+        else:
+            self.disp._comobj._invoke(descr.memid,
+                                      descr.invkind,
+                                      0,
+                                      name,
+                                      value)
+
+# The following 'Dispatch' class, returned from
+#    CreateObject(progid, dynamic=True)
+# differ in behaviour from objects created with
+#    CreateObject(progid, dynamic=False)
+# (let us call the latter 'Custom' objects for this discussion):
+#
+#
+# 1. Dispatch objects support __call__(), custom objects do not
+#
+# 2. Custom objects method support named arguments, Dispatch
+#    objects do not (could be added, would probably be expensive)
+
+class Dispatch(object):
+    """Dynamic dispatch for an object the exposes type information.
+    Binding at runtime is done via ITypeComp::Bind calls.
+    """
+    def __init__(self, comobj, tinfo):
+        self.__dict__["_comobj"] = comobj
+        self.__dict__["_tinfo"] = tinfo
+        self.__dict__["_tcomp"] = tinfo.GetTypeComp()
+        self.__dict__["_tdesc"] = {}
+##        self.__dict__["_iid"] = tinfo.GetTypeAttr().guid
+
+    def __bind(self, name, invkind):
+        """Bind (name, invkind) and return a FuncDesc instance or
+        None.  Results (even unsuccessful ones) are cached."""
+        # We could cache the info in the class instead of the
+        # instance, but we would need an additional key for that:
+        # self._iid
+        try:
+            return self._tdesc[(name, invkind)]
+        except KeyError:
+            try:
+                descr = self._tcomp.Bind(name, invkind)[1]
+            except comtypes.COMError:
+                info = None
+            else:
+                # Using a separate instance to store interesting
+                # attributes of descr avoids that the typecomp instance is
+                # kept alive...
+                info = FuncDesc(memid=descr.memid,
+                                invkind=descr.invkind,
+                                cParams=descr.cParams,
+                                funckind=descr.funckind)
+            self._tdesc[(name, invkind)] = info
+            return info
+
+    def QueryInterface(self, *args):
+        "QueryInterface is forwarded to the real com object."
+        return self._comobj.QueryInterface(*args)
+
+    def __cmp__(self, other):
+        if not isinstance(other, Dispatch):
+            return 1
+        return cmp(self._comobj, other._comobj)
+
+    def __eq__(self, other):
+        return isinstance(other, Dispatch) and \
+               self._comobj == other._comobj
+
+    def __getattr__(self, name):
+        """Get a COM attribute."""
+        if name.startswith("__") and name.endswith("__"):
+            raise AttributeError(name)
+        # check for propget or method
+        descr = self.__bind(name, DISPATCH_METHOD | DISPATCH_PROPERTYGET)
+        if descr is None:
+            raise AttributeError(name)
+        if descr.invkind == DISPATCH_PROPERTYGET:
+            # DISPATCH_PROPERTYGET
+            if descr.funckind == FUNC_DISPATCH:
+                if descr.cParams == 0:
+                    return self._comobj._invoke(descr.memid, descr.invkind, 0)
+            elif descr.funckind == FUNC_PUREVIRTUAL:
+                # FUNC_PUREVIRTUAL descriptions contain the property
+                # itself as a parameter.
+                if descr.cParams == 1:
+                    return self._comobj._invoke(descr.memid, descr.invkind, 0)
+            else:
+                raise RuntimeError("funckind %d not yet implemented" % descr.funckind)
+            put = self.__bind(name, DISPATCH_PROPERTYPUT)
+            putref = self.__bind(name, DISPATCH_PROPERTYPUTREF)
+            return NamedProperty(self, descr, put, putref)
+        else:
+            # DISPATCH_METHOD
+            def caller(*args):
+                return self._comobj._invoke(descr.memid, descr.invkind, 0, *args)
+            caller.__name__ = name
+            return caller
+
+    def __setattr__(self, name, value):
+        # Hm, this can be a propput, a propputref, or 'both' property.
+        # (Or nothing at all.)
+        #
+        # Whether propput or propputref is called will depend on what
+        # is available, and on the type of 'value' as determined by
+        # comtypes._is_object(value).
+        #
+        # I think that the following table MAY be correct; although I
+        # have no idea whether the cases marked (?) are really valid.
+        #
+        #  invkind available  |  _is_object(value) | invkind we should use
+        #  ---------------------------------------------------------------
+        #     put             |     True           |   put      (?)
+        #     put             |     False          |   put
+        #     putref          |     True           |   putref
+        #     putref          |     False          |   putref   (?)
+        #     put, putref     |     True           |   putref
+        #     put, putref     |     False          |   put
+        put = self.__bind(name, DISPATCH_PROPERTYPUT)
+        putref = self.__bind(name, DISPATCH_PROPERTYPUTREF)
+        if not put and not putref:
+            raise AttributeError(name)
+        if comtypes._is_object(value):
+            descr = putref or put
+        else:
+            descr = put or putref
+        if descr.cParams == 1:
+            self._comobj._invoke(descr.memid, descr.invkind, 0, value)
+            return
+        raise AttributeError(name)
+
+    def __call__(self, *args):
+        return self._comobj._invoke(DISPID_VALUE,
+                                    DISPATCH_METHOD | DISPATCH_PROPERTYGET,
+                                    0,
+                                    *args)
+
+    def __getitem__(self, arg):
+        try:
+            return self._comobj._invoke(DISPID_VALUE,
+                                        DISPATCH_METHOD | DISPATCH_PROPERTYGET,
+                                        0,
+                                        *[arg])
+        except comtypes.COMError:
+            return iter(self)[arg]
+
+    def __setitem__(self, name, value):
+        if comtypes._is_object(value):
+            invkind = DISPATCH_PROPERTYPUTREF
+        else:
+            invkind = DISPATCH_PROPERTYPUT
+        return self._comobj._invoke(DISPID_VALUE,
+                                    invkind,
+                                    0,
+                                    *[name, value])
+
+    def __iter__(self):
+        punk = self._comobj._invoke(DISPID_NEWENUM,
+                                    DISPATCH_METHOD | DISPATCH_PROPERTYGET,
+                                    0)
+        enum = punk.QueryInterface(IEnumVARIANT)
+        enum._dynamic = True
+        return enum

comtypes/safearray.py

                             result.append(POINTER(itf)())
                     return result
                 else:
-                    return ptr[:num_elements]
+                    # If the safearray element are NOT native python
+                    # objects, the containing safearray must be kept
+                    # alive until all the elements are destroyed.
+                    if not issubclass(self._itemtype_, Structure):
+                        return ptr[:num_elements]
+                    def keep_safearray(v):
+                        v.__keepref = self
+                        return v
+                    return [keep_safearray(x) for x in ptr[:num_elements]]
             finally:
                 _safearray.SafeArrayUnaccessData(self)
 

comtypes/test/test_avmc.py

+import unittest
+from comtypes.client import CreateObject
+from comtypes.test.find_memleak import find_memleak
+
+class Test(unittest.TestCase):
+    "Test COM records"
+    def test(self):
+        # The ATL COM dll
+        avmc = CreateObject("AvmcIfc.Avmc.1")
+
+        # This returns an array (a list) of DeviceInfo records.
+        devs = avmc.FindAllAvmc()
+        
+        self.failUnlessEqual(devs[0].Flags, 12)
+        self.failUnlessEqual(devs[0].ID, 13)
+        self.failUnlessEqual(devs[0].LocId, 14)
+        self.failUnlessEqual(devs[0].Description, "Avmc")
+        self.failUnlessEqual(devs[0].SerialNumber, "1234")
+
+        self.failUnlessEqual(devs[1].Flags, 22)
+        self.failUnlessEqual(devs[1].ID, 23)
+        self.failUnlessEqual(devs[1].LocId, 24)
+        self.failUnlessEqual(devs[1].Description, "Avmc2")
+        self.failUnlessEqual(devs[1].SerialNumber, "5678")
+
+##        # Leaks... where?
+##        def doit():
+##            avmc.FindAllAvmc()
+##        self.check_leaks(doit)
+
+    def check_leaks(self, func, limit=0):
+        bytes = find_memleak(func)
+        self.failIf(bytes > limit, "Leaks %d bytes" % bytes)
+
+if __name__ == "__main__":
+    unittest.main()

comtypes/test/test_collections.py

         cv.Reset()
         self.failUnlessRaises(ArgumentError, lambda: cv[:])
 
-    def test_leaks(self):
+    def test_leaks_1(self):
         # The XP firewall manager.
         fwmgr = CreateObject('HNetCfg.FwMgr')
         # apps has a _NewEnum property that implements IEnumVARIANT
         bytes = find_memleak(doit, (2, 20))
         self.failIf(bytes, "Leaks %d bytes" % bytes)
 
+    def test_leaks_2(self):
+        # The XP firewall manager.
+        fwmgr = CreateObject('HNetCfg.FwMgr')
+        # apps has a _NewEnum property that implements IEnumVARIANT
+        apps = fwmgr.LocalPolicy.CurrentProfile.AuthorizedApplications
+
         def doit():
             iter(apps).Next(99)
         bytes = find_memleak(doit, (2, 20))
         self.failIf(bytes, "Leaks %d bytes" % bytes)
 
+    def test_leaks_3(self):
+        # The XP firewall manager.
+        fwmgr = CreateObject('HNetCfg.FwMgr')
+        # apps has a _NewEnum property that implements IEnumVARIANT
+        apps = fwmgr.LocalPolicy.CurrentProfile.AuthorizedApplications
+
+        def doit():
+            for i in range(2):
+                for what in iter(apps):
+                    pass
+        bytes = find_memleak(doit, (2, 20))
+        self.failIf(bytes, "Leaks %d bytes" % bytes)
+
 if __name__ == "__main__":
     unittest.main()

comtypes/test/test_dict.py

+"""Use Scripting.Dictionary to test the lazybind module."""
+
+import unittest
+from comtypes import COMError
+from comtypes.client import CreateObject
+from comtypes.client.lazybind import Dispatch
+from comtypes.automation import VARIANT
+
+class Test(unittest.TestCase):
+    def test_dict(self):
+        d = CreateObject("Scripting.Dictionary", dynamic=True)
+        self.failUnlessEqual(type(d), Dispatch)
+
+        # Count is a normal propget, no propput
+        self.failUnlessEqual(d.Count, 0)
+        self.assertRaises(AttributeError, lambda: setattr(d, "Count", -1))
+
+        # HashVal is a 'named' propget, no propput
+        ##d.HashVal
+
+        # Add(Key, Item) -> None
+        self.failUnlessEqual(d.Add("one", 1), None)
+        self.failUnlessEqual(d.Count, 1)
+
+        # RemoveAll() -> None
+        self.failUnlessEqual(d.RemoveAll(), None)
+        self.failUnlessEqual(d.Count, 0)
+
+        # CompareMode: propget, propput
+        # (Can only be set when dict is empty!)
+        self.failUnlessEqual(d.CompareMode, 0)
+        d.CompareMode = 1
+        self.failUnlessEqual(d.CompareMode, 1)
+        d.CompareMode = 0
+
+        # Exists(key) -> bool
+        self.failUnlessEqual(d.Exists(42), False)
+        d.Add(42, "foo")
+        self.failUnlessEqual(d.Exists(42), True)
+
+        # Keys() -> array
+        # Items() -> array
+        self.failUnlessEqual(d.Keys(), (42,))
+        self.failUnlessEqual(d.Items(), ("foo",))
+        d.Remove(42)
+        self.failUnlessEqual(d.Exists(42), False)
+        self.failUnlessEqual(d.Keys(), ())
+        self.failUnlessEqual(d.Items(), ())
+
+        # Item[key] : propget
+        d.Add(42, "foo")
+        self.failUnlessEqual(d.Item[42], "foo")
+
+        d.Add("spam", "bar")
+        self.failUnlessEqual(d.Item["spam"], "bar")
+
+        # Item[key] = value: propput, propputref
+        d.Item["key"] = "value"
+        self.failUnlessEqual(d.Item["key"], "value")
+        d.Item[42] = 73, 48
+        self.failUnlessEqual(d.Item[42], (73, 48))
+
+        ################################################################
+        # part 2, testing propput and propputref
+
+        s = CreateObject("Scripting.Dictionary", dynamic=True)
+        s.CompareMode = 42
+
+        # This calls propputref, since we assign an Object
+        d.Item["object"] = s
+        # This calls propput, since we assing a Value
+        d.Item["value"] = s.CompareMode
+
+        a = d.Item["object"]
+ 
+        self.failUnlessEqual(d.Item["object"], s)
+        self.failUnlessEqual(d.Item["object"].CompareMode, 42)
+        self.failUnlessEqual(d.Item["value"], 42)
+
+        # Changing a property of the object
+        s.CompareMode = 5
+        self.failUnlessEqual(d.Item["object"], s)
+        self.failUnlessEqual(d.Item["object"].CompareMode, 5)
+        self.failUnlessEqual(d.Item["value"], 42)
+
+        # This also calls propputref since we assign an Object
+        d.Item["var"] = VARIANT(s)
+        self.failUnlessEqual(d.Item["var"], s)
+
+        # iter(d)
+        keys = [x for x in d]
+        self.failUnlessEqual(d.Keys(),
+                             tuple([x for x in d]))
+
+        # d[key] = value
+        # d[key] -> value
+        d["blah"] = "blarg"
+        self.failUnlessEqual(d["blah"], "blarg")
+        # d(key) -> value
+        self.failUnlessEqual(d("blah"), "blarg")
+
+if __name__ == "__main__":
+    unittest.main()

comtypes/test/test_dyndispatch.py

 import unittest
 from comtypes.client import CreateObject
-from comtypes.client.dynamic import _Dispatch
+import comtypes.client.lazybind
 
 class Test(unittest.TestCase):
     def test(self):
         d.Language = "jscript"
         d.AddCode('function x() { return [3, "spam foo", 3.14]; };')
         result = d.Run("x", [])
-        self.failUnless(isinstance(result, _Dispatch))
+        self.failUnless(isinstance(result,
+                                   comtypes.client.lazybind.Dispatch))
         self.failUnlessEqual(result[0], 3)
         self.failUnlessEqual(result[1], "spam foo")
         self.failUnlessEqual(result[2], 3.14)
         d.Language = "jscript"
         d.AddCode('function x(a1, a2) { return [3, "spam foo", 3.14, a1, a2]; };')
         result = d.Run("x", [42, 96])
-        self.failUnless(isinstance(result, _Dispatch))
+        self.failUnless(isinstance(result,
+                                   comtypes.client.lazybind.Dispatch))
         self.failUnlessEqual(result[0], 3)
         self.failUnlessEqual(result[1], "spam foo")
         self.failUnlessEqual(result[2], 3.14)

comtypes/test/test_excel.py

 xlRangeValueMSPersistXML = 12
 
 class Test(unittest.TestCase):
-    def setUp(self):
-        self.xl = CreateObject("Excel.Application")
 
-    def test_excel(self):
+    def test_earlybound(self):
+        self._doit(False)
+
+    def test_latebound(self):
+        self._doit(True)
+
+    def _doit(self, dynamic):
+        self.xl = CreateObject("Excel.Application", dynamic=dynamic)
+        
         xl = self.xl
         xl.Visible = 0
         self.failUnlessEqual(xl.Visible, False)
 
         for i in xrange(20):
             xl.Cells.Item[i+1,i+1].Value[()] = "Hi %d" % i
+            print xl.Cells.Item[i+1, i+1].Value[()]
+
+        for i in xrange(20):
+            xl.Cells(i+1,i+1).Value[()] = "Hi %d" % i
+            print xl.Cells(i+1, i+1).Value[()]
 
         # test dates out with Excel
         xl.Range["A5"].Value[()] = "Excel time"
         sh.Range[sh.Cells.Item[1,1],sh.Cells.Item[3,3]].Copy(sh.Cells.Item[4,1])
         sh.Range[sh.Cells.Item[4,1],sh.Cells.Item[6,3]].Select()
 
-        import time
-        time.sleep(2)
-
     def tearDown(self):
         # Close all open workbooks without saving, then quit excel.
         for wb in self.xl.Workbooks:

comtypes/test/test_propputref.py

 from comtypes.automation import VARIANT
 
 class Test(unittest.TestCase):
-    def test(self):
-        d = CreateObject("Scripting.Dictionary")
-        s = CreateObject("TestComServerLib.TestComServer")
+    def test(self, dynamic=False):
+        d = CreateObject("Scripting.Dictionary", dynamic=dynamic)
+        s = CreateObject("TestComServerLib.TestComServer", dynamic=dynamic)
         s.name = "the value"
 
         # This calls propputref, since we assign an Object
         self.failUnlessEqual(d.Item["var"], s)
 
     def test_dispatch(self):
-        from comtypes.client.dynamic import Dispatch
-        d = Dispatch(CreateObject("Scripting.Dictionary"))
-        s = Dispatch(CreateObject("TestComServerLib.TestComServer"))
-        s.name = "the value"
-
-        # This calls propputref, since we assign an Object
-        d.Item["object"] = s
-        # This calls propput, since we assing a Value
-        d.Item["value"] = s.name
-
-        self.failUnlessEqual(d.Item["object"], s._comobj)
-        self.failUnlessEqual(d.Item["object"].name, "the value")
-        self.failUnlessEqual(d.Item["value"], "the value")
-
-        # Changing the default property of the object
-        s.name = "foo bar"
-        self.failUnlessEqual(d.Item["object"], s._comobj)
-        self.failUnlessEqual(d.Item["object"].name, "foo bar")
-        self.failUnlessEqual(d.Item["value"], "the value")
-
-        # This also calls propputref since we assign an Object
-        d.Item["var"] = s._comobj
-        self.failUnlessEqual(d.Item["var"], s._comobj)
+        return self.test(dynamic=True)
 
 if __name__ == "__main__":
     unittest.main()

comtypes/test/test_sapi.py

 from comtypes.client import CreateObject
 
 class Test(unittest.TestCase):
-    def test(self):
-        engine = CreateObject("SAPI.SpVoice")
-        stream = CreateObject("SAPI.SpFileStream")
+    def test(self, dynamic=False):
+        engine = CreateObject("SAPI.SpVoice", dynamic=dynamic)
+        stream = CreateObject("SAPI.SpFileStream", dynamic=dynamic)
         from comtypes.gen import SpeechLib
 
         fd, fname = tempfile.mkstemp(suffix=".wav")
         os.unlink(fname)
 
     def test_dyndisp(self):
-        from comtypes.client.dynamic import _Dispatch
-        engine = _Dispatch(CreateObject("SAPI.SpVoice"))
-        stream = _Dispatch(CreateObject("SAPI.SpFileStream"))
-
-        from comtypes.gen import SpeechLib
-
-        fd, fname = tempfile.mkstemp(suffix=".wav")
-        os.close(fd)
-
-        stream.Open(fname, SpeechLib.SSFMCreateForWrite)
-
-        # engine.AudioStream is a propputref property
-        engine.AudioOutputStream = stream
-        self.failUnlessEqual(engine.AudioOutputStream, stream._comobj)
-        engine.speak("Hello, World", 0)
-        stream.Close()
-        filesize = os.stat(fname).st_size
-        self.failUnless(filesize > 100, "filesize only %d bytes" % filesize)
-        os.unlink(fname)
+        return self.test(dynamic=True)
 
 if __name__ == "__main__":
     unittest.main()

comtypes/typeinfo.py

 class tagFUNCDESC(Structure):
     # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 769
     def __repr__(self):
-        return "FUNCDESC(memid=%s, cParams=%s, cParamsOpt=%s, callconv=%s, invkind=%s)" % \
-               (self.memid, self.cParams, self.cParamsOpt, self.callconv, self.invkind)
+        return "FUNCDESC(memid=%s, cParams=%s, cParamsOpt=%s, callconv=%s, invkind=%s, funckind=%s)" % \
+               (self.memid, self.cParams, self.cParamsOpt, self.callconv, self.invkind, self.funckind)
 
 
 FUNCDESC = tagFUNCDESC
 .. _ctypes: http://docs.python.org/lib/module-ctypes.html
 """
 import sys, os
+import ctypes
 from distutils.core import setup, Command, DistutilsOptionError
 
 try:
         if build.build_lib is not None:
             sys.path.insert(0, build.build_lib)
 
+        # Register our ATL COM tester dll
+        dll = ctypes.OleDLL(r"source\debug\AvmcIfc.dll")
+        dll.DllRegisterServer()
+
         import comtypes.test
         comtypes.test.use_resources.extend(self.use_resources)
 
     'Operating System :: Microsoft :: Windows',
     'Operating System :: Microsoft :: Windows :: Windows CE',
     'Programming Language :: Python',
-    'Programming Language :: Python :: 2'
-    'Programming Language :: Python :: 2.4'
-    'Programming Language :: Python :: 2.5'
-    'Programming Language :: Python :: 2.6'
-    'Programming Language :: Python :: 3'
-    'Programming Language :: Python :: 3.0'
+    'Programming Language :: Python :: 2',
+    'Programming Language :: Python :: 2.4',
+    'Programming Language :: Python :: 2.5',
+    'Programming Language :: Python :: 2.6',
+    'Programming Language :: Python :: 3',
+    'Programming Language :: Python :: 3.0',
     'Topic :: Software Development :: Libraries :: Python Modules',
     ]
 
+// Avmc.cpp : Implementation of CAvmcIfcApp and DLL registration.
+
+#include "stdafx.h"
+#include "AvmcIfc.h"
+#include "Avmc.h"
+#include <comdef.h>
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+const IID DEVICE_INFO_IID = {0x6C7A25CB, 0x7938, 0x4BE0, {0xA2, 0x85, 0x12, 0xC6, 0x16, 0x71, 0x7F, 0xDD} };
+
+STDMETHODIMP Avmc::InterfaceSupportsErrorInfo(REFIID riid)
+{
+	static const IID* arr[] = 
+	{
+		&IID_IAvmc,
+	};
+
+	for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
+	{
+		if (InlineIsEqualGUID(*arr[i],riid))
+			return S_OK;
+	}
+	return S_FALSE;
+}
+
+STDMETHODIMP Avmc::FindAllAvmc(SAFEARRAY **avmcList)
+{	
+	FT_STATUS ftStatus;
+	DWORD numDevs;
+	DWORD i;
+
+	if (!avmcList)
+		return E_POINTER;
+
+	if (*avmcList != NULL) {
+		::SafeArrayDestroy(*avmcList);
+		*avmcList = NULL;
+	}
+	numDevs = 2;
+	ftStatus = FT_OK;
+
+	devInfo = new FT_DEVICE_LIST_INFO_NODE[numDevs];
+
+	strcpy(devInfo[0].Description, "Avmc");
+	devInfo[0].Flags = 12;
+	devInfo[0].ID = 13;
+	devInfo[0].LocId = 14;
+	
+	strcpy(devInfo[0].SerialNumber, "1234");
+	devInfo[0].Type = 15;
+
+	strcpy(devInfo[1].Description, "Avmc2");
+	devInfo[1].Flags = 22;
+	devInfo[1].ID = 23;
+	devInfo[1].LocId = 24;
+	strcpy(devInfo[1].SerialNumber, "5678");
+	devInfo[1].Type = 25;
+
+	ftStatus = FT_OK;
+	if (ftStatus == FT_OK) {
+
+		// Copy into a new safe array...
+		//////////////////////////////////////////////////
+		//here starts the actual creation of the array
+		//////////////////////////////////////////////////
+		IRecordInfo *pUdtRecordInfo = NULL;
+		HRESULT hr = GetRecordInfoFromGuids (LIBID_AVMCIFCLib, 1, 0, 0, DEVICE_INFO_IID, &pUdtRecordInfo);
+	    if( FAILED( hr ) ) {
+			HRESULT hr2 = Error( _T("Can not create Device Info interface") );
+			return( hr );
+		}
+		////////////////// SafeArray Creation and Returning ///////////////
+		SAFEARRAYBOUND rgsabound[1];
+		rgsabound[0].lLbound = 0;
+		rgsabound[0].cElements = numDevs;
+		*avmcList = ::SafeArrayCreateEx( VT_RECORD, 1, rgsabound, pUdtRecordInfo );
+
+		pUdtRecordInfo->Release(); // Release the interface
+		if( *avmcList == NULL ) {
+	        HRESULT hr = Error( _T("Can not create array of Device Info structures") );
+			return( hr );
+		}
+
+		///////////////////////////////////////////////////////////////////
+
+#ifdef DEBUG_NOW
+		strstream s2;
+		s2.clear();
+		for (i = 0; i < numDevs; i++) {
+			s2 << "Dev " << i << endl;
+			s2 << " Flags = 0x" << hex << devInfo[i].Flags << endl;
+			s2 << " Type =  0x" << hex << devInfo[i].Type << endl;
+			s2 << " ID =    0x" << hex << devInfo[i].ID << endl;
+			s2 << " LocId = 0x" << hex << devInfo[i].LocId << endl;
+			s2 << " SerialNumber = " << devInfo[i].SerialNumber << endl;
+			s2 << " Description  = " << devInfo[i].Description << endl;
+			s2 << " ftHandle     = 0x" << hex << devInfo[i].ftHandle << endl;
+			s2 << "---" << endl;
+		}
+		s2 << ends;
+		MessageBox (0, s2.str(), "Device List", 0);
+#endif
+		DeviceInfo HUGEP *pD = NULL;
+		hr = SafeArrayAccessData (*avmcList, (void HUGEP **)&pD);
+
+		for (i = 0; i < numDevs; i++) {
+			pD[i].Flags =			(ULONG) devInfo[i].Flags;
+			pD[i].Type =			(ULONG) devInfo[i].Type;
+			pD[i].ID =				(ULONG) devInfo[i].ID;
+			pD[i].LocId =			(ULONG) devInfo[i].LocId;
+			pD[i].SerialNumber =	_com_util::ConvertStringToBSTR(devInfo[i].SerialNumber);
+			pD[i].Description =		_com_util::ConvertStringToBSTR(devInfo[i].Description);
+			pD[i].ftHandle =		(ULONG)devInfo[i].ftHandle;
+		}
+
+		hr = SafeArrayUnaccessData(*avmcList);
+	}
+
+	return S_OK;
+}
+// Avmc.h: Definition of the Avmc class
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_AVMC_H__14DBEE48_EB7D_48AD_8BEE_8E15B2D0A780__INCLUDED_)
+#define AFX_AVMC_H__14DBEE48_EB7D_48AD_8BEE_8E15B2D0A780__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "resource.h"       // main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// Avmc
+
+//#include "FTD2XX.h"
+typedef PVOID	FT_HANDLE;
+typedef ULONG	FT_STATUS;
+
+enum {
+	FT_OK,
+	FT_INVALID_HANDLE,
+	FT_DEVICE_NOT_FOUND,
+	FT_DEVICE_NOT_OPENED,
+	FT_IO_ERROR,
+	FT_INSUFFICIENT_RESOURCES,
+	FT_INVALID_PARAMETER,
+	FT_INVALID_BAUD_RATE,
+
+	FT_DEVICE_NOT_OPENED_FOR_ERASE,
+	FT_DEVICE_NOT_OPENED_FOR_WRITE,
+	FT_FAILED_TO_WRITE_DEVICE,
+	FT_EEPROM_READ_FAILED,
+	FT_EEPROM_WRITE_FAILED,
+	FT_EEPROM_ERASE_FAILED,
+	FT_EEPROM_NOT_PRESENT,
+	FT_EEPROM_NOT_PROGRAMMED,
+	FT_INVALID_ARGS,
+	FT_NOT_SUPPORTED,
+	FT_OTHER_ERROR
+};
+
+
+//#define FT_SUCCESS(status) ((status) == FT_OK)
+
+typedef struct _ft_device_list_info_node {
+	ULONG Flags;
+	ULONG Type;
+	ULONG ID;
+	DWORD LocId;
+	char SerialNumber[16];
+	char Description[64];
+	FT_HANDLE ftHandle;
+} FT_DEVICE_LIST_INFO_NODE;
+
+class Avmc : 
+	public IDispatchImpl<IAvmc, &IID_IAvmc, &LIBID_AVMCIFCLib>, 
+	public ISupportErrorInfo,
+	public CComObjectRoot,
+	public CComCoClass<Avmc,&CLSID_Avmc>
+{
+public:
+	Avmc() {}
+BEGIN_COM_MAP(Avmc)
+	COM_INTERFACE_ENTRY(IDispatch)
+	COM_INTERFACE_ENTRY(IAvmc)
+	COM_INTERFACE_ENTRY(ISupportErrorInfo)
+END_COM_MAP()
+//DECLARE_NOT_AGGREGATABLE(Avmc) 
+// Remove the comment from the line above if you don't want your object to 
+// support aggregation. 
+
+DECLARE_REGISTRY_RESOURCEID(IDR_Avmc)
+// ISupportsErrorInfo
+	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
+
+// IAvmc
+public:
+	STDMETHOD(FindAllAvmc)(/*[out]*/ SAFEARRAY **avmcList);
+
+private:
+	void FinalizeCommand(char *command, int cmdLength);
+	int  ReadToSimpleArray(int devNum, char *arr);
+
+private:
+	FT_DEVICE_LIST_INFO_NODE			*devInfo;
+	char								mResArray[512]; // Inconsistant array - just to read results...
+};
+
+#endif // !defined(AFX_AVMC_H__14DBEE48_EB7D_48AD_8BEE_8E15B2D0A780__INCLUDED_)
+HKCR
+{
+	AvmcIfc.Avmc.1 = s 'Avmc Class'
+	{
+		CLSID = s '{41BDBDFC-A848-4523-A149-ADD3AE1E6D84}'
+	}
+	AvmcIfc.Avmc = s 'Avmc Class'
+	{
+		CLSID = s '{41BDBDFC-A848-4523-A149-ADD3AE1E6D84}'
+	}
+	NoRemove CLSID
+	{
+		ForceRemove {41BDBDFC-A848-4523-A149-ADD3AE1E6D84} = s 'Avmc Class'
+		{
+			ProgID = s 'AvmcIfc.Avmc.1'
+			VersionIndependentProgID = s 'AvmcIfc.Avmc'
+			InprocServer32 = s '%MODULE%'
+			{
+				val ThreadingModel = s 'both'
+			}
+		}
+	}
+}

source/AvmcIfc.cpp

+// AvmcIfc.cpp : Implementation of DLL Exports.
+
+
+// Note: Proxy/Stub Information
+//      To build a separate proxy/stub DLL, 
+//      run nmake -f AvmcIfcps.mk in the project directory.
+
+#include "stdafx.h"
+#include "resource.h"
+#include <initguid.h>
+#include "AvmcIfc.h"
+
+#include "AvmcIfc_i.c"
+#include "Avmc.h"
+
+
+CComModule _Module;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+OBJECT_ENTRY(CLSID_Avmc, Avmc)
+END_OBJECT_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// DLL Entry Point
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+    if (dwReason == DLL_PROCESS_ATTACH)
+    {
+        _Module.Init(ObjectMap, hInstance, &LIBID_AVMCIFCLib);
+        DisableThreadLibraryCalls(hInstance);
+    }
+    else if (dwReason == DLL_PROCESS_DETACH)
+        _Module.Term();
+    return TRUE;    // ok
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow(void)
+{
+    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+{
+    return _Module.GetClassObject(rclsid, riid, ppv);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllRegisterServer - Adds entries to the system registry
+
+STDAPI DllRegisterServer(void)
+{
+    // registers object, typelib and all interfaces in typelib
+    return _Module.RegisterServer(TRUE);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllUnregisterServer - Removes entries from the system registry
+
+STDAPI DllUnregisterServer(void)
+{
+    return _Module.UnregisterServer(TRUE);
+}
+
+

source/AvmcIfc.def

+; AvmcIfc.def : Declares the module parameters.
+
+LIBRARY      "AvmcIfc.DLL"
+
+EXPORTS
+	DllCanUnloadNow     PRIVATE
+	DllGetClassObject   PRIVATE
+	DllRegisterServer   PRIVATE
+	DllUnregisterServer	PRIVATE

source/AvmcIfc.dsp

+# Microsoft Developer Studio Project File - Name="AvmcIfc" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=AvmcIfc - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "AvmcIfc.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "AvmcIfc.mak" CFG="AvmcIfc - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "AvmcIfc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AvmcIfc - Win32 Unicode Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AvmcIfc - Win32 Release MinSize" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AvmcIfc - Win32 Release MinDependency" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AvmcIfc - Win32 Unicode Release MinSize" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "AvmcIfc - Win32 Unicode Release MinDependency" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "AvmcIfc - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ftd2xx.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# Begin Custom Build - Performing registration
+OutDir=.\Debug
+TargetPath=.\debug\AvmcIfc.dll
+InputPath=.\debug\AvmcIfc.dll
+SOURCE="$(InputPath)"
+
+"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	regsvr32 /s /c "$(TargetPath)" 
+	echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" 
+	
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "AvmcIfc - Win32 Unicode Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# Begin Custom Build - Performing registration
+OutDir=.\DebugU
+TargetPath=.\DebugU\AvmcIfc.dll
+InputPath=.\DebugU\AvmcIfc.dll
+SOURCE="$(InputPath)"
+
+"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	if "%OS%"=="" goto NOTNT 
+	if not "%OS%"=="Windows_NT" goto NOTNT 
+	regsvr32 /s /c "$(TargetPath)" 
+	echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" 
+	goto end 
+	:NOTNT 
+	echo Warning : Cannot register Unicode DLL on Windows 95 
+	:end 
+	
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "AvmcIfc - Win32 Release MinSize"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseMinSize"
+# PROP BASE Intermediate_Dir "ReleaseMinSize"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseMinSize"
+# PROP Intermediate_Dir "ReleaseMinSize"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ftd2xx.lib /nologo /subsystem:windows /dll /machine:I386
+# Begin Custom Build - Performing registration
+OutDir=.\ReleaseMinSize
+TargetPath=.\ReleaseMinSize\AvmcIfc.dll
+InputPath=.\ReleaseMinSize\AvmcIfc.dll
+SOURCE="$(InputPath)"
+
+"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	regsvr32 /s /c "$(TargetPath)" 
+	echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" 
+	
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "AvmcIfc - Win32 Release MinDependency"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseMinDependency"
+# PROP BASE Intermediate_Dir "ReleaseMinDependency"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseMinDependency"
+# PROP Intermediate_Dir "ReleaseMinDependency"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# Begin Custom Build - Performing registration
+OutDir=.\ReleaseMinDependency
+TargetPath=.\ReleaseMinDependency\AvmcIfc.dll
+InputPath=.\ReleaseMinDependency\AvmcIfc.dll
+SOURCE="$(InputPath)"
+
+"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	regsvr32 /s /c "$(TargetPath)" 
+	echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" 
+	
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "AvmcIfc - Win32 Unicode Release MinSize"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseUMinSize"
+# PROP BASE Intermediate_Dir "ReleaseUMinSize"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseUMinSize"
+# PROP Intermediate_Dir "ReleaseUMinSize"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# Begin Custom Build - Performing registration
+OutDir=.\ReleaseUMinSize
+TargetPath=.\ReleaseUMinSize\AvmcIfc.dll
+InputPath=.\ReleaseUMinSize\AvmcIfc.dll
+SOURCE="$(InputPath)"
+
+"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	if "%OS%"=="" goto NOTNT 
+	if not "%OS%"=="Windows_NT" goto NOTNT 
+	regsvr32 /s /c "$(TargetPath)" 
+	echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" 
+	goto end 
+	:NOTNT 
+	echo Warning : Cannot register Unicode DLL on Windows 95 
+	:end 
+	
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "AvmcIfc - Win32 Unicode Release MinDependency"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseUMinDependency"
+# PROP BASE Intermediate_Dir "ReleaseUMinDependency"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseUMinDependency"
+# PROP Intermediate_Dir "ReleaseUMinDependency"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_UNICODE" /D "_ATL_STATIC_REGISTRY" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
+# Begin Custom Build - Performing registration
+OutDir=.\ReleaseUMinDependency
+TargetPath=.\ReleaseUMinDependency\AvmcIfc.dll
+InputPath=.\ReleaseUMinDependency\AvmcIfc.dll
+SOURCE="$(InputPath)"
+
+"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	if "%OS%"=="" goto NOTNT 
+	if not "%OS%"=="Windows_NT" goto NOTNT 
+	regsvr32 /s /c "$(TargetPath)" 
+	echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" 
+	goto end 
+	:NOTNT 
+	echo Warning : Cannot register Unicode DLL on Windows 95 
+	:end 
+	
+# End Custom Build
+
+!ENDIF 
+
+# Begin Target
+
+# Name "AvmcIfc - Win32 Debug"
+# Name "AvmcIfc - Win32 Unicode Debug"
+# Name "AvmcIfc - Win32 Release MinSize"
+# Name "AvmcIfc - Win32 Release MinDependency"
+# Name "AvmcIfc - Win32 Unicode Release MinSize"
+# Name "AvmcIfc - Win32 Unicode Release MinDependency"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Avmc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AvmcIfc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AvmcIfc.def
+# End Source File
+# Begin Source File
+
+SOURCE=.\AvmcIfc.idl
+# ADD MTL /tlb ".\AvmcIfc.tlb" /h "AvmcIfc.h" /iid "AvmcIfc_i.c" /Oicf
+# End Source File
+# Begin Source File
+
+SOURCE=.\AvmcIfc.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Avmc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AvmcCommands.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FTD2XX.H
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\Avmc.rgs
+# End Source File
+# End Group
+# End Target
+# End Project

source/AvmcIfc.dsw

+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AvmcIfc"=.\AvmcIfc.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

source/AvmcIfc.idl

+// AvmcIfc.idl : IDL source for AvmcIfc.dll
+//
+
+// This file will be processed by the MIDL tool to
+// produce the type library (AvmcIfc.tlb) and marshalling code.
+
+import "oaidl.idl";
+import "ocidl.idl";
+
+// 1129c4e1-f46a-4b61-a464-406d7df3e516
+	
+    [
+        uuid(6C7A25CB-7938-4BE0-A285-12C616717FDD),
+        version(1.0),
+        helpstring("FTDI Device info node")
+    ]
+    typedef struct DeviceInfo {
+        [helpstring("Special case variant")]    VARIANT  Special;
+        [helpstring("Name of the variable")]    BSTR     Name;
+        [helpstring("Value of the variable")]   long     Value;
+		[helpstring("Flags")]					long Flags; //ULONG
+		[helpstring("Device Type")]				long Type; //ULONG
+		[helpstring("Device Id")]			    long ID;  //ULONG
+		[helpstring("Local Id")]			    long LocId; //DWORD
+		[helpstring("Device's Serial Number")]  BSTR SerialNumber;
+		[helpstring("Device's Description")]    BSTR Description;
+		[helpstring("Device current handle")]   long ftHandle; //ULONG
+    } DeviceInfo;
+
+	[
+		object,
+		uuid(6C7A25CC-7938-4BE0-A285-12C616717FDD),
+		dual,
+		helpstring("IAvmc Interface"),
+		pointer_default(unique)
+	]
+	interface IAvmc : IDispatch
+	{
+		[id(1), helpstring("method FindAllAvmc")] HRESULT FindAllAvmc([out] SAFEARRAY(DeviceInfo) *avmcList);
+	};
+
+[
+	uuid(70577167-ED71-4977-B719-2C40C6DD8E1D),
+	version(1.0),
+	helpstring("AvmcIfc 1.0 Type Library")
+]
+library AVMCIFCLib
+{
+	importlib("stdole32.tlb");
+	importlib("stdole2.tlb");
+
+	
+	[
+		uuid(41BDBDFC-A848-4523-A149-ADD3AE1E6D84),
+		helpstring("Avmc Class")
+	]
+	coclass Avmc
+	{
+		[default] interface IAvmc;
+	};
+};

source/AvmcIfc.rc

+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""winres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "1 TYPELIB ""AvmcIfc.tlb""\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0"
+        BEGIN
+            VALUE "CompanyName", "\0"
+            VALUE "FileDescription", "AvmcIfc Module\0"
+            VALUE "FileVersion", "1, 0, 0, 1\0"
+            VALUE "InternalName", "AvmcIfc\0"
+            VALUE "LegalCopyright", "Copyright 2006\0"
+            VALUE "OriginalFilename", "AvmcIfc.DLL\0"
+            VALUE "ProductName", "AvmcIfc Module\0"
+            VALUE "ProductVersion", "1, 0, 0, 1\0"
+            VALUE "OLESelfRegister", "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_PROJNAME            "AvmcIfc"
+    IDS_AVMC_DESC           "Avmc Class"
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Unknown language: 0xD, 0x1 resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HEB)
+#ifdef _WIN32
+LANGUAGE 0xD, 0x1
+#pragma code_page(1255)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// REGISTRY
+//
+
+IDR_Avmc                REGISTRY DISCARDABLE    "Avmc.rgs"
+#endif    // Unknown language: 0xD, 0x1 resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+1 TYPELIB "AvmcIfc.tlb"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

source/AvmcIfc.sln

+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AvmcIfc", "AvmcIfc.vcproj", "{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release MinDependency = Release MinDependency
+		Release MinSize = Release MinSize
+		Unicode Debug = Unicode Debug
+		Unicode Release MinDependency = Unicode Release MinDependency
+		Unicode Release MinSize = Unicode Release MinSize
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Debug.ActiveCfg = Debug|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Debug.Build.0 = Debug|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Release MinDependency.ActiveCfg = Release MinDependency|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Release MinDependency.Build.0 = Release MinDependency|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Release MinSize.ActiveCfg = Release MinSize|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Release MinSize.Build.0 = Release MinSize|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Unicode Debug.ActiveCfg = Unicode Debug|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Unicode Debug.Build.0 = Unicode Debug|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Unicode Release MinDependency.ActiveCfg = Unicode Release MinDependency|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Unicode Release MinDependency.Build.0 = Unicode Release MinDependency|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Unicode Release MinSize.ActiveCfg = Unicode Release MinSize|Win32
+		{B5A3DC99-A047-4696-86AC-10E96CDB2EBC}.Unicode Release MinSize.Build.0 = Unicode Release MinSize|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal

source/AvmcIfc.tlb

Binary file added.

source/AvmcIfc.vcproj

+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="AvmcIfc"
+	SccProjectName=""
+	SccLocalPath=""
+	Keyword="AtlProj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Unicode Release MinSize|Win32"
+			OutputDirectory=".\ReleaseUMinSize"
+			IntermediateDirectory=".\ReleaseUMinSize"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			UseOfATL="2"
+			ATLMinimizesCRunTimeLibraryUsage="TRUE"
+			CharacterSet="1">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="TRUE"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="3"
+				PrecompiledHeaderThrough="stdafx.h"
+				PrecompiledHeaderFile=".\ReleaseUMinSize/AvmcIfc.pch"
+				AssemblerListingLocation=".\ReleaseUMinSize/"
+				ObjectFile=".\ReleaseUMinSize/"
+				ProgramDataBaseFileName=".\ReleaseUMinSize/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Performing registration"
+				CommandLine="if &quot;%OS%&quot;==&quot;&quot; goto NOTNT
+if not &quot;%OS%&quot;==&quot;Windows_NT&quot; goto NOTNT
+regsvr32 /s /c &quot;$(TargetPath)&quot;
+echo regsvr32 exec. time &gt; &quot;$(OutDir)\regsvr32.trg&quot;
+goto end
+:NOTNT
+echo Warning : Cannot register Unicode DLL on Windows 95
+:end
+"
+				Outputs="$(OutDir)\regsvr32.trg"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile=".\ReleaseUMinSize/AvmcIfc.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ModuleDefinitionFile=".\AvmcIfc.def"
+				ProgramDatabaseFile=".\ReleaseUMinSize/AvmcIfc.pdb"
+				SubSystem="2"
+				ImportLibrary=".\ReleaseUMinSize/AvmcIfc.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\ReleaseUMinSize/AvmcIfc.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release MinSize|Win32"
+			OutputDirectory=".\ReleaseMinSize"
+			IntermediateDirectory=".\ReleaseMinSize"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			UseOfATL="2"
+			ATLMinimizesCRunTimeLibraryUsage="TRUE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="1"
+				InlineFunctionExpansion="1"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="3"
+				PrecompiledHeaderThrough="stdafx.h"
+				PrecompiledHeaderFile=".\ReleaseMinSize/AvmcIfc.pch"
+				AssemblerListingLocation=".\ReleaseMinSize/"
+				ObjectFile=".\ReleaseMinSize/"
+				ProgramDataBaseFileName=".\ReleaseMinSize/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Performing registration"
+				CommandLine="regsvr32 /s /c &quot;$(TargetPath)&quot;
+echo regsvr32 exec. time &gt; &quot;$(OutDir)\regsvr32.trg&quot;
+"
+				Outputs="$(OutDir)\regsvr32.trg"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="odbc32.lib odbccp32.lib"
+				OutputFile=".\ReleaseMinSize/AvmcIfc.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ModuleDefinitionFile=".\AvmcIfc.def"
+				ProgramDatabaseFile=".\ReleaseMinSize/AvmcIfc.pdb"
+				SubSystem="2"
+				ImportLibrary=".\ReleaseMinSize/AvmcIfc.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\ReleaseMinSize/AvmcIfc.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Unicode Debug|Win32"
+			OutputDirectory=".\DebugU"
+			IntermediateDirectory=".\DebugU"
+			ConfigurationType="2"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="1">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="3"
+				PrecompiledHeaderThrough="stdafx.h"
+				PrecompiledHeaderFile=".\DebugU/AvmcIfc.pch"
+				AssemblerListingLocation=".\DebugU/"
+				ObjectFile=".\DebugU/"
+				ProgramDataBaseFileName=".\DebugU/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description="Performing registration"
+				CommandLine="if &quot;%OS%&quot;==&quot;&quot; goto NOTNT
+if not &quot;%OS%&quot;==&quot;Windows_NT&quot; goto NOTNT
+regsvr32 /s /c &quot;$(TargetPath)&quot;
+echo regsvr32 exec. time &gt; &quot;$(OutDir)\regsvr32.trg&quot;
+goto end
+:NOTNT
+echo Warning : Cannot register Unicode DLL on Windows 95
+:end
+"
+				Outputs="$(OutDir)\regsvr32.trg"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile=".\DebugU/AvmcIfc.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				ModuleDefinitionFile=".\AvmcIfc.def"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\DebugU/AvmcIfc.pdb"
+				SubSystem="2"
+				ImportLibrary=".\DebugU/AvmcIfc.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\DebugU/AvmcIfc.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1033"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="2"
+			UseOfMFC="0"