internal ComTypeDefInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : base(typeLib, typeKind, index) { TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _infoType = "TypeDef"; if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("TypeDefInfo: " + _name); _varComType = TypeLibUtil.TYPEDESCToString(typeLib, _typeInfo, typeAttr.tdescAlias, TypeLibUtil.COMTYPE); _varClrType = TypeLibUtil.TYPEDESCToString(typeLib, _typeInfo, typeAttr.tdescAlias, !TypeLibUtil.COMTYPE); _typeInfo.ReleaseTypeAttr(typeAttrPtr); // Add to the typelibrary for resolution typeLib.TypeDefHash.Add(_name, this); }
internal ComTypeLibTreeNode(TypeLibrary typeLib) { _typeLib = typeLib; _typeLib.TreeNode = this; SetPresInfo(_typeLib.PresInfo); PostConstructor(); }
// The TypeLibrary is used to resolve any typedefs public static String TYPEDESCToString(TypeLibrary typeLib, UCOMITypeInfo typeInfo, TYPEDESC typeDesc, bool comType) { String ret = TYPEDESCToStringInt(typeLib, typeInfo, typeDesc, comType, 0); return ret; }
internal ComStructInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : base(typeLib, typeKind, index) { switch (typeKind) { case TYPEKIND.TKIND_ENUM: _infoType = "Enum"; break; case TYPEKIND.TKIND_MODULE: _infoType = "Module"; break; case TYPEKIND.TKIND_RECORD: _infoType = "Struct"; break; case TYPEKIND.TKIND_UNION: _infoType = "Union"; break; } TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); for (int i = 0; i < typeAttr.cVars; i++) { ComVariableInfo mi = new ComVariableInfo(this, _typeKind, _typeInfo, i); _members.Add(mi); } _typeInfo.ReleaseTypeAttr(typeAttrPtr); if (TraceUtil.If(this, TraceLevel.Verbose)) Trace.WriteLine("Struct: " + _name); }
internal AssemblyTreeNode(Assembly assembly, TypeLibrary typeLib) : base() { _assembly = assembly; _typeLib = typeLib; MethodInfo entryPoint = null; try { entryPoint = _assembly.EntryPoint; } catch { // Sadly, this can throw for some reason } if (entryPoint != null) _isDragSource = true; PostConstructor(); }
// Used for subclassses that are classes, objects and interfaces // Where the type library information is known internal BasicInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) : this() { Setup(typeLib, typeKind, index, typeInfo, guid); }
// Used for subclassses that are classes, objects and interfaces // Where the type library information is known internal BasicInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index) : this() { Setup(typeLib, typeKind, index, null, Guid.Empty); }
public static String TYPEDESCToStringInt(TypeLibrary typeLib, UCOMITypeInfo typeInfo, TYPEDESC typeDesc, bool comType, int level) { String ret; try { if ((VarEnum)typeDesc.vt == VarEnum.VT_PTR || (VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_SAFEARRAY) { TYPEDESC pTypeDesc = (TYPEDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(TYPEDESC)); ret = TYPEDESCToStringInt(typeLib, typeInfo, pTypeDesc, comType, level + 1); if ((VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_SAFEARRAY) { // FIXME - what about the non-comType return "SAFEARRAY(" + ret + ")"; } if (comType) { ret += "*"; } else { // void* become IntPtr if (ret.Equals("void")) ret = "System.IntPtr"; else { // The first pointer is not a ref, its only // a ref if there are two // FIXME - what if there are more? if (level == 1) ret = "ref " + ret; } } return ret; } if ((VarEnum)(typeDesc.vt & ActiveX.VT_TYPEMASK) == VarEnum.VT_CARRAY) { // typeDesc.lpValue in this case is really the laValue // (since TYPEDESC is a contains a union of pointers) ARRAYDESC pArrayDesc = (ARRAYDESC)Marshal.PtrToStructure(typeDesc.lpValue, typeof(ARRAYDESC)); ret = TYPEDESCToStringInt(typeLib, typeInfo, pArrayDesc.tdescElem, comType, level + 1); // Just show the number of diminsions, don't worry about // showing the size of each since we don't want to // get into marshalling the variable length ARRAYDESC // structure for (int i = 0; i < pArrayDesc.cDims; i++) ret += "[]"; return ret; } if ((VarEnum)typeDesc.vt == VarEnum.VT_USERDEFINED) { UCOMITypeInfo uTypeInfo = null; // FIXME - sometimes this chokes and hangs due to a bad // handle value here, need to do something to prevent this int href = typeDesc.lpValue.ToInt32(); typeInfo.GetRefTypeInfo(href, out uTypeInfo); if (uTypeInfo != null) { String docName; String docString; int helpContext; String helpFile; uTypeInfo.GetDocumentation(-1, out docName, out docString, out helpContext, out helpFile); // Fix up misc references if (docName.Equals("GUID")) docName = "System.Guid"; // Present the user names for the types in COM // mode, but for the CLR types, get the real // underlying names if (!comType) return typeLib.ResolveTypeDef(docName, comType); return docName; } else { TraceUtil.WriteLineWarning(null, "USER: "******" 0x" + href.ToString("X") + " ***UNKNOWN***"); return "(userDef unknown)"; } } return GetTypeStr(typeDesc.vt, comType); } catch (Exception ex) { TraceUtil.WriteLineWarning (null, "ActiveX type conversion error: " + ex); return "(error)"; } }
// 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); }
internal static void RememberTypeLib(TypeLibrary typeLib) { TraceUtil.WriteLineInfo(null, "typelib add to properties: " + typeLib.FileName); string guid = Utils.MakeGuidStr(typeLib.Key._guid); _typelibs.Remove(typeLib.FileName); _typelibs.Add(new PreviouslyOpenedTypeLibrary(typeLib.FileName, guid, typeLib.Key._version)); }
internal static void SelectTypeLib(TypeLibrary lib) { // Find and select the registered node BrowserTreeNode typeLibNode = FindTypeLib(lib.Key); if (typeLibNode != null) typeLibNode.PointToNode(); else { throw new Exception("Bug, expected to be in type lib tree: " + lib); } }
// Gets a type library given a file name, this returns // an existing type library if it is already known internal static TypeLibrary GetTypeLib(String fileName) { TraceUtil.WriteLineInfo(null, "TypeLib - GetTypeLib (file): " + fileName); // Key is assigned in ReadTypeLibFile TypeLibrary lib = new TypeLibrary(); lib._fileName = fileName; lib.ReadTypeLibFile(); if (lib._iTypeLib == null) return null; // Find the type library by guid just in case it was // already opened. This will also translate it. return GetTypeLib(lib._iTypeLib); }
// If the UCOMITypeLib pointer is good, then remember // that, because the type library may not be in the registry // or a file we can open. But we can still convert it and // read its information internal static TypeLibrary GetTypeLib(TypeLibKey key, UCOMITypeLib iTypeLib) { TraceUtil.WriteLineInfo(null, "TypeLib - GetTypeLib: " + key); lock (typeof(TypeLibrary)) { TypeLibrary lib = (TypeLibrary)_openedTypeLibs[key]; if (lib != null && lib._converted) return lib; try { if (lib == null) { // Have to create one lib = new TypeLibrary(key); lib._iTypeLib = iTypeLib; try { lib.PopulateFromRegistry(key); } catch (Exception ex) { // This could be ok, sometimes a typelib is not // in the registry TraceUtil.WriteLineWarning (typeof(TypeLibrary), "GetTypeLib exception (not in registry) " + ex); if (lib._iTypeLib == null) { throw new Exception("Failed to find type library information in registry", ex); } } } lib.TranslateTypeLib(); // Generate the C# source after the translation for // now because the source generation requires the // definitions to be read which can cause a call // to GetTypeLib(), don't want to be re-entered // FIXME //lib.GenerateSource(); return lib; } catch (Exception ex) { TraceUtil.WriteLineWarning(typeof(TypeLibrary), "GetTypeLib exception " + ex); throw new Exception("Error getting type library: ", ex); } } }
// Called when a type library is loaded from the remembered // type libraries upon start up internal static void RestoreTypeLib(String fileName, Guid guid, string version) { TypeLibrary lib = null; try { lock (typeof(TypeLibrary)) { TraceUtil.WriteLineInfo(null, "RestoreTypeLib - guid/version: " + guid + " " + version); TypeLibKey typeLibKey = new TypeLibKey(guid, version); // We should not have already seen this one, but // if we have, we will be decent about it lib = (TypeLibrary)_openedTypeLibs[typeLibKey]; if (lib == null) { lib = new TypeLibrary(typeLibKey); try { lib.PopulateFromRegistry(typeLibKey); } catch (Exception ex) { // Get the file name we recorded since its not // registered lib._fileName = fileName; // Might not be registered, ignore error TraceUtil.WriteLineInfo (typeof(TypeLibrary), "Unregistered typelib restore: " + fileName + " exception: " + ex); } } lib.ReadTypeLibFile(); if (lib._openedFile) { if (!_searchMode) { ComSupport.AddTypeLib(lib); } TraceUtil.WriteLineInfo(null, "TypeLib - loaded/restored: " + lib); } else { // Something's wrong, don't try and open again lib.ForgetMe(); TraceUtil.WriteLineInfo(null, "TypeLib - failed to open " + "- forgotten: " + lib); } } } catch (Exception ex) { TraceUtil.WriteLineWarning (null, "TypeLib - deleting bad typelib entry: " + lib + " " + ex); // Something's wrong, don't try and open again lib.ForgetMe(); } }
protected static void GetTypeLibsFromRegistry(String guidStr) { TypeLibrary lib = null; RegistryKey regKey = Windows.KeyTypeLib.OpenSubKey(guidStr); String[] subKeyNames = regKey.GetSubKeyNames(); foreach (String versionStr in subKeyNames) { RegistryKey versionKey = regKey.OpenSubKey(versionStr); try { if (versionKey == null) { throw new Exception("Version entry not " + "found for typelib: " + guidStr); } TypeLibKey key = new TypeLibKey(new Guid(guidStr), versionStr); // See if we already know about it TypeLibrary convLib = (TypeLibrary)_openedTypeLibs[key]; if (convLib == null) { lib = new TypeLibrary(); lib.Key = key; lib.PopulateFromRegistry(versionKey); // We don't read the type lib info until the user // wants the detail text or something else // that requires it } else { lib = convLib; } _registeredTypeLibs.Add(lib, lib); } catch (Exception ex) { TraceUtil.WriteLineInfo(null, "TypeLib - failure to read: " + versionKey + " " + ex); } } }
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; }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index) { Setup(typeLib, typeKind, index, null, Guid.Empty); }
// Returns the index of this object's type in the typelib protected int GetTypeLib(IntPtr dispPtr) { if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine("ComObjInfo::GetTypeLib: " + _obj + " type: " + _obj.GetType()); } if (_typeLib != null) return -1; UCOMITypeLib iTypeLib; int index = -1; try { IDispatch idisp = (IDispatch) Marshal.GetObjectForIUnknown(dispPtr); int count; int result = idisp.GetTypeInfoCount(out count); if (result != 0) { TraceUtil.WriteLineWarning (typeof(ComObjectInfo), "ComObjInfo - " + "GetTypeInfoCount failed: 0x" + result.ToString("x") + " obj: " + _obj); throw new COMException("(probably a bug, please report) " + "Failed on GetTypeInfoCount", result); } if (count == 0) { TraceUtil.WriteLineWarning (typeof(ComObjectInfo), "ComObjInfo - " + " typeinfo count = 0: " + _obj); throw new Exception("This object has no type information " + "(GetTypeInfoCount returned 0). "); } result = idisp.GetTypeInfo(0, 0, out _typeInfo); if (result != 0) { TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "ComObjInfo - " + "typeInfo not found:" + _obj); throw new COMException("(probably a bug, please report) " + "Failed to get ITypeInfo", result); } if (_typeInfo == null) { TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "ComObjInfo - " + "typeInfo not found:" + _obj); throw new Exception("(probably a bug, please report) " + "Null TypeInfo pointer returned"); } // Now we can get the type library information using these // nice interfaces provided as part of the interop services _typeInfo.GetContainingTypeLib(out iTypeLib, out index); _typeLib = TypeLibrary.GetTypeLib(iTypeLib); } catch (Exception ex) { if (_typeInfo != null) { Guid guid = BasicInfo.GuidFromTypeInfo(_typeInfo); TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "ComObjInfo (type " + guid + ")"); } TraceUtil.WriteLineWarning(typeof(ComObjectInfo), "Containing typelib not found:" + ex); throw new Exception("Cannot get TypeLib for object. " + "Getting the TypeLib information for " + "an object is required as this contains " + "the type information used to display " + "the object. ", ex); } if (TraceUtil.If(this, TraceLevel.Info)) { Trace.WriteLine("ComObjInfo - containing typelib index: " + index); } return index; }
internal virtual void Setup(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { _typeLib = typeLib; _iTypeLib = typeLib.ITypeLib; if (typeInfo != null) _typeInfo = typeInfo; else _iTypeLib.GetTypeInfo(index, out _typeInfo); if (!guid.Equals(Guid.Empty)) InitGuid(guid); else InitGuid(GuidFromTypeInfo(_typeInfo)); _typeKind = typeKind; _presInfo = PresentationMap.GetInfo(_typeKind); GetDocumentation(index); if (TraceUtil.If(this, TraceLevel.Info)) Trace.WriteLine(this, "Basic: " + typeKind + " " + this); }
// 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); }
// Adds the remembered type lib to the favorites part // of the type library tree internal static BrowserTreeNode AddTypeLib(TypeLibrary lib) { BrowserTreeNode findRoot; findRoot = _favTypeLibNode; if (findRoot == null) return null; BrowserTreeNode typeLibNode = FindTypeLib(lib.Key, findRoot); if (typeLibNode == null) { typeLibNode = new ComTypeLibTreeNode(lib); // This might be called on the thread to restore open typelibs _comTree.Invoke(new BrowserTreeNode.AddLogicalInvoker(findRoot.AddLogicalNode), new Object[] { typeLibNode }); } return typeLibNode; }
// Constuctor when creating from withing a typelib protected ComClassInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { Init(); SetupTypeLibInfo(typeLib, typeKind, index, typeInfo, guid); _classesByCLSID.Add(_guid, this); }
internal static void ForgetTypeLib(TypeLibrary typelib) { TraceUtil.WriteLineInfo(null, "ForgetTypeLib " + typelib); _typelibs.Remove(typelib.FileName); }
protected void SetupTypeLibInfo(TypeLibrary typeLib, TYPEKIND typeKind, int index, UCOMITypeInfo typeInfo, Guid guid) { if (_hasTypeLibInfo) return; base.Setup(typeLib, typeKind, index, typeInfo, guid); TYPEATTR typeAttr; IntPtr typeAttrPtr; _typeInfo.GetTypeAttr(out typeAttrPtr); typeAttr = (TYPEATTR)Marshal.PtrToStructure(typeAttrPtr, typeof(TYPEATTR)); _cImplTypes = typeAttr.cImplTypes; _typeFlags = typeAttr.wTypeFlags; _typeInfo.ReleaseTypeAttr(typeAttrPtr); _hasTypeLibInfo = true; }
// 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; } }
internal static AssemblyTreeNode AddAssy(Assembly assy, TypeLibrary typeLib) { // The assembly might have already been added (this can // happen when a previously converted [from com] assembly // is opened), if so, // find it and make sure the typeLib information is provided AssemblyTreeNode atNode = FindAssemblyNode(assy); if (atNode != null) { if (typeLib != null) atNode.TypeLib = typeLib; return atNode; } ICollection types = null; // Only get the types if the control tree is showing because // it can take a long time if (ComponentInspectorProperties.ShowControlPanel) types = GetAssyTypes(assy); AssemblyTreeNode node = new AssemblyTreeNode(assy, typeLib); if (_assyTree.InvokeRequired) { _assyTree.Invoke(new BrowserTreeNode.AddLogicalInvoker(_assyRootNode.AddLogicalNode), new Object[] { node }); _controlTree.Invoke(new ControlTree.AddAssyInvoker(ControlTree.AddAssy), new Object[] { assy, types }); } else { _assyRootNode.AddLogicalNode(node); ControlTree.AddAssy(assy, types); } return node; }