WindowsRuntime.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. #include "il2cpp-config.h"
  2. #if IL2CPP_TARGET_WINDOWS && !IL2CPP_USE_GENERIC_WINDOWSRUNTIME
  3. #include "il2cpp-class-internals.h"
  4. #include "il2cpp-string-types.h"
  5. #include "os/WindowsRuntime.h"
  6. #include "utils/Expected.h"
  7. #include "utils/Il2CppError.h"
  8. #include "utils/StringUtils.h"
  9. #include "vm/CCW.h"
  10. #include "WindowsHeaders.h"
  11. #include <roerrorapi.h>
  12. namespace il2cpp
  13. {
  14. namespace os
  15. {
  16. #if !LINK_TO_WINDOWSRUNTIME_LIBS
  17. template<typename FunctionType>
  18. FunctionType ResolveAPI(const wchar_t* moduleName, const char* functionName)
  19. {
  20. HMODULE module = GetModuleHandleW(moduleName);
  21. if (module == NULL)
  22. return NULL;
  23. return reinterpret_cast<FunctionType>(GetProcAddress(module, functionName));
  24. }
  25. #endif
  26. il2cpp_hresult_t WindowsRuntime::GetActivationFactory(Il2CppHString className, Il2CppIActivationFactory** activationFactory)
  27. {
  28. IL2CPP_ASSERT(className != NULL);
  29. IL2CPP_ASSERT(activationFactory != NULL);
  30. #if LINK_TO_WINDOWSRUNTIME_LIBS
  31. return RoGetActivationFactory(reinterpret_cast<HSTRING>(className), reinterpret_cast<const IID&>(Il2CppIActivationFactory::IID), reinterpret_cast<void**>(activationFactory));
  32. #else
  33. typedef HRESULT(WINAPI* RoGetActivationFactoryFunc)(void* activatableClassId, const Il2CppGuid& iid, Il2CppIActivationFactory** factory);
  34. static RoGetActivationFactoryFunc RoGetActivationFactory = NULL;
  35. if (RoGetActivationFactory == NULL)
  36. {
  37. RoGetActivationFactory = ResolveAPI<RoGetActivationFactoryFunc>(L"api-ms-win-core-winrt-l1-1-0.dll", "RoGetActivationFactory");
  38. if (RoGetActivationFactory == NULL)
  39. return IL2CPP_REGDB_E_CLASSNOTREG;
  40. }
  41. return RoGetActivationFactory(className, Il2CppIActivationFactory::IID, activationFactory);
  42. #endif
  43. }
  44. il2cpp_hresult_t WindowsRuntime::CreateHStringReference(const utils::StringView<Il2CppNativeChar>& str, Il2CppHStringHeader* header, Il2CppHString* hstring)
  45. {
  46. IL2CPP_ASSERT(header != NULL);
  47. IL2CPP_ASSERT(hstring != NULL);
  48. if (str.Length() == 0)
  49. {
  50. *hstring = NULL;
  51. return S_OK;
  52. }
  53. #if LINK_TO_WINDOWSRUNTIME_LIBS
  54. return WindowsCreateStringReference(str.Str(), static_cast<uint32_t>(str.Length()), reinterpret_cast<HSTRING_HEADER*>(header), reinterpret_cast<HSTRING*>(hstring));
  55. #else
  56. typedef HRESULT(STDAPICALLTYPE * WindowsCreateStringReferenceFunc)(const wchar_t* sourceString, uint32_t length, Il2CppHStringHeader* hstringHeader, Il2CppHString* hstring);
  57. static WindowsCreateStringReferenceFunc WindowsCreateStringReference = NULL;
  58. if (WindowsCreateStringReference == NULL)
  59. {
  60. WindowsCreateStringReference = ResolveAPI<WindowsCreateStringReferenceFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsCreateStringReference");
  61. if (WindowsCreateStringReference == NULL)
  62. return IL2CPP_COR_E_PLATFORMNOTSUPPORTED;
  63. }
  64. return WindowsCreateStringReference(str.Str(), static_cast<uint32_t>(str.Length()), header, hstring);
  65. #endif
  66. }
  67. il2cpp_hresult_t WindowsRuntime::CreateHString(const utils::StringView<Il2CppChar>& str, Il2CppHString* hstring)
  68. {
  69. IL2CPP_ASSERT(str.Str() != NULL || str.Length() == 0);
  70. if (str.Length() == 0)
  71. {
  72. *hstring = NULL;
  73. return S_OK;
  74. }
  75. #if LINK_TO_WINDOWSRUNTIME_LIBS
  76. return WindowsCreateString(str.Str(), static_cast<uint32_t>(str.Length()), reinterpret_cast<HSTRING*>(hstring));
  77. #else
  78. typedef il2cpp_hresult_t (STDAPICALLTYPE * WindowsCreateStringFunc)(const wchar_t* sourceString, uint32_t length, Il2CppHString* hstring);
  79. static WindowsCreateStringFunc WindowsCreateString = NULL;
  80. if (WindowsCreateString == NULL)
  81. {
  82. WindowsCreateString = ResolveAPI<WindowsCreateStringFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsCreateString");
  83. if (WindowsCreateString == NULL)
  84. return IL2CPP_COR_E_PLATFORMNOTSUPPORTED;
  85. }
  86. return WindowsCreateString(str.Str(), static_cast<uint32_t>(str.Length()), hstring);
  87. #endif
  88. }
  89. il2cpp_hresult_t WindowsRuntime::DuplicateHString(Il2CppHString hstring, Il2CppHString* duplicated)
  90. {
  91. #if LINK_TO_WINDOWSRUNTIME_LIBS
  92. return WindowsDuplicateString(reinterpret_cast<HSTRING>(hstring), reinterpret_cast<HSTRING*>(duplicated));
  93. #else
  94. typedef il2cpp_hresult_t(STDAPICALLTYPE* WindowsDuplicateStringFunc)(Il2CppHString hstring, Il2CppHString* duplicated);
  95. static WindowsDuplicateStringFunc WindowsDuplicateString = NULL;
  96. if (WindowsDuplicateString == NULL)
  97. {
  98. WindowsDuplicateString = ResolveAPI<WindowsDuplicateStringFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsDuplicateString");
  99. if (WindowsDuplicateString == NULL)
  100. return IL2CPP_COR_E_PLATFORMNOTSUPPORTED;
  101. }
  102. return WindowsDuplicateString(hstring, duplicated);
  103. #endif
  104. }
  105. il2cpp_hresult_t WindowsRuntime::DeleteHString(Il2CppHString hstring)
  106. {
  107. if (hstring == NULL)
  108. return IL2CPP_S_OK;
  109. #if LINK_TO_WINDOWSRUNTIME_LIBS
  110. return WindowsDeleteString(reinterpret_cast<HSTRING>(hstring));
  111. #else
  112. typedef il2cpp_hresult_t (STDAPICALLTYPE * WindowsDeleteStringFunc)(Il2CppHString hstring);
  113. static WindowsDeleteStringFunc WindowsDeleteString = NULL;
  114. if (WindowsDeleteString == NULL)
  115. {
  116. WindowsDeleteString = ResolveAPI<WindowsDeleteStringFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsDeleteString");
  117. if (WindowsDeleteString == NULL)
  118. return IL2CPP_COR_E_PLATFORMNOTSUPPORTED;
  119. }
  120. return WindowsDeleteString(hstring);
  121. #endif
  122. }
  123. utils::Expected<const Il2CppChar*> WindowsRuntime::GetHStringBuffer(Il2CppHString hstring, uint32_t* length)
  124. {
  125. #if LINK_TO_WINDOWSRUNTIME_LIBS
  126. return WindowsGetStringRawBuffer(reinterpret_cast<HSTRING>(hstring), length);
  127. #else
  128. typedef const wchar_t* (STDAPICALLTYPE * WindowsGetStringRawBufferFunc)(Il2CppHString hstring, uint32_t* length);
  129. static WindowsGetStringRawBufferFunc WindowsGetStringRawBuffer = NULL;
  130. if (WindowsGetStringRawBuffer == NULL)
  131. {
  132. WindowsGetStringRawBuffer = ResolveAPI<WindowsGetStringRawBufferFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsGetStringRawBuffer");
  133. if (WindowsGetStringRawBuffer == NULL)
  134. return utils::Il2CppError(utils::NotSupported, "Marshaling HSTRINGs is not supported on current platform.");
  135. }
  136. return WindowsGetStringRawBuffer(hstring, length);
  137. #endif
  138. }
  139. utils::Expected<const Il2CppNativeChar*> WindowsRuntime::GetNativeHStringBuffer(Il2CppHString hstring, uint32_t* length)
  140. {
  141. return GetHStringBuffer(hstring, length);
  142. }
  143. utils::Expected<il2cpp_hresult_t> WindowsRuntime::PreallocateHStringBuffer(uint32_t length, Il2CppNativeChar** mutableBuffer, void** bufferHandle)
  144. {
  145. #if LINK_TO_WINDOWSRUNTIME_LIBS
  146. return WindowsPreallocateStringBuffer(length, mutableBuffer, reinterpret_cast<HSTRING_BUFFER*>(bufferHandle));
  147. #else
  148. typedef il2cpp_hresult_t (STDAPICALLTYPE * WindowsPreallocateStringBufferFunc)(uint32_t length, Il2CppNativeChar** mutableBuffer, void** bufferHandle);
  149. static WindowsPreallocateStringBufferFunc WindowsPreallocateStringBuffer = NULL;
  150. if (WindowsPreallocateStringBuffer == NULL)
  151. {
  152. WindowsPreallocateStringBuffer = ResolveAPI<WindowsPreallocateStringBufferFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsPreallocateStringBuffer");
  153. if (WindowsPreallocateStringBuffer == NULL)
  154. return utils::Il2CppError(utils::NotSupported, "Marshaling HSTRINGs is not supported on current platform.");
  155. }
  156. return WindowsPreallocateStringBuffer(length, mutableBuffer, bufferHandle);
  157. #endif
  158. }
  159. utils::Expected<il2cpp_hresult_t> WindowsRuntime::PromoteHStringBuffer(void* bufferHandle, Il2CppHString* hstring)
  160. {
  161. #if LINK_TO_WINDOWSRUNTIME_LIBS
  162. return WindowsPromoteStringBuffer(static_cast<HSTRING_BUFFER>(bufferHandle), reinterpret_cast<HSTRING*>(hstring));
  163. #else
  164. typedef il2cpp_hresult_t (STDAPICALLTYPE * WindowsPromoteStringBufferFunc)(void* bufferHandle, Il2CppHString* hstring);
  165. static WindowsPromoteStringBufferFunc WindowsPromoteStringBuffer = NULL;
  166. if (WindowsPromoteStringBuffer == NULL)
  167. {
  168. WindowsPromoteStringBuffer = ResolveAPI<WindowsPromoteStringBufferFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsPromoteStringBuffer");
  169. if (WindowsPromoteStringBuffer == NULL)
  170. return utils::Il2CppError(utils::NotSupported, "Marshaling HSTRINGs is not supported on current platform.");
  171. }
  172. return WindowsPromoteStringBuffer(bufferHandle, hstring);
  173. #endif
  174. }
  175. utils::Expected<il2cpp_hresult_t> WindowsRuntime::DeleteHStringBuffer(void* bufferHandle)
  176. {
  177. #if LINK_TO_WINDOWSRUNTIME_LIBS
  178. return WindowsDeleteStringBuffer(static_cast<HSTRING_BUFFER>(bufferHandle));
  179. #else
  180. typedef il2cpp_hresult_t (STDAPICALLTYPE * WindowsDeleteStringBufferFunc)(void* bufferHandle);
  181. static WindowsDeleteStringBufferFunc WindowsDeleteStringBuffer = NULL;
  182. if (WindowsDeleteStringBuffer == NULL)
  183. {
  184. WindowsDeleteStringBuffer = ResolveAPI<WindowsDeleteStringBufferFunc>(L"api-ms-win-core-winrt-string-l1-1-0.dll", "WindowsDeleteStringBuffer");
  185. if (WindowsDeleteStringBuffer == NULL)
  186. return utils::Il2CppError(utils::NotSupported, "Marshaling HSTRINGs is not supported on current platform.");
  187. }
  188. return WindowsDeleteStringBuffer(bufferHandle);
  189. #endif
  190. }
  191. Il2CppIRestrictedErrorInfo* WindowsRuntime::GetRestrictedErrorInfo()
  192. {
  193. Il2CppIRestrictedErrorInfo* errorInfo;
  194. HRESULT hr;
  195. #if LINK_TO_WINDOWSRUNTIME_LIBS
  196. hr = ::GetRestrictedErrorInfo(reinterpret_cast<IRestrictedErrorInfo**>(&errorInfo));
  197. #else
  198. typedef HRESULT (STDAPICALLTYPE * GetRestrictedErrorInfoFunc)(Il2CppIRestrictedErrorInfo** ppRestrictedErrorInfo);
  199. static GetRestrictedErrorInfoFunc getRestrictedErrorInfo = NULL;
  200. if (getRestrictedErrorInfo == NULL)
  201. {
  202. getRestrictedErrorInfo = ResolveAPI<GetRestrictedErrorInfoFunc>(L"api-ms-win-core-winrt-error-l1-1-1.dll", "GetRestrictedErrorInfo");
  203. if (getRestrictedErrorInfo == NULL)
  204. return NULL;
  205. }
  206. hr = getRestrictedErrorInfo(&errorInfo);
  207. #endif
  208. if (FAILED(hr))
  209. return NULL;
  210. return errorInfo;
  211. }
  212. // Fallback path for desktop in case we're running on below Windows 8.1
  213. // Also used for Xbox One as it has no RoOriginateLanguageException
  214. static inline void OriginateErrorNoLanguageException(il2cpp_hresult_t hresult, Il2CppHString message)
  215. {
  216. #if !LINK_TO_WINDOWSRUNTIME_LIBS
  217. typedef BOOL(STDAPICALLTYPE * RoOriginateErrorFunc)(il2cpp_hresult_t error, Il2CppHString message);
  218. static RoOriginateErrorFunc RoOriginateError = NULL;
  219. if (RoOriginateError == NULL)
  220. {
  221. RoOriginateError = ResolveAPI<RoOriginateErrorFunc>(L"api-ms-win-core-winrt-error-l1-1-0.dll", "RoOriginateError");
  222. if (RoOriginateError == NULL)
  223. {
  224. // We're running on Win7 or below. Give up.
  225. return;
  226. }
  227. }
  228. RoOriginateError(hresult, message);
  229. #else
  230. RoOriginateError(hresult, reinterpret_cast<HSTRING>(message));
  231. #endif
  232. }
  233. #if !IL2CPP_TARGET_XBOXONE
  234. inline void OriginateLanguageExceptionWithFallback(il2cpp_hresult_t hresult, Il2CppException* ex, Il2CppHString message, WindowsRuntime::GetOrCreateFunc createCCWCallback)
  235. {
  236. #if !LINK_TO_WINDOWSRUNTIME_LIBS
  237. typedef BOOL(STDAPICALLTYPE * RoOriginateLanguageExceptionFunc)(il2cpp_hresult_t error, Il2CppHString message, Il2CppIUnknown* languageException);
  238. static RoOriginateLanguageExceptionFunc RoOriginateLanguageException = NULL;
  239. if (RoOriginateLanguageException == NULL)
  240. {
  241. RoOriginateLanguageException = ResolveAPI<RoOriginateLanguageExceptionFunc>(L"api-ms-win-core-winrt-error-l1-1-1.dll", "RoOriginateLanguageException");
  242. if (RoOriginateLanguageException == NULL)
  243. {
  244. // We're running on Win8 or below. Fallback to RoOriginateError
  245. OriginateErrorNoLanguageException(hresult, message);
  246. return;
  247. }
  248. }
  249. #endif
  250. Il2CppIUnknown* exceptionCCW = createCCWCallback(reinterpret_cast<Il2CppObject*>(ex), Il2CppIUnknown::IID);
  251. #if LINK_TO_WINDOWSRUNTIME_LIBS
  252. RoOriginateLanguageException(hresult, reinterpret_cast<HSTRING>(static_cast<Il2CppHString>(message)), reinterpret_cast<IUnknown*>(exceptionCCW));
  253. #else
  254. RoOriginateLanguageException(hresult, message, exceptionCCW);
  255. #endif
  256. exceptionCCW->Release();
  257. }
  258. #endif // !IL2CPP_TARGET_XBOXONE
  259. void WindowsRuntime::OriginateLanguageException(il2cpp_hresult_t hresult, Il2CppException* ex, Il2CppString* exceptionString, GetOrCreateFunc createCCWCallback)
  260. {
  261. utils::StringView<Il2CppNativeChar> message(utils::StringUtils::GetChars(exceptionString), utils::StringUtils::GetLength(exceptionString));
  262. Il2CppHString messageHString;
  263. Il2CppHStringHeader unused;
  264. CreateHStringReference(message, &unused, &messageHString);
  265. #if IL2CPP_TARGET_XBOXONE
  266. OriginateErrorNoLanguageException(hresult, messageHString);
  267. #else
  268. OriginateLanguageExceptionWithFallback(hresult, ex, messageHString, createCCWCallback);
  269. #endif
  270. }
  271. void WindowsRuntime::EnableErrorReporting()
  272. {
  273. #if !LINK_TO_WINDOWSRUNTIME_LIBS
  274. typedef il2cpp_hresult_t (STDCALL * RoSetErrorReportingFlagsFunc)(uint32_t flags);
  275. static RoSetErrorReportingFlagsFunc RoSetErrorReportingFlags = NULL;
  276. if (RoSetErrorReportingFlags == NULL)
  277. {
  278. RoSetErrorReportingFlags = ResolveAPI<RoSetErrorReportingFlagsFunc>(L"api-ms-win-core-winrt-error-l1-1-0.dll", "RoSetErrorReportingFlags");
  279. // We're running on Win7 or below. Do nothing
  280. if (RoSetErrorReportingFlags == NULL)
  281. return;
  282. }
  283. const int RO_ERROR_REPORTING_USESETERRORINFO = 0x00000004;
  284. #endif
  285. il2cpp_hresult_t hr = RoSetErrorReportingFlags(RO_ERROR_REPORTING_USESETERRORINFO);
  286. IL2CPP_ASSERT(IL2CPP_HR_SUCCEEDED(hr) && "RoSetErrorReportingFlags failed");
  287. }
  288. }
  289. }
  290. #endif