public static UnsafeNativeMethods.ITypeInfo[] FindTypeInfos(object obj, bool wantCoClass)
 {
     UnsafeNativeMethods.ITypeInfo[] infoArray = null;
     int pcti = 0;
     UnsafeNativeMethods.ITypeInfo pTypeInfo = null;
     if (obj is System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo)
     {
         System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo info2 = (System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo) obj;
         if (!System.Windows.Forms.NativeMethods.Succeeded(info2.GetMultiTypeInfoCount(ref pcti)) || (pcti == 0))
         {
             pcti = 0;
         }
         if (pcti > 0)
         {
             infoArray = new UnsafeNativeMethods.ITypeInfo[pcti];
             for (int i = 0; i < pcti; i++)
             {
                 if (!System.Windows.Forms.NativeMethods.Failed(info2.GetInfoOfIndex(i, 1, ref pTypeInfo, 0, 0, IntPtr.Zero, IntPtr.Zero)))
                 {
                     infoArray[i] = pTypeInfo;
                 }
             }
         }
     }
     if ((infoArray == null) || (infoArray.Length == 0))
     {
         pTypeInfo = FindTypeInfo(obj, wantCoClass);
         if (pTypeInfo != null)
         {
             infoArray = new UnsafeNativeMethods.ITypeInfo[] { pTypeInfo };
         }
     }
     return infoArray;
 }
コード例 #2
0
        internal string GetClassName(object component)
        {
            string pbstrClassName = null;

            if (((component is System.Windows.Forms.NativeMethods.IVsPerPropertyBrowsing) && System.Windows.Forms.NativeMethods.Succeeded(((System.Windows.Forms.NativeMethods.IVsPerPropertyBrowsing)component).GetClassName(ref pbstrClassName))) && (pbstrClassName != null))
            {
                return(pbstrClassName);
            }
            UnsafeNativeMethods.ITypeInfo info = Com2TypeInfoProcessor.FindTypeInfo(component, true);
            if ((info != null) && (info != null))
            {
                try
                {
                    info.GetDocumentation(-1, ref pbstrClassName, null, null, null);
                    while (((pbstrClassName != null) && (pbstrClassName.Length > 0)) && (pbstrClassName[0] == '_'))
                    {
                        pbstrClassName = pbstrClassName.Substring(1);
                    }
                    return(pbstrClassName);
                }
                catch
                {
                }
            }
            return("");
        }
コード例 #3
0
        /// <summary>
        ///  Given an Object, this attempts to locate its type ifo
        /// </summary>
        public static UnsafeNativeMethods.ITypeInfo FindTypeInfo(object obj, bool wantCoClass)
        {
            UnsafeNativeMethods.ITypeInfo pTypeInfo = null;

            // This is kind of odd.  What's going on here is that if we want the CoClass (e.g. for
            // the interface name), we need to look for IProvideClassInfo first, then look for the
            // typeinfo from the IDispatch. In the case of many OleAut32 operations, the CoClass
            // doesn't have the interface members on it, although in the shell it usually does, so
            // we need to re-order the lookup if we *actually* want the CoClass if it's available.

            for (int i = 0; pTypeInfo == null && i < 2; i++)
            {
                if (wantCoClass == (i == 0))
                {
                    if (obj is NativeMethods.IProvideClassInfo pProvideClassInfo)
                    {
                        pProvideClassInfo.GetClassInfo(out pTypeInfo);
                    }
                }
                else
                {
                    if (obj is UnsafeNativeMethods.IDispatch iDispatch)
                    {
                        iDispatch.GetTypeInfo(0, Kernel32.GetThreadLocale(), out pTypeInfo);
                    }
                }
            }

            return(pTypeInfo);
        }
コード例 #4
0
 public static UnsafeNativeMethods.ITypeInfo FindTypeInfo(object obj, bool wantCoClass)
 {
     UnsafeNativeMethods.ITypeInfo classInfo = null;
     for (int i = 0; (classInfo == null) && (i < 2); i++)
     {
         if (wantCoClass == (i == 0))
         {
             if (obj is System.Windows.Forms.NativeMethods.IProvideClassInfo)
             {
                 System.Windows.Forms.NativeMethods.IProvideClassInfo info2 = (System.Windows.Forms.NativeMethods.IProvideClassInfo)obj;
                 try
                 {
                     classInfo = info2.GetClassInfo();
                 }
                 catch
                 {
                 }
             }
         }
         else if (obj is UnsafeNativeMethods.IDispatch)
         {
             UnsafeNativeMethods.IDispatch dispatch = (UnsafeNativeMethods.IDispatch)obj;
             try
             {
                 classInfo = dispatch.GetTypeInfo(0, SafeNativeMethods.GetThreadLCID());
             }
             catch
             {
             }
         }
     }
     return(classInfo);
 }
コード例 #5
0
        public static UnsafeNativeMethods.ITypeInfo[] FindTypeInfos(object obj, bool wantCoClass)
        {
            UnsafeNativeMethods.ITypeInfo[] infoArray = null;
            int pcti = 0;

            UnsafeNativeMethods.ITypeInfo pTypeInfo = null;
            if (obj is System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo)
            {
                System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo info2 = (System.Windows.Forms.NativeMethods.IProvideMultipleClassInfo)obj;
                if (!System.Windows.Forms.NativeMethods.Succeeded(info2.GetMultiTypeInfoCount(ref pcti)) || (pcti == 0))
                {
                    pcti = 0;
                }
                if (pcti > 0)
                {
                    infoArray = new UnsafeNativeMethods.ITypeInfo[pcti];
                    for (int i = 0; i < pcti; i++)
                    {
                        if (!System.Windows.Forms.NativeMethods.Failed(info2.GetInfoOfIndex(i, 1, ref pTypeInfo, 0, 0, IntPtr.Zero, IntPtr.Zero)))
                        {
                            infoArray[i] = pTypeInfo;
                        }
                    }
                }
            }
            if ((infoArray == null) || (infoArray.Length == 0))
            {
                pTypeInfo = FindTypeInfo(obj, wantCoClass);
                if (pTypeInfo != null)
                {
                    infoArray = new UnsafeNativeMethods.ITypeInfo[] { pTypeInfo };
                }
            }
            return(infoArray);
        }
コード例 #6
0
        private unsafe long GetTypeInfoVersion(UnsafeNativeMethods.ITypeInfo pTypeInfo)
        {
            long   num3;
            IntPtr zero = IntPtr.Zero;

            if (!System.Windows.Forms.NativeMethods.Succeeded(pTypeInfo.GetTypeAttr(ref zero)))
            {
                return(0L);
            }
            try
            {
                System.Runtime.InteropServices.ComTypes.TYPEATTR typeattr;
                try
                {
                    typeattr = *((System.Runtime.InteropServices.ComTypes.TYPEATTR *)zero);
                }
                catch
                {
                    return(0L);
                }
                long  num2    = 0L;
                int * numPtr  = (int *)&num2;
                byte *numPtr2 = (byte *)&typeattr;
                numPtr[0] = *((int *)(numPtr2 + CountMemberOffset));
                numPtr++;
                numPtr[0] = *((int *)(numPtr2 + VersionOffset));
                num3      = num2;
            }
            finally
            {
                pTypeInfo.ReleaseTypeAttr(zero);
            }
            return(num3);
        }
コード例 #7
0
        private unsafe long GetTypeInfoVersion(UnsafeNativeMethods.ITypeInfo pTypeInfo)
        {
            IntPtr  pTypeAttr = IntPtr.Zero;
            HRESULT hr        = pTypeInfo.GetTypeAttr(ref pTypeAttr);

            if (!hr.Succeeded())
            {
                return(0);
            }

            Runtime.InteropServices.ComTypes.TYPEATTR pTAStruct;
            try
            {
                try
                {
                    // just access directly...no marshalling needed!
                    //
                    pTAStruct = *(Runtime.InteropServices.ComTypes.TYPEATTR *)pTypeAttr;
                }
                catch
                {
                    return(0);
                }

                long result = 0;

                // we pull two things out of the struct: the
                // number of functions and variables, and the version.
                // since they are next to each other, we just pull the memory directly.
                //
                // the cFuncs and cVars are both shorts, so we read them as one block of ints.
                //
                //
                int * pResult  = (int *)&result;
                byte *pbStruct = (byte *)&pTAStruct;

                // in the low byte, pull the number of props.
                //
                *pResult = *(int *)(pbStruct + CountMemberOffset);

                // move up to the high word of the long.
                //
                pResult++;

                // now pull out the version info.
                //
                *pResult = *(int *)(pbStruct + VersionOffset);

                // return that composite long.
                //
                return(result);
            }
            finally
            {
                pTypeInfo.ReleaseTypeAttr(pTypeAttr);
            }
        }
コード例 #8
0
        private static Guid GetGuidForTypeInfo(UnsafeNativeMethods.ITypeInfo typeInfo, int[] versions)
        {
            IntPtr pTypeAttr = IntPtr.Zero;
            int    hr        = typeInfo.GetTypeAttr(ref pTypeAttr);

            if (!NativeMethods.Succeeded(hr))
            {
                throw new ExternalException(string.Format(SR.TYPEINFOPROCESSORGetTypeAttrFailed, hr), hr);
            }

            try {
                ref readonly NativeMethods.tagTYPEATTR typeAttr = ref UnsafeNativeMethods.PtrToRef <NativeMethods.tagTYPEATTR>(pTypeAttr);
コード例 #9
0
        private static void ProcessVariables(UnsafeNativeMethods.ITypeInfo typeInfo, IDictionary propInfoList, int dispidToGet, int nameDispID, StructCache structCache)
        {
            IntPtr zero     = IntPtr.Zero;
            int    typeAttr = typeInfo.GetTypeAttr(ref zero);

            if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr) || (zero == IntPtr.Zero))
            {
                throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr);
            }
            System.Windows.Forms.NativeMethods.tagTYPEATTR data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR));
            UnsafeNativeMethods.PtrToStructure(zero, data);
            try
            {
                if (data != null)
                {
                    System.Windows.Forms.NativeMethods.tagVARDESC gvardesc = (System.Windows.Forms.NativeMethods.tagVARDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagVARDESC));
                    for (int i = 0; i < data.cVars; i++)
                    {
                        IntPtr pVarDesc = IntPtr.Zero;
                        if (System.Windows.Forms.NativeMethods.Succeeded(typeInfo.GetVarDesc(i, ref pVarDesc)) && (pVarDesc != IntPtr.Zero))
                        {
                            UnsafeNativeMethods.PtrToStructure(pVarDesc, gvardesc);
                            try
                            {
                                if ((gvardesc.varkind != 2) && ((dispidToGet == -1) || (gvardesc.memid == dispidToGet)))
                                {
                                    PropInfo info = ProcessDataCore(typeInfo, propInfoList, gvardesc.memid, nameDispID, gvardesc.elemdescVar.tdesc, gvardesc.wVarFlags, structCache);
                                    if (info.ReadOnly != 1)
                                    {
                                        info.ReadOnly = 2;
                                    }
                                }
                            }
                            finally
                            {
                                if (pVarDesc != IntPtr.Zero)
                                {
                                    typeInfo.ReleaseVarDesc(pVarDesc);
                                }
                            }
                        }
                    }
                    structCache.ReleaseStruct(gvardesc);
                }
            }
            finally
            {
                typeInfo.ReleaseTypeAttr(zero);
                structCache.ReleaseStruct(data);
            }
        }
コード例 #10
0
        /// <summary>
        /// Given an Object, this attempts to locate its type ifo
        /// </summary>
        public static UnsafeNativeMethods.ITypeInfo FindTypeInfo(object obj, bool wantCoClass)
        {
            UnsafeNativeMethods.ITypeInfo pTypeInfo = null;

            // this is kind of odd.  What's going on here is that
            // if we want the CoClass (e.g. for the interface name),
            // we need to look for IProvideClassInfo first, then
            // look for the typeinfo from the IDispatch.
            // In the case of many OleAut32 operations, the CoClass
            // doesn't have the interface members on it, although
            // in the shell it usually does, so
            // we need to re-order the lookup if we _actually_ want
            // the CoClass if it's available.
            //

            for (int i = 0; pTypeInfo == null && i < 2; i++)
            {
                if (wantCoClass == (i == 0))
                {
                    if (obj is NativeMethods.IProvideClassInfo pProvideClassInfo)
                    {
                        try
                        {
                            pTypeInfo = pProvideClassInfo.GetClassInfo();
                        }
                        catch
                        {
                        }
                    }
                }
                else
                {
                    if (obj is UnsafeNativeMethods.IDispatch iDispatch)
                    {
                        try
                        {
                            pTypeInfo = iDispatch.GetTypeInfo(0, SafeNativeMethods.GetThreadLCID());
                        }
                        catch
                        {
                        }
                    }
                }
            }
            return(pTypeInfo);
        }
コード例 #11
0
        internal string GetClassName(object component)
        {
            string name = null;

            // does IVsPerPropretyBrowsing supply us a name?
            if (component is NativeMethods.IVsPerPropertyBrowsing)
            {
                int hr = ((NativeMethods.IVsPerPropertyBrowsing)component).GetClassName(ref name);
                if (NativeMethods.Succeeded(hr) && name != null)
                {
                    return(name);
                }
                // otherwise fall through...
            }

            UnsafeNativeMethods.ITypeInfo pTypeInfo = Com2TypeInfoProcessor.FindTypeInfo(component, true);

            if (pTypeInfo == null)
            {
                //Debug.Fail("The current component failed to return an ITypeInfo");
                return("");
            }

            if (pTypeInfo != null)
            {
                string desc = null;
                try
                {
                    pTypeInfo.GetDocumentation(NativeMethods.MEMBERID_NIL, ref name, ref desc, null, null);

                    // strip the leading underscores
                    while (name != null && name.Length > 0 && name[0] == '_')
                    {
                        name = name.Substring(1);
                    }
                    return(name);
                }
                catch
                {
                }
            }
            return("");
        }
コード例 #12
0
        /// <include file='doc\COM2TypeInfoProcessor.uex' path='docs/doc[@for="Com2TypeInfoProcessor.FindTypeInfos"]/*' />
        /// <devdoc>
        /// Given an Object, this attempts to locate its type info. If it implementes IProvideMultipleClassInfo
        /// all available type infos will be returned, otherwise the primary one will be alled.
        /// </devdoc>
        public static UnsafeNativeMethods.ITypeInfo[] FindTypeInfos(object obj, bool wantCoClass)
        {
            UnsafeNativeMethods.ITypeInfo[] typeInfos = null;
            int n = 0;

            UnsafeNativeMethods.ITypeInfo temp = null;

            if (obj is NativeMethods.IProvideMultipleClassInfo)
            {
                NativeMethods.IProvideMultipleClassInfo pCI = (NativeMethods.IProvideMultipleClassInfo)obj;
                if (!NativeMethods.Succeeded(pCI.GetMultiTypeInfoCount(ref n)) || n == 0)
                {
                    n = 0;
                }

                if (n > 0)
                {
                    typeInfos = new UnsafeNativeMethods.ITypeInfo[n];

                    for (int i = 0; i < n; i++)
                    {
                        if (NativeMethods.Failed(pCI.GetInfoOfIndex(i, 1 /*MULTICLASSINFO_GETTYPEINFO*/, ref temp, 0, 0, IntPtr.Zero, IntPtr.Zero)))
                        {
                            continue;
                        }
                        Debug.Assert(temp != null, "IProvideMultipleClassInfo::GetInfoOfIndex returned S_OK for ITypeInfo index " + i + ", this is a issue in the object that's being browsed, NOT the property browser.");
                        typeInfos[i] = temp;
                    }
                }
            }

            if (typeInfos == null || typeInfos.Length == 0)
            {
                temp = FindTypeInfo(obj, wantCoClass);
                if (temp != null)
                {
                    typeInfos = new UnsafeNativeMethods.ITypeInfo[] { temp };
                }
            }

            return(typeInfos);
        }
コード例 #13
0
        private static Guid GetGuidForTypeInfo(UnsafeNativeMethods.ITypeInfo typeInfo, StructCache structCache, int[] versions)
        {
            IntPtr zero     = IntPtr.Zero;
            int    typeAttr = typeInfo.GetTypeAttr(ref zero);

            if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr))
            {
                throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr);
            }
            Guid empty = Guid.Empty;

            System.Windows.Forms.NativeMethods.tagTYPEATTR data = null;
            try
            {
                if (structCache == null)
                {
                    data = new System.Windows.Forms.NativeMethods.tagTYPEATTR();
                }
                else
                {
                    data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR));
                }
                UnsafeNativeMethods.PtrToStructure(zero, data);
                empty = data.guid;
                if (versions != null)
                {
                    versions[0] = data.wMajorVerNum;
                    versions[1] = data.wMinorVerNum;
                }
            }
            finally
            {
                typeInfo.ReleaseTypeAttr(zero);
                if ((structCache != null) && (data != null))
                {
                    structCache.ReleaseStruct(data);
                }
            }
            return(empty);
        }
コード例 #14
0
        public static Com2Properties GetProperties(object obj)
        {
            if ((obj == null) || !Marshal.IsComObject(obj))
            {
                return(null);
            }
            UnsafeNativeMethods.ITypeInfo[] infoArray = FindTypeInfos(obj, false);
            if ((infoArray == null) || (infoArray.Length == 0))
            {
                return(null);
            }
            int       defaultIndex = -1;
            int       num2         = -1;
            ArrayList list         = new ArrayList();

            for (int i = 0; i < infoArray.Length; i++)
            {
                UnsafeNativeMethods.ITypeInfo typeInfo = infoArray[i];
                if (typeInfo != null)
                {
                    int[] versions             = new int[2];
                    Guid  key                  = GetGuidForTypeInfo(typeInfo, null, versions);
                    PropertyDescriptor[] props = null;
                    bool flag                  = ((key != Guid.Empty) && (processedLibraries != null)) && processedLibraries.Contains(key);
                    if (flag)
                    {
                        CachedProperties properties = (CachedProperties)processedLibraries[key];
                        if ((versions[0] == properties.MajorVersion) && (versions[1] == properties.MinorVersion))
                        {
                            props = properties.Properties;
                            if ((i == 0) && (properties.DefaultIndex != -1))
                            {
                                defaultIndex = properties.DefaultIndex;
                            }
                        }
                        else
                        {
                            flag = false;
                        }
                    }
                    if (!flag)
                    {
                        props = InternalGetProperties(obj, typeInfo, -1, ref num2);
                        if ((i == 0) && (num2 != -1))
                        {
                            defaultIndex = num2;
                        }
                        if (processedLibraries == null)
                        {
                            processedLibraries = new Hashtable();
                        }
                        if (key != Guid.Empty)
                        {
                            processedLibraries[key] = new CachedProperties(props, (i == 0) ? defaultIndex : -1, versions[0], versions[1]);
                        }
                    }
                    if (props != null)
                    {
                        list.AddRange(props);
                    }
                }
            }
            Com2PropertyDescriptor[] array = new Com2PropertyDescriptor[list.Count];
            list.CopyTo(array, 0);
            return(new Com2Properties(obj, array, defaultIndex));
        }
コード例 #15
0
        private static System.Type GetValueTypeFromTypeDesc(System.Windows.Forms.NativeMethods.tagTYPEDESC typeDesc, UnsafeNativeMethods.ITypeInfo typeInfo, object[] typeData, StructCache structCache)
        {
            IntPtr unionMember;
            int    hr = 0;

            switch (((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt))
            {
            case System.Windows.Forms.NativeMethods.tagVT.VT_DISPATCH:
            case System.Windows.Forms.NativeMethods.tagVT.VT_UNKNOWN:
                typeData[0] = GetGuidForTypeInfo(typeInfo, structCache, null);
                return(VTToType((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt));

            case System.Windows.Forms.NativeMethods.tagVT.VT_PTR:
            {
                System.Windows.Forms.NativeMethods.tagTYPEDESC data = (System.Windows.Forms.NativeMethods.tagTYPEDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEDESC));
                try
                {
                    try
                    {
                        UnsafeNativeMethods.PtrToStructure(typeDesc.unionMember, data);
                    }
                    catch
                    {
                        data = new System.Windows.Forms.NativeMethods.tagTYPEDESC {
                            unionMember = (IntPtr)Marshal.ReadInt32(typeDesc.unionMember),
                            vt          = Marshal.ReadInt16(typeDesc.unionMember, 4)
                        };
                    }
                    if (data.vt == 12)
                    {
                        return(VTToType((System.Windows.Forms.NativeMethods.tagVT)data.vt));
                    }
                    unionMember = data.unionMember;
                }
                finally
                {
                    structCache.ReleaseStruct(data);
                }
                break;
            }

            case System.Windows.Forms.NativeMethods.tagVT.VT_USERDEFINED:
                unionMember = typeDesc.unionMember;
                break;

            default:
                return(VTToType((System.Windows.Forms.NativeMethods.tagVT)typeDesc.vt));
            }
            UnsafeNativeMethods.ITypeInfo pTypeInfo = null;
            hr = typeInfo.GetRefTypeInfo(unionMember, ref pTypeInfo);
            if (!System.Windows.Forms.NativeMethods.Succeeded(hr))
            {
                throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetRefTypeInfoFailed", new object[] { hr }), hr);
            }
            try
            {
                if (pTypeInfo != null)
                {
                    IntPtr zero = IntPtr.Zero;
                    hr = pTypeInfo.GetTypeAttr(ref zero);
                    if (!System.Windows.Forms.NativeMethods.Succeeded(hr))
                    {
                        throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { hr }), hr);
                    }
                    System.Windows.Forms.NativeMethods.tagTYPEATTR gtypeattr = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR));
                    UnsafeNativeMethods.PtrToStructure(zero, gtypeattr);
                    try
                    {
                        Guid g = gtypeattr.guid;
                        if (!Guid.Empty.Equals(g))
                        {
                            typeData[0] = g;
                        }
                        switch (gtypeattr.typekind)
                        {
                        case 0:
                            return(ProcessTypeInfoEnum(pTypeInfo, structCache));

                        case 3:
                        case 5:
                            return(VTToType(System.Windows.Forms.NativeMethods.tagVT.VT_UNKNOWN));

                        case 4:
                            return(VTToType(System.Windows.Forms.NativeMethods.tagVT.VT_DISPATCH));

                        case 6:
                            return(GetValueTypeFromTypeDesc(gtypeattr.Get_tdescAlias(), pTypeInfo, typeData, structCache));
                        }
                        return(null);
                    }
                    finally
                    {
                        pTypeInfo.ReleaseTypeAttr(zero);
                        structCache.ReleaseStruct(gtypeattr);
                    }
                }
            }
            finally
            {
                pTypeInfo = null;
            }
            return(null);
        }
コード例 #16
0
        /// <summary>
        ///  Gets the properties for a given Com2 Object.  The returned Com2Properties
        ///  Object contains the properties and relevant data about them.
        /// </summary>
        public static Com2Properties GetProperties(object obj)
        {
            Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties");

            if (obj == null || !Marshal.IsComObject(obj))
            {
                Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties returning null: Object is not a com Object");
                return(null);
            }

            UnsafeNativeMethods.ITypeInfo[] typeInfos = FindTypeInfos(obj, false);

            // oops, looks like this guy doesn't surface any type info
            // this is okay, so we just say it has no props
            if (typeInfos == null || typeInfos.Length == 0)
            {
                Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties :: Didn't get typeinfo");
                return(null);
            }

            int       defaultProp = -1;
            int       temp        = -1;
            ArrayList propList    = new ArrayList();

            Guid[] typeGuids = new Guid[typeInfos.Length];

            for (int i = 0; i < typeInfos.Length; i++)
            {
                UnsafeNativeMethods.ITypeInfo ti = typeInfos[i];

                if (ti == null)
                {
                    continue;
                }

                int[] versions             = new int[2];
                Guid  typeGuid             = GetGuidForTypeInfo(ti, versions);
                PropertyDescriptor[] props = null;
                bool dontProcess           = typeGuid != Guid.Empty && processedLibraries != null && processedLibraries.Contains(typeGuid);

                if (dontProcess)
                {
                    CachedProperties cp = (CachedProperties)processedLibraries[typeGuid];

                    if (versions[0] == cp.MajorVersion && versions[1] == cp.MinorVersion)
                    {
                        props = cp.Properties;
                        if (i == 0 && cp.DefaultIndex != -1)
                        {
                            defaultProp = cp.DefaultIndex;
                        }
                    }
                    else
                    {
                        dontProcess = false;
                    }
                }

                if (!dontProcess)
                {
                    props = InternalGetProperties(obj, ti, Ole32.DispatchID.MEMBERID_NIL, ref temp);

                    // only save the default property from the first type Info
                    if (i == 0 && temp != -1)
                    {
                        defaultProp = temp;
                    }

                    if (processedLibraries == null)
                    {
                        processedLibraries = new Hashtable();
                    }

                    if (typeGuid != Guid.Empty)
                    {
                        processedLibraries[typeGuid] = new CachedProperties(props, i == 0 ? defaultProp : -1, versions[0], versions[1]);
                    }
                }

                if (props != null)
                {
                    propList.AddRange(props);
                }
            }

            Debug.WriteLineIf(DbgTypeInfoProcessorSwitch.TraceVerbose, "Com2TypeInfoProcessor.GetProperties : returning " + propList.Count.ToString(CultureInfo.InvariantCulture) + " properties");

            // done!
            Com2PropertyDescriptor[] temp2 = new Com2PropertyDescriptor[propList.Count];
            propList.CopyTo(temp2, 0);

            return(new Com2Properties(obj, temp2, defaultProp));
        }
コード例 #17
0
        private static PropertyDescriptor[] InternalGetProperties(object obj, UnsafeNativeMethods.ITypeInfo typeInfo, int dispidToGet, ref int defaultIndex)
        {
            if (typeInfo == null)
            {
                return(null);
            }
            Hashtable   propInfoList = new Hashtable();
            int         nameDispId   = GetNameDispId((UnsafeNativeMethods.IDispatch)obj);
            bool        addAboutBox  = false;
            StructCache structCache  = new StructCache();

            try
            {
                ProcessFunctions(typeInfo, propInfoList, dispidToGet, nameDispId, ref addAboutBox, structCache);
            }
            catch (ExternalException)
            {
            }
            try
            {
                ProcessVariables(typeInfo, propInfoList, dispidToGet, nameDispId, structCache);
            }
            catch (ExternalException)
            {
            }
            typeInfo = null;
            int count = propInfoList.Count;

            if (addAboutBox)
            {
                count++;
            }
            PropertyDescriptor[] descriptorArray = new PropertyDescriptor[count];
            int hr = 0;

            object[]            retval   = new object[1];
            ComNativeDescriptor instance = ComNativeDescriptor.Instance;

            foreach (PropInfo info in propInfoList.Values)
            {
                if (!info.NonBrowsable)
                {
                    try
                    {
                        hr = instance.GetPropertyValue(obj, info.DispId, retval);
                    }
                    catch (ExternalException exception)
                    {
                        hr = exception.ErrorCode;
                    }
                    if (!System.Windows.Forms.NativeMethods.Succeeded(hr))
                    {
                        info.Attributes.Add(new BrowsableAttribute(false));
                        info.NonBrowsable = true;
                    }
                }
                else
                {
                    hr = 0;
                }
                Attribute[] array = new Attribute[info.Attributes.Count];
                info.Attributes.CopyTo(array, 0);
                descriptorArray[info.Index] = new Com2PropertyDescriptor(info.DispId, info.Name, array, info.ReadOnly != 2, info.ValueType, info.TypeData, !System.Windows.Forms.NativeMethods.Succeeded(hr));
                if (info.IsDefault)
                {
                    int index = info.Index;
                }
            }
            if (addAboutBox)
            {
                descriptorArray[descriptorArray.Length - 1] = new Com2AboutBoxPropertyDescriptor();
            }
            return(descriptorArray);
        }
コード例 #18
0
        private static PropInfo ProcessDataCore(UnsafeNativeMethods.ITypeInfo typeInfo, IDictionary propInfoList, int dispid, int nameDispID, System.Windows.Forms.NativeMethods.tagTYPEDESC typeDesc, int flags, StructCache structCache)
        {
            string pBstrName             = null;
            string pBstrDocString        = null;
            int    hr                    = typeInfo.GetDocumentation(dispid, ref pBstrName, ref pBstrDocString, null, null);
            ComNativeDescriptor instance = ComNativeDescriptor.Instance;

            if (!System.Windows.Forms.NativeMethods.Succeeded(hr))
            {
                throw new COMException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetDocumentationFailed", new object[] { dispid, hr, instance.GetClassName(typeInfo) }), hr);
            }
            if (pBstrName == null)
            {
                return(null);
            }
            PropInfo info = (PropInfo)propInfoList[pBstrName];

            if (info == null)
            {
                info = new PropInfo {
                    Index = propInfoList.Count
                };
                propInfoList[pBstrName] = info;
                info.Name   = pBstrName;
                info.DispId = dispid;
                info.Attributes.Add(new DispIdAttribute(info.DispId));
            }
            if (pBstrDocString != null)
            {
                info.Attributes.Add(new DescriptionAttribute(pBstrDocString));
            }
            if (info.ValueType == null)
            {
                object[] typeData = new object[1];
                try
                {
                    info.ValueType = GetValueTypeFromTypeDesc(typeDesc, typeInfo, typeData, structCache);
                }
                catch (Exception)
                {
                }
                if (info.ValueType == null)
                {
                    info.NonBrowsable = true;
                }
                if (info.NonBrowsable)
                {
                    flags |= 0x400;
                }
                if (typeData[0] != null)
                {
                    info.TypeData = typeData[0];
                }
            }
            if ((flags & 1) != 0)
            {
                info.ReadOnly = 1;
            }
            if ((((flags & 0x40) != 0) || ((flags & 0x400) != 0)) || ((info.Name[0] == '_') || (dispid == -515)))
            {
                info.Attributes.Add(new BrowsableAttribute(false));
                info.NonBrowsable = true;
            }
            if ((flags & 0x200) != 0)
            {
                info.IsDefault = true;
            }
            if (((flags & 4) != 0) && ((flags & 0x10) != 0))
            {
                info.Attributes.Add(new BindableAttribute(true));
            }
            if (dispid == nameDispID)
            {
                info.Attributes.Add(new ParenthesizePropertyNameAttribute(true));
                info.Attributes.Add(new MergablePropertyAttribute(false));
            }
            return(info);
        }
コード例 #19
0
        private static void ProcessFunctions(UnsafeNativeMethods.ITypeInfo typeInfo, IDictionary propInfoList, int dispidToGet, int nameDispID, ref bool addAboutBox, StructCache structCache)
        {
            IntPtr zero     = IntPtr.Zero;
            int    typeAttr = typeInfo.GetTypeAttr(ref zero);

            if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr) || (zero == IntPtr.Zero))
            {
                throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr);
            }
            System.Windows.Forms.NativeMethods.tagTYPEATTR data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR));
            UnsafeNativeMethods.PtrToStructure(zero, data);
            try
            {
                if (data != null)
                {
                    System.Windows.Forms.NativeMethods.tagFUNCDESC gfuncdesc = (System.Windows.Forms.NativeMethods.tagFUNCDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagFUNCDESC));
                    System.Windows.Forms.NativeMethods.tagELEMDESC structure = (System.Windows.Forms.NativeMethods.tagELEMDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagELEMDESC));
                    for (int i = 0; i < data.cFuncs; i++)
                    {
                        IntPtr pFuncDesc = IntPtr.Zero;
                        if (System.Windows.Forms.NativeMethods.Succeeded(typeInfo.GetFuncDesc(i, ref pFuncDesc)) && (pFuncDesc != IntPtr.Zero))
                        {
                            UnsafeNativeMethods.PtrToStructure(pFuncDesc, gfuncdesc);
                            try
                            {
                                if ((gfuncdesc.invkind == 1) || ((dispidToGet != -1) && (gfuncdesc.memid != dispidToGet)))
                                {
                                    if (gfuncdesc.memid == -552)
                                    {
                                        addAboutBox = true;
                                    }
                                }
                                else
                                {
                                    System.Windows.Forms.NativeMethods.tagTYPEDESC tdesc;
                                    bool flag = gfuncdesc.invkind == 2;
                                    if (flag)
                                    {
                                        if (gfuncdesc.cParams != 0)
                                        {
                                            continue;
                                        }
                                        tdesc = gfuncdesc.elemdescFunc.tdesc;
                                    }
                                    else
                                    {
                                        if ((gfuncdesc.lprgelemdescParam == IntPtr.Zero) || (gfuncdesc.cParams != 1))
                                        {
                                            continue;
                                        }
                                        Marshal.PtrToStructure(gfuncdesc.lprgelemdescParam, structure);
                                        tdesc = structure.tdesc;
                                    }
                                    PropInfo info = ProcessDataCore(typeInfo, propInfoList, gfuncdesc.memid, nameDispID, tdesc, gfuncdesc.wFuncFlags, structCache);
                                    if ((info != null) && !flag)
                                    {
                                        info.ReadOnly = 2;
                                    }
                                }
                            }
                            finally
                            {
                                typeInfo.ReleaseFuncDesc(pFuncDesc);
                            }
                        }
                    }
                    structCache.ReleaseStruct(gfuncdesc);
                    structCache.ReleaseStruct(structure);
                }
            }
            finally
            {
                typeInfo.ReleaseTypeAttr(zero);
                structCache.ReleaseStruct(data);
            }
        }
コード例 #20
0
 private static System.Type ProcessTypeInfoEnum(UnsafeNativeMethods.ITypeInfo enumTypeInfo, StructCache structCache)
 {
     if (enumTypeInfo != null)
     {
         try
         {
             IntPtr zero     = IntPtr.Zero;
             int    typeAttr = enumTypeInfo.GetTypeAttr(ref zero);
             if (!System.Windows.Forms.NativeMethods.Succeeded(typeAttr) || (zero == IntPtr.Zero))
             {
                 throw new ExternalException(System.Windows.Forms.SR.GetString("TYPEINFOPROCESSORGetTypeAttrFailed", new object[] { typeAttr }), typeAttr);
             }
             System.Windows.Forms.NativeMethods.tagTYPEATTR data = (System.Windows.Forms.NativeMethods.tagTYPEATTR)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagTYPEATTR));
             UnsafeNativeMethods.PtrToStructure(zero, data);
             if (zero == IntPtr.Zero)
             {
                 return(null);
             }
             try
             {
                 int       cVars = data.cVars;
                 ArrayList list  = new ArrayList();
                 ArrayList list2 = new ArrayList();
                 System.Windows.Forms.NativeMethods.tagVARDESC gvardesc = (System.Windows.Forms.NativeMethods.tagVARDESC)structCache.GetStruct(typeof(System.Windows.Forms.NativeMethods.tagVARDESC));
                 object objectForNativeVariant = null;
                 string pBstrName      = null;
                 string pBstrDocString = null;
                 enumTypeInfo.GetDocumentation(-1, ref pBstrName, ref pBstrDocString, null, null);
                 for (int i = 0; i < cVars; i++)
                 {
                     IntPtr pVarDesc = IntPtr.Zero;
                     if (System.Windows.Forms.NativeMethods.Succeeded(enumTypeInfo.GetVarDesc(i, ref pVarDesc)) && (pVarDesc != IntPtr.Zero))
                     {
                         try
                         {
                             UnsafeNativeMethods.PtrToStructure(pVarDesc, gvardesc);
                             if (((gvardesc != null) && (gvardesc.varkind == 2)) && (gvardesc.unionMember != IntPtr.Zero))
                             {
                                 str2 = (string)(pBstrDocString = null);
                                 objectForNativeVariant = null;
                                 if (System.Windows.Forms.NativeMethods.Succeeded(enumTypeInfo.GetDocumentation(gvardesc.memid, null, ref pBstrDocString, null, null)))
                                 {
                                     string str4;
                                     try
                                     {
                                         objectForNativeVariant = Marshal.GetObjectForNativeVariant(gvardesc.unionMember);
                                     }
                                     catch (Exception)
                                     {
                                     }
                                     list2.Add(objectForNativeVariant);
                                     if (pBstrDocString != null)
                                     {
                                         str4 = pBstrDocString;
                                     }
                                     else
                                     {
                                         str4 = str2;
                                     }
                                     list.Add(str4);
                                 }
                             }
                         }
                         finally
                         {
                             if (pVarDesc != IntPtr.Zero)
                             {
                                 enumTypeInfo.ReleaseVarDesc(pVarDesc);
                             }
                         }
                     }
                 }
                 structCache.ReleaseStruct(gvardesc);
                 if (list.Count > 0)
                 {
                     IntPtr iUnknownForObject = Marshal.GetIUnknownForObject(enumTypeInfo);
                     try
                     {
                         pBstrName = iUnknownForObject.ToString() + "_" + pBstrName;
                         if (builtEnums == null)
                         {
                             builtEnums = new Hashtable();
                         }
                         else if (builtEnums.ContainsKey(pBstrName))
                         {
                             return((System.Type)builtEnums[pBstrName]);
                         }
                         System.Type underlyingType = typeof(int);
                         if ((list2.Count > 0) && (list2[0] != null))
                         {
                             underlyingType = list2[0].GetType();
                         }
                         EnumBuilder builder = ModuleBuilder.DefineEnum(pBstrName, TypeAttributes.Public, underlyingType);
                         for (int j = 0; j < list.Count; j++)
                         {
                             builder.DefineLiteral((string)list[j], list2[j]);
                         }
                         System.Type type2 = builder.CreateType();
                         builtEnums[pBstrName] = type2;
                         return(type2);
                     }
                     finally
                     {
                         if (iUnknownForObject != IntPtr.Zero)
                         {
                             Marshal.Release(iUnknownForObject);
                         }
                     }
                 }
             }
             finally
             {
                 enumTypeInfo.ReleaseTypeAttr(zero);
                 structCache.ReleaseStruct(data);
             }
         }
         catch
         {
         }
     }
     return(null);
 }