object FetchVariants(IntPtr baseArray, int index, Type type)
        {
            if (baseArray == IntPtr.Zero)
            {
                Fx.Assert("baseArray should not be null");

                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseArrray");
            }
            uint displacement = (uint)(index * Marshal.SizeOf(typeof(TagVariant)));

            TagVariant varBase = (TagVariant)Marshal.PtrToStructure(GetDisp(baseArray, displacement), typeof(TagVariant));

            if ((varBase.vt & (ushort)(VarEnum.VT_VARIANT | VarEnum.VT_BYREF)) == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyVariantAllowedByRef), HR.DISP_E_TYPEMISMATCH));
            }
            TagVariant varActualVariant = (TagVariant)Marshal.PtrToStructure(varBase.ptr, typeof(TagVariant));

            if ((varActualVariant.vt & (ushort)(VarEnum.VT_VARIANT | VarEnum.VT_BYREF | VarEnum.VT_ARRAY)) == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyByRefVariantSafeArraysAllowed), HR.DISP_E_TYPEMISMATCH));
            }

            IntPtr ppArray    = varActualVariant.ptr;
            IntPtr pSafeArray = (IntPtr)Marshal.PtrToStructure(ppArray, typeof(IntPtr));

            int dimensionsOfSafeArray = SafeNativeMethods.SafeArrayGetDim(pSafeArray);

            if (dimensionsOfSafeArray != 1)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyOneDimensionalSafeArraysAllowed), HR.DISP_E_TYPEMISMATCH));
            }

            int sizeofElement = SafeNativeMethods.SafeArrayGetElemsize(pSafeArray);

            if (sizeofElement != Marshal.SizeOf(typeof(TagVariant)))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyVariantTypeElementsAllowed), HR.DISP_E_TYPEMISMATCH));
            }

            int lBound = SafeNativeMethods.SafeArrayGetLBound(pSafeArray, 1);

            if (lBound > 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyZeroLBoundAllowed), HR.DISP_E_TYPEMISMATCH));
            }

            int uBound = SafeNativeMethods.SafeArrayGetUBound(pSafeArray, 1);

            IntPtr pRawData = SafeNativeMethods.SafeArrayAccessData(pSafeArray);

            try
            {
                object[] objects = Marshal.GetObjectsForNativeVariants(pRawData, uBound + 1);

                Array arr = Array.CreateInstance(type.GetElementType(), objects.Length);

                if (objects.Length == 0)
                {
                    return(arr);
                }

                if (type.GetElementType() != typeof(Int32) && type.GetElementType() != typeof(Int64))
                {
                    try
                    {
                        objects.CopyTo(arr, 0);
                    }
                    catch (Exception e)
                    {
                        if (Fx.IsFatal(e))
                        {
                            throw;
                        }

                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, objects[0].GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH));
                    }
                }
                else
                {
                    if (type.GetElementType() == typeof(Int32))
                    {
                        for (int i = 0; i < objects.Length; i++)
                        {
                            if (objects[i].GetType() == typeof(Int16))
                            {
                                arr.SetValue((Int32)((Int16)objects[i]), i);
                            }
                            else if (objects[i].GetType() == typeof(Int32))
                            {
                                arr.SetValue(objects[i], i);
                            }
                            else
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, objects[i].GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH));
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < objects.Length; i++)
                        {
                            if (objects[i].GetType() == typeof(Int16))
                            {
                                arr.SetValue((Int64)((Int16)objects[i]), i);
                            }
                            else if (objects[i].GetType() == typeof(Int32))
                            {
                                arr.SetValue((Int64)((Int32)objects[i]), i);
                            }
                            else if (objects[i].GetType() == typeof(Int64))
                            {
                                arr.SetValue(objects[i], i);
                            }
                            else
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, objects[i].GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH));
                            }
                        }
                    }
                }

                return(arr);
            }
            finally
            {
                SafeNativeMethods.SafeArrayUnaccessData(pSafeArray);
            }
        }
Exemple #2
0
        private object FetchVariants(IntPtr baseArray, int index, Type type)
        {
            object obj2;

            if (baseArray == IntPtr.Zero)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseArrray");
            }
            uint       disp    = (uint)(index * Marshal.SizeOf(typeof(TagVariant)));
            TagVariant variant = (TagVariant)Marshal.PtrToStructure(this.GetDisp(baseArray, disp), typeof(TagVariant));

            if ((variant.vt & 0x400c) == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("OnlyVariantAllowedByRef"), HR.DISP_E_TYPEMISMATCH));
            }
            TagVariant variant2 = (TagVariant)Marshal.PtrToStructure(variant.ptr, typeof(TagVariant));

            if ((variant2.vt & 0x600c) == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("OnlyByRefVariantSafeArraysAllowed"), HR.DISP_E_TYPEMISMATCH));
            }
            IntPtr pSafeArray = (IntPtr)Marshal.PtrToStructure(variant2.ptr, typeof(IntPtr));

            if (SafeNativeMethods.SafeArrayGetDim(pSafeArray) != 1)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("OnlyOneDimensionalSafeArraysAllowed"), HR.DISP_E_TYPEMISMATCH));
            }
            if (SafeNativeMethods.SafeArrayGetElemsize(pSafeArray) != Marshal.SizeOf(typeof(TagVariant)))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("OnlyVariantTypeElementsAllowed"), HR.DISP_E_TYPEMISMATCH));
            }
            if (SafeNativeMethods.SafeArrayGetLBound(pSafeArray, 1) > 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("OnlyZeroLBoundAllowed"), HR.DISP_E_TYPEMISMATCH));
            }
            int    num5 = SafeNativeMethods.SafeArrayGetUBound(pSafeArray, 1);
            IntPtr aSrcNativeVariant = SafeNativeMethods.SafeArrayAccessData(pSafeArray);

            try
            {
                object[] objectsForNativeVariants = Marshal.GetObjectsForNativeVariants(aSrcNativeVariant, num5 + 1);
                Array    array = Array.CreateInstance(type.GetElementType(), objectsForNativeVariants.Length);
                if (objectsForNativeVariants.Length == 0)
                {
                    return(array);
                }
                if ((type.GetElementType() != typeof(int)) && (type.GetElementType() != typeof(long)))
                {
                    try
                    {
                        objectsForNativeVariants.CopyTo(array, 0);
                        goto Label_0410;
                    }
                    catch (Exception exception)
                    {
                        if (Fx.IsFatal(exception))
                        {
                            throw;
                        }
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("UnsupportedConversion", new object[] { objectsForNativeVariants[0].GetType(), type.GetElementType() }), HR.DISP_E_TYPEMISMATCH));
                    }
                }
                if (type.GetElementType() == typeof(int))
                {
                    for (int i = 0; i < objectsForNativeVariants.Length; i++)
                    {
                        if (objectsForNativeVariants[i].GetType() == typeof(short))
                        {
                            array.SetValue((int)((short)objectsForNativeVariants[i]), i);
                        }
                        else
                        {
                            if (objectsForNativeVariants[i].GetType() != typeof(int))
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("UnsupportedConversion", new object[] { objectsForNativeVariants[i].GetType(), type.GetElementType() }), HR.DISP_E_TYPEMISMATCH));
                            }
                            array.SetValue(objectsForNativeVariants[i], i);
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < objectsForNativeVariants.Length; j++)
                    {
                        if (objectsForNativeVariants[j].GetType() == typeof(short))
                        {
                            array.SetValue((long)((short)objectsForNativeVariants[j]), j);
                        }
                        else if (objectsForNativeVariants[j].GetType() == typeof(int))
                        {
                            array.SetValue((long)((int)objectsForNativeVariants[j]), j);
                        }
                        else
                        {
                            if (objectsForNativeVariants[j].GetType() != typeof(long))
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(System.ServiceModel.SR.GetString("UnsupportedConversion", new object[] { objectsForNativeVariants[j].GetType(), type.GetElementType() }), HR.DISP_E_TYPEMISMATCH));
                            }
                            array.SetValue(objectsForNativeVariants[j], j);
                        }
                    }
                }
Label_0410:
                obj2 = array;
            }
            finally
            {
                SafeNativeMethods.SafeArrayUnaccessData(pSafeArray);
            }
            return(obj2);
        }