/// <summary> /// This method validates that the given weak reference is alive. /// 1. IWeakReference->Resolve method returns the target's interface for the mapping IID passed to it. /// 2. If the object is not alive it returns null. /// 2. From the returned interface we get or create a new RCW and return it. /// </summary> /// <returns></returns> internal unsafe object Resolve() { IntPtr pInspectable; __com_IWeakReference *pComIWeakReference = (__com_IWeakReference *)m_pComWeakRef; Guid inspectableIID = Interop.COM.IID_IInspectable; int result = CalliIntrinsics.StdCall__int( pComIWeakReference->pVtable->pfnResolve, m_pComWeakRef, &inspectableIID, &pInspectable); if (result >= 0 && pInspectable != IntPtr.Zero) { try { return(McgMarshal.ComInterfaceToObject(pInspectable, McgModuleManager.IInspectable)); } finally { // Release the pInspectable. McgMarshal.ComRelease(pInspectable); } } return(null); }
internal static Exception AttachRestrictedErrorInfo(Exception e) { // If there is no exception, then the restricted error info doesn't apply to it if (e != null) { System.IntPtr pRestrictedErrorInfo = IntPtr.Zero; try { // Get the restricted error info for this thread and see if it may correlate to the current // exception object. Note that in general the thread's IRestrictedErrorInfo is not meant for // exceptions that are marshaled Windows.Foundation.HResults and instead are intended for // HRESULT ABI return values. However, in many cases async APIs will set the thread's restricted // error info as a convention in order to provide extended debugging information for the ErrorCode // property. if (TryGetRestrictedErrorInfo(out pRestrictedErrorInfo)) { string description; string restrictedDescription; string capabilitySid; int restrictedErrorInfoHResult; if (RestrictedErrorInfoHelper.GetErrorDetails( pRestrictedErrorInfo, out description, out restrictedErrorInfoHResult, out restrictedDescription, out capabilitySid) && (e.HResult == restrictedErrorInfoHResult)) { // Since this is a special case where by convention there may be a correlation, there is not a // guarantee that the restricted error info does belong to the async error code. In order to // reduce the risk that we associate incorrect information with the exception object, we need // to apply a heuristic where we attempt to match the current exception's HRESULT with the // HRESULT the IRestrictedErrorInfo belongs to. If it is a match we will assume association // for the IAsyncInfo case. string errorReference; RestrictedErrorInfoHelper.GetReference(pRestrictedErrorInfo, out errorReference); object restrictedErrorInfo = McgMarshal.ComInterfaceToObject(pRestrictedErrorInfo, InternalTypes.IRestrictedErrorInfo); InteropExtensions.AddExceptionDataForRestrictedErrorInfo( e, restrictedDescription, errorReference, capabilitySid, restrictedErrorInfo); } } } catch (Exception) { // If we can't get the restricted error info, then proceed as if it isn't associated with this // error. } finally { McgMarshal.ComSafeRelease(pRestrictedErrorInfo); } } return(e); }
//==================================================================== // return an Object for IUnknown //==================================================================== public static Object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) { object obj = McgMarshal.ComInterfaceToObject(pUnk, InternalTypes.IUnknown); #if CORECLR if (obj == null) { return(Marshal.GetObjectForIUnknown(pUnk)); } #endif return(obj); }
public static Object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) { return(McgMarshal.ComInterfaceToObject(pUnk, InternalTypes.IUnknown)); }
/// <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)); }
public static Object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk) { return(McgMarshal.ComInterfaceToObject(pUnk, McgModuleManager.IUnknown)); }