icall-windows.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /**
  2. * \file
  3. * Windows icall support.
  4. *
  5. * Copyright 2016 Microsoft
  6. * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  7. */
  8. #include <config.h>
  9. #include <glib.h>
  10. #if defined(HOST_WIN32)
  11. #include <winsock2.h>
  12. #include <windows.h>
  13. #include <mono/metadata/icall-internals.h>
  14. #include <mono/utils/w32subset.h>
  15. void
  16. mono_icall_make_platform_path (gchar *path)
  17. {
  18. for (size_t i = strlen (path); i > 0; i--)
  19. if (path [i-1] == '\\')
  20. path [i-1] = '/';
  21. }
  22. const gchar *
  23. mono_icall_get_file_path_prefix (const gchar *path)
  24. {
  25. if (*path == '/' && *(path + 1) == '/') {
  26. return "file:";
  27. } else {
  28. return "file:///";
  29. }
  30. }
  31. gpointer
  32. mono_icall_module_get_hinstance (MonoImage *image)
  33. {
  34. if (image && m_image_is_module_handle (image))
  35. return image->raw_data;
  36. return (gpointer) (-1);
  37. }
  38. #if HAVE_API_SUPPORT_WIN32_GET_COMPUTER_NAME
  39. MonoStringHandle
  40. mono_icall_get_machine_name (MonoError *error)
  41. {
  42. gunichar2 buf [MAX_COMPUTERNAME_LENGTH + 1];
  43. DWORD len = G_N_ELEMENTS (buf);
  44. if (GetComputerNameW (buf, &len))
  45. return mono_string_new_utf16_handle (mono_domain_get (), buf, len, error);
  46. return MONO_HANDLE_NEW (MonoString, NULL);
  47. }
  48. #elif !HAVE_EXTERN_DEFINED_WIN32_GET_COMPUTER_NAME
  49. MonoStringHandle
  50. mono_icall_get_machine_name (MonoError *error)
  51. {
  52. g_unsupported_api ("GetComputerName");
  53. return mono_string_new_handle (mono_domain_get (), "mono", error);
  54. }
  55. #endif
  56. int
  57. mono_icall_get_platform (void)
  58. {
  59. /* Win32NT */
  60. return 2;
  61. }
  62. MonoStringHandle
  63. mono_icall_get_new_line (MonoError *error)
  64. {
  65. return mono_string_new_handle (mono_domain_get (), "\r\n", error);
  66. }
  67. MonoBoolean
  68. mono_icall_is_64bit_os (void)
  69. {
  70. #if SIZEOF_VOID_P == 8
  71. return TRUE;
  72. #else
  73. gboolean isWow64Process = FALSE;
  74. if (IsWow64Process (GetCurrentProcess (), &isWow64Process)) {
  75. return (MonoBoolean)isWow64Process;
  76. }
  77. return FALSE;
  78. #endif
  79. }
  80. MonoArrayHandle
  81. mono_icall_get_environment_variable_names (MonoError *error)
  82. {
  83. MonoArrayHandle names;
  84. MonoDomain *domain;
  85. MonoStringHandle str;
  86. WCHAR* env_strings;
  87. WCHAR* env_string;
  88. WCHAR* equal_str;
  89. int n = 0;
  90. env_strings = GetEnvironmentStrings();
  91. if (env_strings) {
  92. env_string = env_strings;
  93. while (*env_string != '\0') {
  94. /* weird case that MS seems to skip */
  95. if (*env_string != '=')
  96. n++;
  97. while (*env_string != '\0')
  98. env_string++;
  99. env_string++;
  100. }
  101. }
  102. domain = mono_domain_get ();
  103. names = mono_array_new_handle (domain, mono_defaults.string_class, n, error);
  104. return_val_if_nok (error, NULL_HANDLE_ARRAY);
  105. if (env_strings) {
  106. n = 0;
  107. str = MONO_HANDLE_NEW (MonoString, NULL);
  108. env_string = env_strings;
  109. while (*env_string != '\0') {
  110. /* weird case that MS seems to skip */
  111. if (*env_string != '=') {
  112. equal_str = wcschr(env_string, '=');
  113. g_assert(equal_str);
  114. MonoString *s = mono_string_new_utf16_checked (domain, env_string, (gint32)(equal_str - env_string), error);
  115. goto_if_nok (error, cleanup);
  116. MONO_HANDLE_ASSIGN_RAW (str, s);
  117. mono_array_handle_setref (names, n, str);
  118. n++;
  119. }
  120. while (*env_string != '\0')
  121. env_string++;
  122. env_string++;
  123. }
  124. }
  125. cleanup:
  126. if (env_strings)
  127. FreeEnvironmentStrings (env_strings);
  128. if (!is_ok (error))
  129. return NULL_HANDLE_ARRAY;
  130. return names;
  131. }
  132. #if HAVE_API_SUPPORT_WIN32_SH_GET_FOLDER_PATH
  133. #include <shlobj.h>
  134. MonoStringHandle
  135. mono_icall_get_windows_folder_path (int folder, MonoError *error)
  136. {
  137. error_init (error);
  138. #ifndef CSIDL_FLAG_CREATE
  139. #define CSIDL_FLAG_CREATE 0x8000
  140. #endif
  141. WCHAR path [MAX_PATH];
  142. /* Create directory if no existing */
  143. if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
  144. int len = 0;
  145. while (path [len])
  146. ++ len;
  147. return mono_string_new_utf16_handle (mono_domain_get (), path, len, error);
  148. }
  149. return mono_string_new_handle (mono_domain_get (), "", error);
  150. }
  151. #elif !HAVE_EXTERN_DEFINED_WIN32_SH_GET_FOLDER_PATH
  152. MonoStringHandle
  153. mono_icall_get_windows_folder_path (int folder, MonoError *error)
  154. {
  155. error_init (error);
  156. g_unsupported_api ("SHGetFolderPath");
  157. return mono_string_new_handle (mono_domain_get (), "", error);
  158. }
  159. #endif
  160. #if HAVE_API_SUPPORT_WIN32_SEND_MESSAGE_TIMEOUT
  161. ICALL_EXPORT void
  162. ves_icall_System_Environment_BroadcastSettingChange (MonoError *error)
  163. {
  164. SendMessageTimeoutW (HWND_BROADCAST, WM_SETTINGCHANGE, (WPARAM)NULL, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, 0);
  165. }
  166. #elif !HAVE_EXTERN_DEFINED_WIN32_SEND_MESSAGE_TIMEOUT
  167. ICALL_EXPORT void
  168. ves_icall_System_Environment_BroadcastSettingChange (MonoError *error)
  169. {
  170. g_unsupported_api ("SendMessageTimeout");
  171. mono_error_set_not_supported (error, G_UNSUPPORTED_API, "SendMessageTimeout");
  172. SetLastError (ERROR_NOT_SUPPORTED);
  173. }
  174. #endif
  175. #if HAVE_API_SUPPORT_WIN32_WAIT_FOR_INPUT_IDLE
  176. gint32
  177. mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
  178. {
  179. return WaitForInputIdle (handle, milliseconds);
  180. }
  181. #elif !HAVE_EXTERN_DEFINED_WIN32_WAIT_FOR_INPUT_IDLE
  182. gint32
  183. mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
  184. {
  185. ERROR_DECL (error);
  186. g_unsupported_api ("WaitForInputIdle");
  187. mono_error_set_not_supported (error, G_UNSUPPORTED_API, "WaitForInputIdle");
  188. mono_error_set_pending_exception (error);
  189. return WAIT_TIMEOUT;
  190. }
  191. #endif
  192. void
  193. mono_icall_write_windows_debug_string (const gunichar2 *message)
  194. {
  195. OutputDebugString (message);
  196. }
  197. #endif /* HOST_WIN32 */