Пример #1
1
 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;
 }
Пример #2
0
        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;
        }
Пример #3
0
        internal static string GetNameOfType(ComTypes.ITypeInfo typeInfo) {
            string name;
            string documentation;
            GetInfoFromType(typeInfo, out name, out documentation);

            return name;
        }
Пример #4
0
        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;
        }
Пример #5
0
        /// <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();
            }
        }
Пример #6
0
        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(); }
        }
Пример #7
0
        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;
        }
Пример #8
0
        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;
            }
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
 public void Stat(out COMTypes.STATSTG pstatstg, int grfStatFlag)
 {
     pstatstg = new COMTypes.STATSTG();
     pstatstg.cbSize = this.stm.Length;
 }
Пример #12
0
 //----------------------------------
 // IStream
 //----------------------------------
 public void Clone(out COMTypes.IStream ppstm)
 {
     throw new NotImplementedException();
 }
Пример #13
0
 /// <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);
 }
Пример #14
0
        // 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!";
            }
        }
Пример #15
0
        /// <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);
Пример #17
0
 void WIN32.IOleClientSite.GetMoniker(uint dwAssign, uint dwWhichMoniker, out COMTypes.IMoniker ppmk)
 {
     throw new NotImplementedException();
 }
Пример #18
0
#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);
        }
Пример #19
0
 public void CopyTo(COMTypes.IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten)
 {
     throw new NotImplementedException();
 }
Пример #20
0
        /// <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;
        }
Пример #21
0
 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];
 }
Пример #22
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();
        }
Пример #23
0
        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;
        }
Пример #24
0
        /// <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;
        }
Пример #25
0
        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;
        }
Пример #26
0
        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;
        }
Пример #27
0
 /// <summary>
 /// Initializes new instance of ComMethod class.
 /// </summary>
 internal ComMethod(COM.ITypeInfo typeinfo, string name)
 {
     _typeInfo = typeinfo;
     Name = name;
 }
Пример #28
0
        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);
                    }
                }
            }
        }
Пример #29
0
        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;
        }
Пример #30
0
        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;
        }