/// <summary> /// The method calls RoOriginateLanguageException. The method has all the logic in try, catch block to ensure that none of the exception helpers /// throw exception themselves. /// </summary> /// <param name="ex"></param> /// <returns></returns> private static bool OriginateLanguageException(Exception ex) { IntPtr pUnk = IntPtr.Zero; HSTRING errorMsg = default(HSTRING); try { pUnk = McgMarshal.ObjectToComInterface(ex, InternalTypes.IUnknown); if (pUnk != IntPtr.Zero) { RuntimeAugments.GenerateExceptionInformationForDump(ex, pUnk); errorMsg = McgMarshal.StringToHString(ex.Message); return(ExternalInterop.RoOriginateLanguageException(ex.HResult, errorMsg, pUnk) >= 0); } } catch (Exception) { // We can't do anything here and hence simply swallow the exception } finally { McgMarshal.ComSafeRelease(pUnk); if (errorMsg.handle != IntPtr.Zero) { ExternalInterop.WindowsDeleteString(errorMsg.handle.ToPointer()); } } return(false); }
public static int StdCall__int( IntPtr pfn, void *pthis, System.Runtime.InteropServices.HSTRING arg0, void *arg1) { // This method is implemented elsewhere in the toolchain return(0); }
#pragma warning restore 649, 169 /// <summary> /// This method gets the mapping hr for the exception. and also does the right thing to propogate the hr correctly to the native layer. /// /// We check if the exception is a pure managed exception or an exception created from an hr that entered the system from native. /// a. If it is a pure managed exception we create an IUnknown ptr from the exception and RoOriginateLanguageException on it. /// This helps us to preserve our managed exception and throw the same exception in case this exception roundtrips and hence preserve the call stack. /// Since the API RoOriginateLanguageException is available only on windows blue, we can't do the same in win8. In desktop CLR we use the non-modern SDK API /// GetErroInfo\SetErrorInfo combination to preserve managed exception but unfortunately we can't do this in .NET Native and hence we only our able to preserve the exception message and /// type and end up getting a rough stacktrace PS - Even this behavior in win8 is possible only in debug mode as RoSetErrorReportingFlags is set to UseSetErrorInfo only in debug mode. /// /// b. In case the exception is created due to an hr that entered managed world via native call, we will have restrictederrorInfo associated with it. In this case /// we do not RoOriginateLanguageException\RoOriginateError and rather preserve the exception stack trace by simply calling the SetRestrictedErrorInfo. /// /// c. PS - Due to the use of modern SDK we have no way to round trip exceptions in classicCOM scenarios any more. /// This is because we can't use SetErrorInfo\GetErrorInfo APIs at all. Unfortunately we have no workaround for this even in windowsBlue! /// With the use of IRestrictedErrorInfo has some disadvantages as we lose other info available with IErrorInfo in terms of HelpFile etc. /// /// d. This class puts all the logic in try, catch block to ensure that none of the exception helpers. /// throw exception themselves. /// </summary> /// <param name="ex"></param> /// <param name="isWinRTScenario"></param> /// <returns></returns> internal static int GetHRForExceptionWithErrorPropogationNoThrow(Exception ex, bool isWinRTScenario) { int hr = ex.HResult; if (hr == Interop.COM.COR_E_OBJECTDISPOSED && isWinRTScenario) { // Since ObjectDisposedException is projected to RO_E_CLOSED in WINRT we make sure to use the correct hr while updating the CRuntimeError object of Windows. hr = Interop.COM.RO_E_CLOSED; } try { // Check whether the exception has an associated RestrictedErrorInfo associated with it. if (isWinRTScenario) { IntPtr pRestrictedErrorInfo; object restrictedErrorInfo; if (InteropExtensions.TryGetRestrictedErrorObject(ex, out restrictedErrorInfo) && restrictedErrorInfo != null) { // We have the restricted errorInfo associated with this object and hence this exception was created by an hr entering managed through native. pRestrictedErrorInfo = McgMarshal.ObjectToComInterface(restrictedErrorInfo, InternalTypes.IRestrictedErrorInfo); if (pRestrictedErrorInfo != IntPtr.Zero) { // We simply call SetRestrictedErrorInfo since we do not want to originate the exception again. ExternalInterop.SetRestrictedErrorInfo(pRestrictedErrorInfo); McgMarshal.ComSafeRelease(pRestrictedErrorInfo); } } else { // we are in windows blue and hence we can preserve our exception so that we can reuse this exception in case it comes back and provide richer exception support. OriginateLanguageException(ex); } } else { // We are either pre WinBlue or in classicCOM scenario and hence we can only RoOriginateError at this point. // Desktop CLR uses SetErrorInfo and preserves the exception object which helps us give the same support as winBlue. // Since .NET Native can only use modern SDK we have a compatibility break here by only preserving the restrictederrorMsg and exception type but the stack trace will be incorrect. // Also RoOriginateError works only under the debugger since RoSetErrorReportingFlags is set to RO_ERROR_REPORTING_USESETERRORINFO. // If we are not under the debugger we can't set this API since it is not part of the modernSDK and hence this will not work // and will result in different behavior than the desktop. HSTRING errorMsg = McgMarshal.StringToHString(ex.Message); ExternalInterop.RoOriginateError(ex.HResult, errorMsg); ExternalInterop.WindowsDeleteString(errorMsg.handle.ToPointer()); } } catch (Exception) { // We can't throw an exception here and hence simply swallow it. } return(hr); }
public static int StdCall__int( global::System.IntPtr pfn, IntPtr pthis, HSTRING arg0, IntPtr arg1, void *arg2, void *arg3) { // This method is implemented elsewhere in the toolchain return(0); }
public static unsafe string HStringToString(HSTRING pHString) { if (pHString.handle == IntPtr.Zero) { return(String.Empty); } uint length = 0; char *pchBuffer = ExternalInterop.WindowsGetStringRawBuffer(pHString.handle.ToPointer(), &length); return(new string(pchBuffer, 0, (int)length)); }
/// <summary> /// Returns the requested interface pointer specified by itfType from the CCWActivationFactory /// object instance. Typically the requested interface is the /// System.Runtime.InteropServices.WindowsRuntime.IActivationFactory interface. /// </summary> public unsafe int GetCCWActivationFactory(HSTRING activatableClassId, RuntimeTypeHandle itfType, IntPtr *factoryOut) { try { string classId = McgMarshal.HStringToString(activatableClassId); if (classId == null) { return(Interop.COM.E_INVALIDARG); } RuntimeTypeHandle factoryTypeHandle = default(RuntimeTypeHandle); if (m_ccwFactoriesNameMap != null) { int slot = m_ccwFactoriesNameMap.FindString(classId); if (slot >= 0) { factoryTypeHandle = m_ccwFactories[slot].FactoryType; } } if (factoryTypeHandle.IsNull()) { return(Interop.COM.E_NOINTERFACE); } object factory = InteropExtensions.RuntimeNewObject(factoryTypeHandle); *factoryOut = McgMarshal.ObjectToComInterface( factory, itfType); } catch (Exception ex) { *factoryOut = default(IntPtr); return(McgMarshal.GetHRForExceptionWinRT(ex)); } return(Interop.COM.S_OK); }
internal static unsafe extern int RoParseTypeName( HSTRING typename, uint *typenamePartsLength, IntPtr **typenameParts);
internal static extern int RoOriginateLanguageException(int hr, HSTRING message, IntPtr pLanguageException);
public static extern int RoOriginateError(int hr, HSTRING hstring);
internal static unsafe string HStringToString(IntPtr hString) { HSTRING hstring = new HSTRING(hString); return(HStringToString(hstring)); }
public static string HStringToString(HSTRING hString) { throw new PlatformNotSupportedException("HStringToString"); }