Exemplo n.º 1
0
        // Get a classinfo when reading from the registry
        internal static ComClassInfo GetClassInfo(RegistryKey classKey,
                                                  String guidStr)
        {
            Guid         guid    = new Guid(guidStr);
            ComClassInfo clsInfo = (ComClassInfo)_classesByCLSID[guid];

            if (clsInfo != null)
            {
                return(clsInfo);
            }

            return(new ComClassInfo(classKey, guidStr));
        }
Exemplo n.º 2
0
        protected Type GetTypeFromTypeLib(TypeLibrary typeLib)
        {
            if (typeLib == null)
            {
                _typeFailedException =
                    new Exception("Unable to determine TypeLib "
                                  + "from CLSID: " + _guidStr);
                throw _typeFailedException;
            }

            // Set this information because we might have read the
            // class from a source other than the type library
            _container = typeLib;
            _typeLib   = typeLib;

            // Get the type associated with the CLSId from the typelib
            if (Name == null)
            {
                ComClassInfo clsInfo = typeLib.GetClassInfoFromCLSID(_guid);
                Name = clsInfo.Name;
            }

            Type type = typeLib.FindTypeByName(Name,
                                               TypeLibrary.FIND_CLASS);

            if (type == null)
            {
                _typeFailedException =
                    new Exception("CLR type not found in "
                                  + _container
                                  + " for ActiveX type "
                                  + this
                                  + ".\n\nThis is likely caused by "
                                  + "the assembly corresponding to "
                                  + "this type library not being "
                                  + "available.");
                throw _typeFailedException;
            }

            if (TraceUtil.If(this, TraceLevel.Info))
            {
                Trace.WriteLine("ComClassInfo - type: " + type);
            }
            return(type);
        }
Exemplo n.º 3
0
        // Returns a ComClassInfo for the requested class
        // Used for creating from within a typelib
        internal static ComClassInfo GetClassInfo(TypeLibrary typeLib,
                                                  TYPEKIND typeKind,
                                                  int index)
        {
            UCOMITypeInfo typeInfo;

            typeLib.ITypeLib.GetTypeInfo(index, out typeInfo);
            Guid guid = GuidFromTypeInfo(typeInfo);

            ComClassInfo clsInfo = (ComClassInfo)_classesByCLSID[guid];

            if (clsInfo != null)
            {
                // Add the type lib information if we have seen this
                // class before
                clsInfo.SetupTypeLibInfo(typeLib, typeKind, index,
                                         null, Guid.Empty);
                return(clsInfo);
            }

            return(new ComClassInfo(typeLib, typeKind, index,
                                    typeInfo, guid));
        }
Exemplo n.º 4
0
        // Figures out the class Type of an object based on the
        // information in this type library
        // This is presently not used, we call GetTypeForITypeInfo
        // instead.  But let's keep this around since it might
        // be valuable to get a COM class instead of interface
        internal Type FigureOutClass()
        {
            _interfaces = new ArrayList();
            IntPtr unkPtr = Marshal.GetIUnknownForObject(_obj);

            Marshal.AddRef(unkPtr);
            // Find out all if the interfaces in the library implemented
            // by the object
            foreach (ComInterfaceInfo intInfo in _typeLib.Interfaces)
            {
                Guid   tempGuid = intInfo._guid;
                IntPtr implPtr;
                Marshal.QueryInterface(unkPtr, ref tempGuid, out implPtr);
                if (implPtr != IntPtr.Zero)
                {
                    if (TraceUtil.If(this, TraceLevel.Info))
                    {
                        Trace.WriteLine("ComObjectInfo - impl IID: "
                                        + intInfo);
                    }
                    // Makes sure we have the type information for this interface
                    // This method has been removed from ComInterfaceInfo
                    // since its only used here
                    //intInfo.ResolveInterface();
                    _interfaces.Add(intInfo);
                }
            }
            Marshal.Release(unkPtr);
            // Find out if any classes have default interfaces of any
            // of the interfaces implemented, hopefully there will be
            // only one
            _classesDefaultInterfaces = new ArrayList();
            _classesInterfaces        = new ArrayList();
            foreach (ComInterfaceInfo intInfo in _interfaces)
            {
                if (TraceUtil.If(this, TraceLevel.Info))
                {
                    Trace.WriteLine("ComObjectInfo - checking IID: "
                                    + intInfo);
                }
                //foreach (ComClassInfo classInfo in intInfo._typeLib.Classes)
                foreach (ComClassInfo classInfo in
                         ComClassInfo.GetClassInfos(intInfo))
                {
                    if (TraceUtil.If(this, TraceLevel.Info))
                    {
                        Trace.WriteLine("TypeLib - checking class: "
                                        + classInfo);
                    }
                    if (classInfo._defaultInterface == null)
                    {
                        continue;
                    }
                    if (classInfo._defaultInterface.Equals(intInfo))
                    {
                        _classesDefaultInterfaces.Add(classInfo);
                    }
                    // Note that this does not consider the inherited
                    // interfaces, but that's probably for the best now
                    // We want to consider those only after we have
                    // exhausted all over possibilities
                    foreach (ComInterfaceInfo implIface in
                             classInfo._interfaces)
                    {
                        if (implIface.Equals(intInfo))
                        {
                            _classesInterfaces.Add(classInfo);
                        }
                    }
                }
            }

            /*****
            *         FIXME - stuff to do to finish this:
            *  1) make a hash table that has all classes that implement a given interface.
            *  Probably make a class/interface into structure that is a list from this
            *  hash table.  This has an indication if its the classes default interface
            *  or not.  Sometimes you will get an interface in one typelib and the class
            *  is in another type lib.  This will help that, and it will also make
            *  the resolution of the classes faster.
            *  2) deal with inherited interfaces.  After we have exhausted all
            *  possbilities with the actual interfaces, when we should do checking
            *  using the inherited interfaces so at least we will find something.
            *  Of course, the inherited interfaces will show up on the query interface,
            *  so we need to make sure we prefer the lower level interfaces.  Maybe
            *  they will always show up first, but we need to see about this.
            *****/
            // If no default interface, then just take the first class
            // that implements this interface
            BasicInfo chosenClass;

            if (_classesDefaultInterfaces.Count > 0)
            {
                chosenClass = (BasicInfo)_classesDefaultInterfaces[0];
                if (TraceUtil.If(this, TraceLevel.Info))
                {
                    Trace.WriteLine("ComObjectInfo - FOUND default i/f: "
                                    + chosenClass);
                }
            }
            else if (_classesInterfaces.Count > 0)
            {
                chosenClass = (BasicInfo)_classesInterfaces[0];
                if (TraceUtil.If(this, TraceLevel.Info))
                {
                    Trace.WriteLine("ComObjectInfo - FOUND non-default i/f: "
                                    + chosenClass);
                }
            }
            else if (_interfaces.Count == 1)
            {
                chosenClass = (BasicInfo)_interfaces[0];
                if (TraceUtil.If(this, TraceLevel.Info))
                {
                    Trace.WriteLine("ComObjectInfo - FOUND only one interface: "
                                    + chosenClass);
                }
            }
            else
            {
                if (TraceUtil.If(this, TraceLevel.Info))
                {
                    Trace.WriteLine("ComObjectInfo - NO CLASS FOUND "
                                    + " (using static): " + this);
                }
                SetStaticType();
                return(_objTypeStatic);
            }
            String className = chosenClass._container.Name
                               + "." + chosenClass.Name;

            if (chosenClass is ComClassInfo)
            {
                className += "Class";
            }
            Type t = Type.GetType(className + "," + _typeLib.Name,
                                  true, true);

            if (TraceUtil.If(this, TraceLevel.Info))
            {
                Trace.WriteLine("ComObjectInfo - FOUND type: " + t);
            }
            return(t);
            // This does not seem to work
            //return Type.GetTypeFromCLSID
            //    (((ComClassInfo)_classesDefaultInterfaces[0])._guid, true);
        }
Exemplo n.º 5
0
        // We have an object and we want to figure out the best
        // type for it
        protected override void SetType()
        {
            if (TraceUtil.If(this, TraceLevel.Info))
            {
                Trace.WriteLine("ComObjInfo - SetType: "
                                + _obj);
            }
            if (_obj != null)
            {
                if (!_obj.GetType().IsCOMObject&&
                    !_obj.GetType().Equals(Windows.COM_ROOT_TYPE))
                {
                    base.SetType();
                    return;
                }
                if (TypeIsGoodEnough(_obj.GetType()))
                {
                    _objType = _obj.GetType();
                    return;
                }
            }
            if (TypeIsGoodEnough(_objType))
            {
                return;
            }
            // Get the type library so we can convert it only once.  If
            // we don't do this, the GetTypeForITypeInfo code will
            // try to convert it multiple times.  This also sets the _typeInfo
            // pointer.
            if (_typeLib == null)
            {
                IntPtr dispPtr;
                // Get the IDispatch ptr
                try
                {
                    dispPtr = Marshal.GetIDispatchForObject(_obj);
                }
                catch
                {
                    // This could just be a COM object, see if it
                    // implements any of the interfaces we know about
                    _interfaces =
                        ComInterfaceInfo.GetImplementedInterfacesKnown(_obj);
                    if (_interfaces.Count == 0)
                    {
                        throw new Exception
                                  ("Unable to determine type of object, "
                                  + "IDispatch not implemented, and it implements "
                                  + "no interfaces associated with known type "
                                  + "libraries.");
                    }
                    ComInterfaceInfo ciInfo = PickBestInterface();

                    AssignType(ciInfo.GetCLRType());
                    return;
                }
                // Get the type library from the dispPtr
                try
                {
                    Marshal.AddRef(dispPtr);
                    GetTypeLib(dispPtr);
                }
                finally
                {
                    Marshal.Release(dispPtr);
                }
            }
            if (_typeLib != null)
            {
                // Get the COM pointer to the ITypeInfo so we can call
                // GetTypeForITypeInfo below.
                //IntPtr iTypeInfo = Marshal.GetIUnknownForObject(_typeInfo);
                // This figures out the actual class of the object, by hand
                // based on what interfaces it implements.
                //Type newType = FigureOutClass();
                // This returns the type of the interface this object implements,
                // but is done completely automatically.  This is probably the
                // better solution (since is less of my code).
                // The problem this this one is that it converts any
                // necessary type libraries automatically without
                // having my hooks so I can properly find out about the
                // converted type libraries
                //Type newType = Marshal.GetTypeForITypeInfo(iTypeInfo);
                // Just look up the type by name from the type info's name,
                // this will get an interface type, which is fine.  A class type
                // might be better, but that takes more work to figure out.
                // FIXME - we may want to go to find the class type for those
                // objects that implement multiple interfaces, see about that.
                String typeName = ComClassInfo.GetTypeName(_typeInfo);
                _comTypeName = _typeLib.Name + "." + typeName;
                if (TraceUtil.If(this, TraceLevel.Info))
                {
                    Trace.WriteLine("TypeName: " + typeName);
                }
                Type newType =
                    _typeLib.FindTypeByName(typeName,
                                            !TypeLibrary.FIND_CLASS);
                AssignType(newType);
            }
            // Can't figure it out, let the superclass deal with it
            if (_objType == null)
            {
                base.SetType();
            }
        }
        // Applies to classes and interface, and since we don't have
        // a common superclass, just put it here and make it static
        internal static CodeTypeDeclaration CreateTypeCodeDom
            (BasicInfo basicInfo,
            ArrayList interfaces,
            bool doClass)
        {
            CodeTypeDeclaration codeDom = new CodeTypeDeclaration();
            Guid useGuid = basicInfo._guid;

            if (basicInfo is ComClassInfo && doClass)
            {
                codeDom.Name        = basicInfo.Name + "Class";
                codeDom.IsInterface = false;
            }
            else
            {
                // Use the default interface's class if we are generating
                // the interface for the class
                if (basicInfo is ComClassInfo)
                {
                    useGuid = ((ComClassInfo)basicInfo).DefaultInterface._guid;
                }
                codeDom.Name        = basicInfo.Name;
                codeDom.IsInterface = true;
                if (basicInfo is ComInterfaceInfo)
                {
                    ComInterfaceInfo ifaceInfo = (ComInterfaceInfo)basicInfo;
                    ComInterfaceType ifaceType;
                    if (ifaceInfo._dual)
                    {
                        ifaceType = ComInterfaceType.InterfaceIsDual;
                    }
                    else if (ifaceInfo._dispatch)
                    {
                        ifaceType = ComInterfaceType.InterfaceIsIDispatch;
                    }
                    else
                    {
                        ifaceType = ComInterfaceType.InterfaceIsIUnknown;
                    }
                    // Add InterfaceType attribute
                    CodeAttributeArgument ifaceTypeArg = new CodeAttributeArgument();
                    ifaceTypeArg.Value = new CodeSnippetExpression
                                             ("(System.Runtime.InteropServices.ComInterfaceType)"
                                             + (int)ifaceType);
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.InterfaceType",
                            new CodeAttributeArgument[] { ifaceTypeArg }));
                }
            }
            // Add Guid attribute
            CodeAttributeArgument guidArg = new CodeAttributeArgument();

            // The _guidStr has braces which the attribute can't handle
            guidArg.Value = new CodePrimitiveExpression
                                (useGuid.ToString());
            codeDom.CustomAttributes.Add
                (new CodeAttributeDeclaration
                    ("System.Runtime.InteropServices.Guid",
                    new CodeAttributeArgument[] { guidArg }));
            if (basicInfo is ComClassInfo)
            {
                ComClassInfo classInfo = (ComClassInfo)basicInfo;
                if (doClass)
                {
                    codeDom.TypeAttributes |= TypeAttributes.Abstract;
                    // Class inherits from the interface of the same name
                    codeDom.BaseTypes.Add
                        (new CodeTypeReference(basicInfo.Name));
                    // Add TypeLibType attribute
                    CodeAttributeArgument typeLibTypeArg = new CodeAttributeArgument();
                    typeLibTypeArg.Value = new CodePrimitiveExpression
                                               ((int)classInfo._typeFlags);
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.TypeLibType",
                            new CodeAttributeArgument[] { typeLibTypeArg }));
                    // Add ClassInterface attribute
                    CodeAttributeArgument classIfaceArg = new CodeAttributeArgument();
                    classIfaceArg.Value = new CodeSnippetExpression("(short)0");
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.ClassInterface",
                            new CodeAttributeArgument[] { classIfaceArg }));
                    // Make the no-arg constructor public (default cons
                    // visibility is family)
                    CodeConstructor cons = new CodeConstructor();
                    cons.Attributes = MemberAttributes.Public;
                    codeDom.Members.Add(cons);
                }
                else
                {
                    // Add CoClass attribute
                    CodeAttributeArgument typeArg = new CodeAttributeArgument();
                    typeArg.Value = new CodeTypeReferenceExpression
                                        (new CodeTypeReference("typeof("
                                                               + basicInfo.GetCLRTypeName()
                                                               + ")"));
                    codeDom.CustomAttributes.Add
                        (new CodeAttributeDeclaration
                            ("System.Runtime.InteropServices.CoClass",
                            new CodeAttributeArgument[] { typeArg }));
                }
            }
            if (TraceUtil.If(basicInfo, TraceLevel.Info))
            {
                Trace.WriteLine(basicInfo, "CG - "
                                + basicInfo.Name);
            }
            bool firstTime = true;

            // Add inherited interfaces
            foreach (BasicInfo member in interfaces)
            {
                if (member is ComInterfaceInfo)
                {
                    // FIXME - should probably compare these by GUID
                    if (member.Name.Equals("IUnknown") ||
                        member.Name.Equals("IDispatch"))
                    {
                        continue;
                    }
                    codeDom.BaseTypes.Add
                        (new CodeTypeReference(member.Name));
                    // Add the members for the class or interface,
                    // its all of the members
                    // of each implemented interface
                    if ((!codeDom.IsInterface && doClass) ||
                        codeDom.IsInterface)
                    {
                        // Qualify subsequent interfaces with the
                        // interface name
                        // Unless this is an interface, then just
                        // leave the name alone
                        if (firstTime || codeDom.IsInterface)
                        {
                            AddMembers(codeDom, member.Members, null);
                        }
                        else
                        {
                            AddMembers(codeDom, member.Members,
                                       member.Name + "_");
                        }
                    }
                    firstTime = false;
                }
            }
            // Don't add the members for the class interface
            if (basicInfo is ComClassInfo && !doClass)
            {
                return(codeDom);
            }
            // Add members for this interface (a class has none)
            AddMembers(codeDom, basicInfo.Members, null);
            return(codeDom);
        }