// Get or create a interface info for the specified interface
        internal static ComInterfaceInfo GetInterfaceInfo
            (TypeLibrary typeLib,
            TYPEKIND typeKind,
            int index)
        {
            UCOMITypeInfo typeInfo;
            Guid          guid;

            typeLib.ITypeLib.GetTypeInfo(index, out typeInfo);
            guid = GuidFromTypeInfo(typeInfo);
            // Use the TypeLibrary lock to prevent deadlocks
            lock (typeof(TypeLibrary))
            {
                // Never heard of it, get the defining type library
                ComInterfaceInfo intInfo =
                    (ComInterfaceInfo)_interfacesByGuid[guid];
                if (intInfo == null)
                {
                    // Add the interface to the table before we call
                    // setup because setup will try to create the
                    // inherited interfaces, and it should find
                    // this one (otherwise it will stack overflow)
                    intInfo = new ComInterfaceInfo();
                    _interfacesByGuid.Add(guid, intInfo);
                    intInfo.Setup(typeLib, typeKind, index);
                }
                return(intInfo);
            }
        }
예제 #2
0
 // Finds the best class that implements this interface
 internal static ArrayList GetClassInfos(ComInterfaceInfo intInfo)
 {
     // Add to the global hash
     lock (_classesByInterface)
     {
         ArrayList ret = (ArrayList)_classesByInterface[intInfo];
         if (ret == null)
         {
             return(new ArrayList());
         }
         return(ret);
     }
 }
예제 #3
0
        protected ComInterfaceInfo PickBestInterface()
        {
            ComInterfaceInfo bestIf = null;

            // Pick the one with the highest number of parents
            foreach (ComInterfaceInfo ifInfo in _interfaces)
            {
                if (bestIf == null ||
                    ifInfo.ParentCount > bestIf.ParentCount)
                {
                    bestIf = ifInfo;
                }
            }
            return(bestIf);
        }
예제 #4
0
        public override void AddDomTo(IList parent)
        {
            //return;

            // Do the class
            CodeTypeDeclaration codeDom =
                ComInterfaceInfo.CreateTypeCodeDom
                    (this, _interfaces, ComInterfaceInfo.DOCLASS);

            parent.Add(codeDom);

            // Do the interface associated with the class
            codeDom = ComInterfaceInfo.CreateTypeCodeDom
                          (this, _interfaces, !ComInterfaceInfo.DOCLASS);
            parent.Add(codeDom);
        }
예제 #5
0
        internal void AddInterface(ComInterfaceInfo intInfo,
                                   bool isDefault)
        {
            _interfaces.Add(intInfo);
            if (isDefault)
            {
                _defaultInterface = intInfo;
            }

            // Add to the global hash
            lock (_classesByInterface)
            {
                ArrayList classList = (ArrayList)_classesByInterface[intInfo];
                if (classList == null)
                {
                    classList = new ArrayList();
                    _classesByInterface.Add(intInfo, classList);
                }
                classList.Add(this);
            }
        }
예제 #6
0
		// Get or create a interface info for the specified interface
		internal static ComInterfaceInfo GetInterfaceInfo
			(TypeLibrary typeLib,
			TYPEKIND typeKind,
			int index)
		{
			UCOMITypeInfo typeInfo;
			Guid guid;
			typeLib.ITypeLib.GetTypeInfo(index, out typeInfo);
			guid = GuidFromTypeInfo(typeInfo);
			// Use the TypeLibrary lock to prevent deadlocks
			lock (typeof(TypeLibrary))
			{
				// Never heard of it, get the defining type library
				ComInterfaceInfo intInfo = 
					(ComInterfaceInfo)_interfacesByGuid[guid];
				if (intInfo == null)
				{
					// Add the interface to the table before we call
					// setup because setup will try to create the
					// inherited interfaces, and it should find
					// this one (otherwise it will stack overflow)
					intInfo = new ComInterfaceInfo();
					_interfacesByGuid.Add(guid, intInfo);
					intInfo.Setup(typeLib, typeKind, index);
				} 
				return intInfo;
			}
		}
예제 #7
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();
            }
        }
예제 #8
0
		// Finds the best class that implements this interface
		internal static ArrayList GetClassInfos(ComInterfaceInfo intInfo)
		{
			// Add to the global hash
			lock (_classesByInterface)
			{
				ArrayList ret = (ArrayList)_classesByInterface[intInfo];
				if (ret == null)
					return new ArrayList();
				return ret;
			}
		}
예제 #9
0
		internal void AddInterface(ComInterfaceInfo intInfo,
								   bool isDefault)
		{
			_interfaces.Add(intInfo);
			if (isDefault)
				_defaultInterface = intInfo;

			// Add to the global hash
			lock (_classesByInterface)
			{
				ArrayList classList = (ArrayList)_classesByInterface[intInfo];
				if (classList == null)
				{
					classList = new ArrayList();
					_classesByInterface.Add(intInfo, classList);
				}
				classList.Add(this);                
			}
		}
        // 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);
        }
        // Constructor from creating withing a typelib
        internal override void Setup(TypeLibrary typeLib,
                                     TYPEKIND typeKind,
                                     int index)
        {
            base.Setup(typeLib, typeKind, index);
            Init();
            _container = typeLib;
            TYPEATTR typeAttr;
            IntPtr   typeAttrPtr;

            _typeInfo.GetTypeAttr(out typeAttrPtr);
            typeAttr =
                (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr,
                                                 typeof(TYPEATTR));
            if (typeKind == TYPEKIND.TKIND_DISPATCH)
            {
                _infoType = "Dispatch Interface";
                _dispatch = true;
            }
            else
            {
                _infoType = "Interface";
            }
            if ((typeAttr.wTypeFlags & TYPEFLAGS.TYPEFLAG_FDUAL) != 0)
            {
                _infoType = "Dual Interface";
                _dispatch = true;
                _dual     = true;
            }
            // Members
            for (int i = 0; i < typeAttr.cFuncs; i++)
            {
                // Some members for a dispatch interface are not added
                // because they are the inherited members from the
                // IDispatch interface
                ComMemberInfo mi = ComMemberInfo.
                                   MakeComMemberInfo(this,
                                                     typeKind,
                                                     _typeInfo,
                                                     i,
                                                     _dispatch,
                                                     _dual);
                if (mi != null)
                {
                    _members.Add(mi);
                    _memberNames.Add(mi.NameKey, mi);
                }
            }
            // Inherited interfaces
            for (int i = 0; i < typeAttr.cImplTypes; i++)
            {
                int           href;
                int           refTypeIndex;
                UCOMITypeInfo refTypeInfo;
                UCOMITypeLib  refITypeLib;
                TypeLibrary   refTypeLib;
                try
                {
                    _typeInfo.GetRefTypeOfImplType(i, out href);
                    _typeInfo.GetRefTypeInfo(href, out refTypeInfo);
                    refTypeInfo.GetContainingTypeLib(out refITypeLib,
                                                     out refTypeIndex);
                    refTypeLib = TypeLibrary.GetTypeLib(refITypeLib);
                    ComInterfaceInfo mi =
                        ComInterfaceInfo.GetInterfaceInfo(refTypeLib,
                                                          typeAttr.typekind,
                                                          refTypeIndex);
                    if (TraceUtil.If(this, TraceLevel.Verbose))
                    {
                        Trace.WriteLine("  inherit: " + mi);
                    }
                    _members.Add(mi);
                    _parentCount += 1 + mi.ParentCount;
                    // Don't set the typelib on the member as multiple
                    // typelibs may refer to the same interface
                    mi._container = this;
                }
                catch (Exception ex)
                {
                    ErrorDialog.Show
                        (ex,
                        "Warning - this error was detected when attempting "
                        + "to find an ancestor of the interface "
                        + _name
                        + ".  This is normal in the case where the type "
                        + "library containing that interface "
                        + "is not available.  "
                        + "In other situations this might be a bug and "
                        + "should be reported.",
                        "Warning - Cannot Access Inherited Interface",
                        MessageBoxIcon.Warning);
                }
            }
            if (_dual)
            {
                _printName  = (String)_name.Clone();
                _printName += " (Dual)";
            }
            else
            {
                _printName = _name;
            }
            _typeInfo.ReleaseTypeAttr(typeAttrPtr);
        }