internal ComMethodInformation(bool hasvarargs, bool hasoptional, ParameterInformation[] arguments, Type returnType, int dispId, COM.INVOKEKIND invokekind) : base(hasvarargs, hasoptional, arguments) { this.ReturnType = returnType; this.DispId = dispId; this.InvokeKind = invokekind; }
internal ComTypeEnumDesc(ComTypes.ITypeInfo typeInfo, ComTypeLibDesc typeLibDesc) : base(typeInfo, ComType.Enum, typeLibDesc) { ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo); string[] memberNames = new string[typeAttr.cVars]; object[] memberValues = new object[typeAttr.cVars]; IntPtr p = IntPtr.Zero; // For each enum member get name and value. for (int i = 0; i < typeAttr.cVars; i++) { typeInfo.GetVarDesc(i, out p); // Get the enum member value (as object). ComTypes.VARDESC varDesc; try { varDesc = (ComTypes.VARDESC)Marshal.PtrToStructure(p, typeof(ComTypes.VARDESC)); if (varDesc.varkind == ComTypes.VARKIND.VAR_CONST) { memberValues[i] = Marshal.GetObjectForNativeVariant(varDesc.desc.lpvarValue); } } finally { typeInfo.ReleaseVarDesc(p); } // Get the enum member name memberNames[i] = ComRuntimeHelpers.GetNameOfMethod(typeInfo, varDesc.memid); } _memberNames = memberNames; _memberValues = memberValues; }
internal static string GetNameOfType(ComTypes.ITypeInfo typeInfo) { string name; string documentation; GetInfoFromType(typeInfo, out name, out documentation); return name; }
internal static string GetNameOfLib(ComTypes.ITypeLib typeLib) { string name; string strDocString; int dwHelpContext; string strHelpFile; typeLib.GetDocumentation(-1, out name, out strDocString, out dwHelpContext, out strHelpFile); return name; }
/// <summary> /// Constructor /// </summary> /// <param name="info">ITypeInfo object being wrapped by this object</param> internal ComTypeInfo(COM.ITypeInfo info) { _typeinfo = info; _properties = new Dictionary<String, ComProperty>(StringComparer.OrdinalIgnoreCase); _methods = new Dictionary<String, ComMethod>(StringComparer.OrdinalIgnoreCase); if (_typeinfo != null) { Initialize(); } }
private DateTime FiletimeToDateTime(ComType.FILETIME FileTime) { try { if (FileTime.dwLowDateTime < 0) FileTime.dwLowDateTime = 0; if (FileTime.dwHighDateTime < 0) FileTime.dwHighDateTime = 0; long RawFileTime = (((long)FileTime.dwHighDateTime) << 32) + FileTime.dwLowDateTime; return DateTime.FromFileTimeUtc(RawFileTime); } catch { return new DateTime(); } }
internal static ComTypeLibDesc GetFromTypeLib(ComTypes.ITypeLib typeLib) { // check whether we have already loaded this type library ComTypes.TYPELIBATTR typeLibAttr = ComRuntimeHelpers.GetTypeAttrForTypeLib(typeLib); ComTypeLibDesc typeLibDesc; lock (_CachedTypeLibDesc) { if (_CachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out typeLibDesc)) { return typeLibDesc; } } typeLibDesc = new ComTypeLibDesc(); typeLibDesc._typeLibName = ComRuntimeHelpers.GetNameOfLib(typeLib); int countTypes = typeLib.GetTypeInfoCount(); for (int i = 0; i < countTypes; i++) { ComTypes.TYPEKIND typeKind; typeLib.GetTypeInfoType(i, out typeKind); ComTypes.ITypeInfo typeInfo; if (typeKind == ComTypes.TYPEKIND.TKIND_COCLASS) { typeLib.GetTypeInfo(i, out typeInfo); ComTypeClassDesc classDesc = new ComTypeClassDesc(typeInfo); typeLibDesc._classes.AddLast(classDesc); } else if (typeKind == ComTypes.TYPEKIND.TKIND_ENUM) { typeLib.GetTypeInfo(i, out typeInfo); ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(typeInfo); typeLibDesc._enums.Add(enumDesc.TypeName, enumDesc); } } // cache the typelib using the guid as the dictionary key lock (_CachedTypeLibDesc) { //check if we are late and somebody already added the key. ComTypeLibDesc curLibDesc; if (_CachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out curLibDesc)) { return curLibDesc; } _CachedTypeLibDesc.Add(typeLibAttr.guid, typeLibDesc); } return typeLibDesc; }
public int SetFileTimeProxy( IntPtr rawFileName, ref ComTypes.FILETIME rawCreationTime, ref ComTypes.FILETIME rawLastAccessTime, ref ComTypes.FILETIME rawLastWriteTime, ref DOKAN_FILE_INFO rawFileInfo) { try { string file = GetFileName(rawFileName); long time; time = ((long)rawCreationTime.dwHighDateTime << 32) + (uint)rawCreationTime.dwLowDateTime; DateTime ctime = DateTime.FromFileTime(time); if (time == 0) ctime = DateTime.MinValue; time = ((long)rawLastAccessTime.dwHighDateTime << 32) + (uint)rawLastAccessTime.dwLowDateTime; DateTime atime = DateTime.FromFileTime(time); if (time == 0) atime = DateTime.MinValue; time = ((long)rawLastWriteTime.dwHighDateTime << 32) + (uint)rawLastWriteTime.dwLowDateTime; DateTime mtime = DateTime.FromFileTime(time); if (time == 0) mtime = DateTime.MinValue; return operations_.SetFileTime( file, ctime, atime, mtime, GetFileInfo(ref rawFileInfo)); } catch (Exception e) { Console.Error.WriteLine(e.ToString()); return -1; } }
internal static void GetInfoFromType(ComTypes.ITypeInfo typeInfo, out string name, out string documentation) { int dwHelpContext; string strHelpFile; typeInfo.GetDocumentation(-1, out name, out documentation, out dwHelpContext, out strHelpFile); }
internal static ComTypes.TYPELIBATTR GetTypeAttrForTypeLib(ComTypes.ITypeLib typeLib) { IntPtr pAttrs = IntPtr.Zero; typeLib.GetLibAttr(out pAttrs); // GetTypeAttr should never return null, this is just to be safe if (pAttrs == IntPtr.Zero) { throw Error.CannotRetrieveTypeInformation(); } try { return (ComTypes.TYPELIBATTR)Marshal.PtrToStructure(pAttrs, typeof(ComTypes.TYPELIBATTR)); } finally { typeLib.ReleaseTLibAttr(pAttrs); } }
public void Stat(out COMTypes.STATSTG pstatstg, int grfStatFlag) { pstatstg = new COMTypes.STATSTG(); pstatstg.cbSize = this.stm.Length; }
//---------------------------------- // IStream //---------------------------------- public void Clone(out COMTypes.IStream ppstm) { throw new NotImplementedException(); }
/// <summary> /// Determine .net type for the given type descriptor /// </summary> /// <param name="typedesc">COM type descriptor to convert</param> /// <returns>type represented by the typedesc</returns> internal static Type GetTypeFromTypeDesc(COM.TYPEDESC typedesc) { VarEnum vt = (VarEnum)typedesc.vt; return VarEnumSelector.GetTypeForVarEnum(vt); }
// Disable obsolete warning about VarEnum in CoreCLR #pragma warning disable 618 /// <summary> /// This function gets a string representation of the Type Descriptor /// This is used in generating signature for Properties and Methods. /// </summary> /// <param name="typeinfo">Reference to the type info to which the type descriptor belongs</param> /// <param name="typedesc">reference to type descriptor which is being converted to string from</param> /// <returns>string representation of the type descriptor</returns> private static string GetStringFromTypeDesc(COM.ITypeInfo typeinfo, COM.TYPEDESC typedesc) { if ((VarEnum)typedesc.vt == VarEnum.VT_PTR) { COM.TYPEDESC refdesc = ClrFacade.PtrToStructure<COM.TYPEDESC>(typedesc.lpValue); return GetStringFromTypeDesc(typeinfo, refdesc); } if ((VarEnum)typedesc.vt == VarEnum.VT_SAFEARRAY) { COM.TYPEDESC refdesc = ClrFacade.PtrToStructure<COM.TYPEDESC>(typedesc.lpValue); return "SAFEARRAY(" + GetStringFromTypeDesc(typeinfo, refdesc) + ")"; } if ((VarEnum)typedesc.vt == VarEnum.VT_USERDEFINED) { return GetStringFromCustomType(typeinfo, typedesc.lpValue); } switch ((VarEnum)typedesc.vt) { case VarEnum.VT_I1: return "char"; case VarEnum.VT_I2: return "short"; case VarEnum.VT_I4: case VarEnum.VT_INT: case VarEnum.VT_HRESULT: return "int"; case VarEnum.VT_I8: return "int64"; case VarEnum.VT_R4: return "float"; case VarEnum.VT_R8: return "double"; case VarEnum.VT_UI1: return "byte"; case VarEnum.VT_UI2: return "ushort"; case VarEnum.VT_UI4: case VarEnum.VT_UINT: return "uint"; case VarEnum.VT_UI8: return "uint64"; case VarEnum.VT_BSTR: case VarEnum.VT_LPSTR: case VarEnum.VT_LPWSTR: return "string"; case VarEnum.VT_DATE: return "Date"; case VarEnum.VT_BOOL: return "bool"; case VarEnum.VT_CY: return "currency"; case VarEnum.VT_DECIMAL: return "decimal"; case VarEnum.VT_CLSID: return "clsid"; case VarEnum.VT_DISPATCH: return "IDispatch"; case VarEnum.VT_UNKNOWN: return "IUnknown"; case VarEnum.VT_VARIANT: return "Variant"; case VarEnum.VT_VOID: return "void"; case VarEnum.VT_ARRAY: return "object[]"; case VarEnum.VT_EMPTY: return ""; default: return "Unknown!"; } }
/// <summary> /// Gets the name of the custom type defined in the type library /// </summary> /// <param name="typeinfo">ITypeInfo interface of the type</param> /// <param name="refptr">reference to the custom type</param> /// <returns>name of the custom type</returns> private static string GetStringFromCustomType(COM.ITypeInfo typeinfo, IntPtr refptr) { COM.ITypeInfo custtypeinfo; int reftype = unchecked((int)(long)refptr); // note that we cast to long first to prevent overflows; this cast is OK since we are only interested in the lower word typeinfo.GetRefTypeInfo(reftype, out custtypeinfo); if (custtypeinfo != null) { String strName, strDoc, strHelp; int id; custtypeinfo.GetDocumentation(-1, out strName, out strDoc, out id, out strHelp); return strName; } return "UnknownCustomtype"; }
public static extern bool GetProcessTimes(IntPtr processHandle, out ComType.FILETIME creationTime, out ComType.FILETIME exitTime, out ComType.FILETIME kernelTime, out ComType.FILETIME userTime);
void WIN32.IOleClientSite.GetMoniker(uint dwAssign, uint dwWhichMoniker, out COMTypes.IMoniker ppmk) { throw new NotImplementedException(); }
#pragma warning restore 618 /// <summary> /// Converts a FuncDesc out of GetFuncDesc into a MethodInformation /// </summary> private static ComMethodInformation GetMethodInformation(COM.FUNCDESC funcdesc, bool skipLastParameter) { Type returntype = GetTypeFromTypeDesc(funcdesc.elemdescFunc.tdesc); ParameterInformation[] parameters = GetParameterInformation(funcdesc, skipLastParameter); bool hasOptional = false; foreach (ParameterInformation p in parameters) { if (p.isOptional) { hasOptional = true; break; } } return new ComMethodInformation(false, hasOptional, parameters, returntype, funcdesc.memid, funcdesc.invkind); }
public void CopyTo(COMTypes.IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { throw new NotImplementedException(); }
/// <summary> /// Obtains the parameter information for a given FuncDesc /// </summary> internal static ParameterInformation[] GetParameterInformation(COM.FUNCDESC funcdesc, bool skipLastParameter) { int cParams = funcdesc.cParams; if (skipLastParameter) { Diagnostics.Assert(cParams > 0, "skipLastParameter is only true for property setters where there is at least one parameter"); cParams--; } ParameterInformation[] parameters = new ParameterInformation[cParams]; IntPtr ElementDescriptionArrayPtr = funcdesc.lprgelemdescParam; int ElementDescriptionSize = ClrFacade.SizeOf<COM.ELEMDESC>(); for (int i = 0; i < cParams; i++) { COM.ELEMDESC ElementDescription; int ElementDescriptionArrayByteOffset; IntPtr ElementDescriptionPointer; bool fOptional = false; ElementDescription = new COM.ELEMDESC(); ElementDescriptionArrayByteOffset = i * ElementDescriptionSize; //Disable PRefast warning for converting to int32 and converting back into intptr. //Code below takes into account 32 bit vs 64 bit conversions #pragma warning disable 56515 if (IntPtr.Size == 4) { ElementDescriptionPointer = (IntPtr)(ElementDescriptionArrayPtr.ToInt32() + ElementDescriptionArrayByteOffset); } else { ElementDescriptionPointer = (IntPtr)(ElementDescriptionArrayPtr.ToInt64() + ElementDescriptionArrayByteOffset); } #pragma warning enable 56515 ElementDescription = ClrFacade.PtrToStructure<COM.ELEMDESC>(ElementDescriptionPointer); //get the type of parameter Type type = ComUtil.GetTypeFromTypeDesc(ElementDescription.tdesc); Object defaultvalue = null; //check is this parameter is optional. if ((ElementDescription.desc.paramdesc.wParamFlags & COM.PARAMFLAG.PARAMFLAG_FOPT) != 0) { fOptional = true; defaultvalue = Type.Missing; } bool fByRef = (ElementDescription.desc.paramdesc.wParamFlags & COM.PARAMFLAG.PARAMFLAG_FOUT) != 0; parameters[i] = new ParameterInformation(type, fOptional, defaultvalue, fByRef); } return parameters; }
internal static string GetNameOfMethod(ComTypes.ITypeInfo typeInfo, int memid) { int cNames; string[] rgNames = new string[1]; typeInfo.GetNames(memid, rgNames, 1, out cNames); return rgNames[0]; }
/// <summary> /// Gets Method Signature from FuncDesc describing the method. /// </summary> /// <param name="typeinfo">ITypeInfo interface of the object</param> /// <param name="funcdesc">FuncDesc which defines the method</param> /// <param name="isPropertyPut">True if this is a property put; these properties take their return type from their first parameter</param> /// <returns>signature of the method</returns> internal static string GetMethodSignatureFromFuncDesc(COM.ITypeInfo typeinfo, COM.FUNCDESC funcdesc, bool isPropertyPut) { StringBuilder builder = new StringBuilder(); string name = GetNameFromFuncDesc(typeinfo, funcdesc); if (!isPropertyPut) { //First get the string for return type. string retstring = GetStringFromTypeDesc(typeinfo, funcdesc.elemdescFunc.tdesc); builder.Append(retstring + " "); } //Append the function name builder.Append(name); builder.Append(" ("); IntPtr ElementDescriptionArrayPtr = funcdesc.lprgelemdescParam; int ElementDescriptionSize = ClrFacade.SizeOf<COM.ELEMDESC>(); for (int i = 0; i < funcdesc.cParams; i++) { COM.ELEMDESC ElementDescription; int ElementDescriptionArrayByteOffset; IntPtr ElementDescriptionPointer; ElementDescription = new COM.ELEMDESC(); ElementDescriptionArrayByteOffset = i * ElementDescriptionSize; //Disable PRefast warning for converting to int32 and converting back into intptr. //Code below takes into account 32 bit vs 64 bit conversions #pragma warning disable 56515 if (IntPtr.Size == 4) { ElementDescriptionPointer = (IntPtr)(ElementDescriptionArrayPtr.ToInt32() + ElementDescriptionArrayByteOffset); } else { ElementDescriptionPointer = (IntPtr)(ElementDescriptionArrayPtr.ToInt64() + ElementDescriptionArrayByteOffset); } #pragma warning restore 56515 ElementDescription = ClrFacade.PtrToStructure<COM.ELEMDESC>(ElementDescriptionPointer); string paramstring = GetStringFromTypeDesc(typeinfo, ElementDescription.tdesc); if (i == 0 && isPropertyPut) // use the type of the first argument as the return type { builder.Insert(0, paramstring + " "); } else { builder.Append(paramstring); if (i < funcdesc.cParams - 1) { builder.Append(", "); } } } builder.Append(")"); return builder.ToString(); }
public static int IDispatchInvoke( IntPtr dispatchPointer, int memberDispId, ComTypes.INVOKEKIND flags, ref ComTypes.DISPPARAMS dispParams, out Variant result, out ExcepInfo excepInfo, out uint argErr ) { int hresult = _IDispatchInvoke( dispatchPointer, memberDispId, flags, ref dispParams, out result, out excepInfo, out argErr ); if (hresult == ComHresults.DISP_E_MEMBERNOTFOUND && (flags & ComTypes.INVOKEKIND.INVOKE_FUNC) != 0 && (flags & (ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT | ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF)) == 0) { // Re-invoke with no result argument to accomodate Word hresult = _IDispatchInvokeNoResult( dispatchPointer, memberDispId, ComTypes.INVOKEKIND.INVOKE_FUNC, ref dispParams, out result, out excepInfo, out argErr); } return hresult; }
/// <summary> /// Converts a MethodBase[] into a MethodInformation[] /// </summary> /// <returns>the ComMethodInformation[] corresponding to methods</returns> internal static ComMethodInformation[] GetMethodInformationArray(COM.ITypeInfo typeInfo, Collection<int> methods, bool skipLastParameters) { int methodCount = methods.Count; int count = 0; ComMethodInformation[] returnValue = new ComMethodInformation[methodCount]; foreach (int index in methods) { IntPtr pFuncDesc; typeInfo.GetFuncDesc(index, out pFuncDesc); COM.FUNCDESC funcdesc = ClrFacade.PtrToStructure<COM.FUNCDESC>(pFuncDesc); returnValue[count++] = ComUtil.GetMethodInformation(funcdesc, skipLastParameters); typeInfo.ReleaseFuncDesc(pFuncDesc); } return returnValue; }
private byte[] GetOleStream(IStorage storage, comTypes.STATSTG statstg) { comTypes.IStream pIStream; storage.OpenStream(statstg.pwcsName, IntPtr.Zero, (uint)(STGM.READ | STGM.SHARE_EXCLUSIVE), 0, out pIStream); byte[] data = new byte[statstg.cbSize]; pIStream.Read(data, (int)statstg.cbSize, IntPtr.Zero); Marshal.ReleaseComObject(pIStream); return data; }
private static void GetFuncDescForDescIndex(ComTypes.ITypeInfo typeInfo, int funcIndex, out ComTypes.FUNCDESC funcDesc, out IntPtr funcDescHandle) { IntPtr pFuncDesc = IntPtr.Zero; typeInfo.GetFuncDesc(funcIndex, out pFuncDesc); // GetFuncDesc should never return null, this is just to be safe if (pFuncDesc == IntPtr.Zero) { throw Error.CannotRetrieveTypeInformation(); } funcDesc = (ComTypes.FUNCDESC)Marshal.PtrToStructure(pFuncDesc, typeof(ComTypes.FUNCDESC)); funcDescHandle = pFuncDesc; }
/// <summary> /// Initializes new instance of ComMethod class. /// </summary> internal ComMethod(COM.ITypeInfo typeinfo, string name) { _typeInfo = typeinfo; Name = name; }
private static void ScanSourceInterface(ComTypes.ITypeInfo sourceTypeInfo, ref Dictionary<string, ComEventDesc> events) { ComTypes.TYPEATTR sourceTypeAttribute = ComRuntimeHelpers.GetTypeAttrForTypeInfo(sourceTypeInfo); for (int index = 0; index < sourceTypeAttribute.cFuncs; index++) { IntPtr funcDescHandleToRelease = IntPtr.Zero; try { ComTypes.FUNCDESC funcDesc; GetFuncDescForDescIndex(sourceTypeInfo, index, out funcDesc, out funcDescHandleToRelease); // we are not interested in hidden or restricted functions for now. if ((funcDesc.wFuncFlags & (int)ComTypes.FUNCFLAGS.FUNCFLAG_FHIDDEN) != 0) { continue; } if ((funcDesc.wFuncFlags & (int)ComTypes.FUNCFLAGS.FUNCFLAG_FRESTRICTED) != 0) { continue; } string name = ComRuntimeHelpers.GetNameOfMethod(sourceTypeInfo, funcDesc.memid); name = name.ToUpper(System.Globalization.CultureInfo.InvariantCulture); // Sometimes coclass has multiple source interfaces. Usually this is caused by // adding new events and putting them on new interfaces while keeping the // old interfaces around. This may cause name collisioning which we are // resolving by keeping only the first event with the same name. if (events.ContainsKey(name) == false) { ComEventDesc eventDesc = new ComEventDesc(); eventDesc.dispid = funcDesc.memid; eventDesc.sourceIID = sourceTypeAttribute.guid; events.Add(name, eventDesc); } } finally { if (funcDescHandleToRelease != IntPtr.Zero) { sourceTypeInfo.ReleaseFuncDesc(funcDescHandleToRelease); } } } }
internal static ComTypeLibDesc GetFromTypeLib(ComTypes.ITypeLib typeLib) { // check whether we have already loaded this type library ComTypes.TYPELIBATTR typeLibAttr = ComRuntimeHelpers.GetTypeAttrForTypeLib(typeLib); ComTypeLibDesc typeLibDesc; lock (_CachedTypeLibDesc) { if (_CachedTypeLibDesc.TryGetValue(typeLibAttr.guid, out typeLibDesc)) { return typeLibDesc; } } typeLibDesc = new ComTypeLibDesc(); typeLibDesc._typeLibName = ComRuntimeHelpers.GetNameOfLib(typeLib); typeLibDesc._typeLibAttributes = typeLibAttr; int countTypes = typeLib.GetTypeInfoCount(); for (int i = 0; i < countTypes; i++) { ComTypes.TYPEKIND typeKind; typeLib.GetTypeInfoType(i, out typeKind); ComTypes.ITypeInfo typeInfo; typeLib.GetTypeInfo(i, out typeInfo); if (typeKind == ComTypes.TYPEKIND.TKIND_COCLASS) { ComTypeClassDesc classDesc = new ComTypeClassDesc(typeInfo, typeLibDesc); typeLibDesc._classes.AddLast(classDesc); } else if (typeKind == ComTypes.TYPEKIND.TKIND_ENUM) { ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(typeInfo, typeLibDesc); typeLibDesc._enums.Add(enumDesc.TypeName, enumDesc); } else if (typeKind == ComTypes.TYPEKIND.TKIND_ALIAS) { ComTypes.TYPEATTR typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo); if (typeAttr.tdescAlias.vt == (short)VarEnum.VT_USERDEFINED) { string aliasName, documentation; ComRuntimeHelpers.GetInfoFromType(typeInfo, out aliasName, out documentation); ComTypes.ITypeInfo referencedTypeInfo; typeInfo.GetRefTypeInfo(typeAttr.tdescAlias.lpValue.ToInt32(), out referencedTypeInfo); ComTypes.TYPEATTR referencedTypeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(referencedTypeInfo); ComTypes.TYPEKIND referencedTypeKind = referencedTypeAttr.typekind; if (referencedTypeKind == ComTypes.TYPEKIND.TKIND_ENUM) { ComTypeEnumDesc enumDesc = new ComTypeEnumDesc(referencedTypeInfo, typeLibDesc); typeLibDesc._enums.Add(aliasName, enumDesc); } } } } // cached the typelib using the guid as the dictionary key lock (_CachedTypeLibDesc) { _CachedTypeLibDesc.Add(typeLibAttr.guid, typeLibDesc); } return typeLibDesc; }
private static ComTypes.ITypeInfo GetCoClassTypeInfo(object rcw, ComTypes.ITypeInfo typeInfo) { Debug.Assert(typeInfo != null); IProvideClassInfo provideClassInfo = rcw as IProvideClassInfo; if (provideClassInfo != null) { IntPtr typeInfoPtr = IntPtr.Zero; try { provideClassInfo.GetClassInfo(out typeInfoPtr); if (typeInfoPtr != IntPtr.Zero) { return Marshal.GetObjectForIUnknown(typeInfoPtr) as ComTypes.ITypeInfo; } } finally { if (typeInfoPtr != IntPtr.Zero) { Marshal.Release(typeInfoPtr); } } } // retrieving class information through IPCI has failed - // we can try scanning the typelib to find the coclass ComTypes.ITypeLib typeLib; int typeInfoIndex; typeInfo.GetContainingTypeLib(out typeLib, out typeInfoIndex); string typeName = ComRuntimeHelpers.GetNameOfType(typeInfo); ComTypeLibDesc typeLibDesc = ComTypeLibDesc.GetFromTypeLib(typeLib); ComTypeClassDesc coclassDesc = typeLibDesc.GetCoClassForInterface(typeName); if (coclassDesc == null) { return null; } ComTypes.ITypeInfo typeInfoCoClass; Guid coclassGuid = coclassDesc.Guid; typeLib.GetTypeInfoOfGuid(ref coclassGuid, out typeInfoCoClass); return typeInfoCoClass; }