The Webview Univeral Flutter package for Appeto SDK.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

128 lignes
6.8 KiB

  1. //*********************************************************
  2. //
  3. // Copyright (c) Microsoft. All rights reserved.
  4. // This code is licensed under the MIT License.
  5. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
  6. // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  7. // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  8. // PARTICULAR PURPOSE AND NONINFRINGEMENT.
  9. //
  10. //*********************************************************
  11. // Note: When origination is enabled by including this file, origination is done as part of the RETURN_* and THROW_* macros. Before originating
  12. // a new error we will observe whether there is already an error payload associated with the current thread. If there is, and the HRESULTs match,
  13. // then a new error will not be originated. Otherwise we will overwrite it with a new origination. The ABI boundary for WinRT APIs will check the
  14. // per-thread error information. The act of checking the error clears it, so there should be minimal risk of failing to originate distinct errors
  15. // simply because the HRESULTs match.
  16. //
  17. // For THROW_ macros we will examine the thread-local error storage once per throw. So typically once, with additional calls if the exception is
  18. // caught and re-thrown.
  19. //
  20. // For RETURN_ macros we will have to examine the thread-local error storage once per frame as the call stack unwinds. Because error conditions
  21. // -should- be uncommon the performance impact of checking TLS should be minimal. The more expensive part is originating the error because it must
  22. // capture the entire stack and some additional data.
  23. #ifndef __WIL_RESULT_ORIGINATE_INCLUDED
  24. #define __WIL_RESULT_ORIGINATE_INCLUDED
  25. #include "result.h"
  26. #include <OleAuto.h> // RestrictedErrorInfo uses BSTRs :(
  27. #include "resource.h"
  28. #include "com.h"
  29. #include <roerrorapi.h>
  30. #ifndef __cplusplus_winrt // The CX runtime likes to originate errors already so we would conflict with them.
  31. namespace wil
  32. {
  33. namespace details
  34. {
  35. // Note: The name must begin with "Raise" so that the !analyze auto-bucketing will ignore this stack frame. Otherwise this line of code gets all the blame.
  36. inline void __stdcall RaiseRoOriginateOnWilExceptions(wil::FailureInfo const& failure) WI_NOEXCEPT
  37. {
  38. if ((failure.type == FailureType::Return) || (failure.type == FailureType::Exception))
  39. {
  40. bool shouldOriginate = true;
  41. wil::com_ptr_nothrow<IRestrictedErrorInfo> restrictedErrorInformation;
  42. if (GetRestrictedErrorInfo(&restrictedErrorInformation) == S_OK)
  43. {
  44. // This thread already has an error origination payload. Don't originate again if it has the same HRESULT that we are
  45. // observing right now.
  46. wil::unique_bstr descriptionUnused;
  47. HRESULT existingHr = failure.hr;
  48. wil::unique_bstr restrictedDescriptionUnused;
  49. wil::unique_bstr capabilitySidUnused;
  50. if (SUCCEEDED(restrictedErrorInformation->GetErrorDetails(&descriptionUnused, &existingHr, &restrictedDescriptionUnused, &capabilitySidUnused)))
  51. {
  52. shouldOriginate = (failure.hr != existingHr);
  53. }
  54. }
  55. if (shouldOriginate)
  56. {
  57. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
  58. wil::unique_hmodule errorModule;
  59. if (GetModuleHandleExW(0, L"api-ms-win-core-winrt-error-l1-1-1.dll", &errorModule))
  60. {
  61. auto pfn = reinterpret_cast<decltype(&::RoOriginateError)>(GetProcAddress(errorModule.get(), "RoOriginateError"));
  62. if (pfn != nullptr)
  63. {
  64. pfn(failure.hr, nullptr);
  65. }
  66. }
  67. #else // DESKTOP | SYSTEM
  68. ::RoOriginateError(failure.hr, nullptr);
  69. #endif // DESKTOP | SYSTEM
  70. }
  71. else if (restrictedErrorInformation)
  72. {
  73. // GetRestrictedErrorInfo returns ownership of the error information. If we aren't originating, and an error was already present,
  74. // then we need to restore the error information for later observation.
  75. SetRestrictedErrorInfo(restrictedErrorInformation.get());
  76. }
  77. }
  78. }
  79. // This method will check for the presence of stowed exception data on the current thread. If such data exists, and the HRESULT
  80. // matches the current failure, then we will call RoFailFastWithErrorContext. RoFailFastWithErrorContext in this situation will
  81. // result in -VASTLY- improved crash bucketing. It is hard to express just how much better. In other cases we just return and
  82. // the calling method fails fast the same way it always has.
  83. inline void __stdcall FailfastWithContextCallback(wil::FailureInfo const& failure) WI_NOEXCEPT
  84. {
  85. wil::com_ptr_nothrow<IRestrictedErrorInfo> restrictedErrorInformation;
  86. if (GetRestrictedErrorInfo(&restrictedErrorInformation) == S_OK)
  87. {
  88. wil::unique_bstr descriptionUnused;
  89. HRESULT existingHr = failure.hr;
  90. wil::unique_bstr restrictedDescriptionUnused;
  91. wil::unique_bstr capabilitySidUnused;
  92. if (SUCCEEDED(restrictedErrorInformation->GetErrorDetails(&descriptionUnused, &existingHr, &restrictedDescriptionUnused, &capabilitySidUnused)) &&
  93. (existingHr == failure.hr))
  94. {
  95. // GetRestrictedErrorInfo returns ownership of the error information. We want it to be available for RoFailFastWithErrorContext
  96. // so we must restore it via SetRestrictedErrorInfo first.
  97. SetRestrictedErrorInfo(restrictedErrorInformation.get());
  98. RoFailFastWithErrorContext(existingHr);
  99. }
  100. else
  101. {
  102. // The error didn't match the current failure. Put it back in thread-local storage even though we aren't failing fast
  103. // in this method, so it is available in the debugger just-in-case.
  104. SetRestrictedErrorInfo(restrictedErrorInformation.get());
  105. }
  106. }
  107. }
  108. } // namespace details
  109. } // namespace wil
  110. // Automatically call RoOriginateError upon error origination by including this file
  111. WI_HEADER_INITITALIZATION_FUNCTION(ResultStowedExceptionInitialize, []
  112. {
  113. ::wil::SetOriginateErrorCallback(::wil::details::RaiseRoOriginateOnWilExceptions);
  114. ::wil::SetFailfastWithContextCallback(::wil::details::FailfastWithContextCallback);
  115. return 1;
  116. });
  117. #endif // __cplusplus_winrt
  118. #endif // __WIL_RESULT_ORIGINATE_INCLUDED