コード例 #1
0
ファイル: McgComHelpers.cs プロジェクト: tedd/corert
        static object ComInterfaceToObjectInternal_NoManagedUnboxing(
            IntPtr pComItf,
            RuntimeTypeHandle interfaceType,
            RuntimeTypeHandle classTypeInSignature,
            CreateComObjectFlags flags)
        {
            if (pComItf == default(IntPtr))
            {
                return(null);
            }

            //
            // Is this a CCW?
            //
            ComCallableObject ccw;

            if (ComCallableObject.TryGetCCW(pComItf, out ccw))
            {
                return(ccw.TargetObject);
            }

            //
            // This pointer is not a CCW, but we need to do one additional check here for aggregation
            // In case the COM pointer is a interface implementation from native, but the outer object is a
            // managed object
            //
            IntPtr pComIdentityIUnknown = McgMarshal.ComQueryInterfaceNoThrow(pComItf, ref Interop.COM.IID_IUnknown);

            if (pComIdentityIUnknown == default(IntPtr))
            {
                throw new InvalidCastException();
            }

            try
            {
                //
                // Check whether the identity COM pointer to see if it is a aggregating CCW
                //
                if (ComCallableObject.TryGetCCW(pComIdentityIUnknown, out ccw))
                {
                    return(ccw.TargetObject);
                }

                //
                // Nope, not a CCW - let's go down our RCW creation code path
                //
                return(ComInterfaceToComObjectInternal(
                           pComItf,
                           pComIdentityIUnknown,
                           interfaceType,
                           classTypeInSignature,
                           ContextCookie.Default,
                           flags
                           ));
            }
            finally
            {
                McgMarshal.ComRelease(pComIdentityIUnknown);
            }
        }
コード例 #2
0
ファイル: ExceptionHelpers.cs プロジェクト: ebeworld/corert
        /// <summary>
        /// This method returns a new Exception object given the HR value.
        ///
        /// 1. We check whether we have our own LanguageException associated with this hr. If so we simply use it since it helps preserve the stacktrace, message and type.
        ///    This is done using GetLanguageException API on ILanguageExceptionErrorInfo from IRestrictedErrorInfo. Since ILanguageExceptionErrorInfo is available only on Windows Blue
        ///    we can only do this WindowsBlue and above. In desktop CLR we could use GetErroInfo and check whether we have our IErroInfo and retrieve our own exception.
        ///    For Win8 in .NET Native we simply create the exception using the RestrictedErrorInfo and hence only able to give the exception with restrictedErrorMsg.
        /// 2. In case we do not have the languageException we simply check RestrictedErrorInfo for errorMsg and create an exception using
        ///   <errorMsg>\r\n<restrictedErrorMsg>. This is done for only windows blue. To be backward compatible we only use errorMsg for creating exception in win8.
        /// 3. PS - This class puts all the logic in try, catch block to ensure that none of the exception helpers
        ///  throw exception themselves.
        /// </summary>
        /// <param name="hr"></param>
        /// <param name="isWinRTScenario"></param>
        internal static Exception GetExceptionForHRInternalNoThrow(int hr, bool isWinRTScenario, bool isClassicCOM)
        {
            Exception ex;
            IntPtr    pRestrictedErrorInfo = IntPtr.Zero;

            try
            {
                if (TryGetRestrictedErrorInfo(out pRestrictedErrorInfo))
                {
                    // This is to check whether we need to give post win8 behavior or not.
                    if (isWinRTScenario)
                    {
                        // Check whether the given IRestrictedErrorInfo object supports ILanguageExceptionErrorInfo
                        IntPtr pLanguageExceptionErrorInfo = McgMarshal.ComQueryInterfaceNoThrow(pRestrictedErrorInfo, ref Interop.COM.IID_ILanguageExceptionErrorInfo);
                        if (pLanguageExceptionErrorInfo != IntPtr.Zero)
                        {
                            // We have an LanguageExceptionErrorInfo.
                            IntPtr pUnk;
                            __com_ILanguageExceptionErrorInfo *pComLanguageExceptionErrorInfo = (__com_ILanguageExceptionErrorInfo *)pLanguageExceptionErrorInfo;
                            int result = CalliIntrinsics.StdCall <int>(pComLanguageExceptionErrorInfo->pVtable->pfnGetLanguageException, pLanguageExceptionErrorInfo, out pUnk);
                            McgMarshal.ComSafeRelease(pLanguageExceptionErrorInfo);

                            if (result >= 0 && pUnk != IntPtr.Zero)
                            {
                                try
                                {
                                    // Check whether the given pUnk is a managed exception.
                                    ComCallableObject ccw;
                                    if (ComCallableObject.TryGetCCW(pUnk, out ccw))
                                    {
                                        return(ccw.TargetObject as Exception);
                                    }
                                }
                                finally
                                {
                                    McgMarshal.ComSafeRelease(pUnk);
                                }
                            }
                        }
                    }
                    String message = null, errorInfoReference = null;
                    string errMsg, errCapSid, resErrMsg;
                    int    errHr;
                    object restrictedErrorInfo = null;

                    bool hasErrorInfo = false;
                    if (RestrictedErrorInfoHelper.GetErrorDetails(pRestrictedErrorInfo, out errMsg, out errHr, out resErrMsg, out errCapSid) && errHr == hr)
                    {
                        // RestrictedErrorInfo details can be used since the pRestrictedErrorInfo has the same hr value as the hr returned by the native code.
                        // We are in windows blue or above and hence the exceptionMsg is errMsg + "\r\n" + resErrMsg
                        message = String.IsNullOrEmpty(resErrMsg) ? errMsg : errMsg + "\r\n" + resErrMsg;
                        RestrictedErrorInfoHelper.GetReference(pRestrictedErrorInfo, out errorInfoReference);
                        restrictedErrorInfo = McgMarshal.ComInterfaceToObject(pRestrictedErrorInfo, InternalTypes.IRestrictedErrorInfo);

                        hasErrorInfo = true;
                    }

                    if (hr == Interop.COM.RO_E_CLOSED && isWinRTScenario)
                    {
                        hr = Interop.COM.COR_E_OBJECTDISPOSED;
                    }

                    // Now we simply need to set the description and the resDescription by adding an internal method.
                    ex = GetMappingExceptionForHR(hr, message, isClassicCOM, hasErrorInfo);

                    if (restrictedErrorInfo != null)
                    {
                        InteropExtensions.AddExceptionDataForRestrictedErrorInfo(ex, resErrMsg, errorInfoReference, errCapSid, restrictedErrorInfo);
                    }

                    return(ex);
                }
            }
            catch (Exception)
            {
                // We can't do any thing here and hence we swallow the exception and get the corresponding hr.
            }
            finally
            {
                McgMarshal.ComSafeRelease(pRestrictedErrorInfo);
            }

            // We could not find any restrictedErrorInfo associated with this object and hence we simply use the hr to create the exception.
            return(GetMappingExceptionForHR(hr, null, isClassicCOM, hasErrorInfo: false));
        }