/** * \file * Windows icall support. * * Copyright 2016 Microsoft * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include #if defined(HOST_WIN32) #include #include #include "mono/metadata/icall-windows-internals.h" #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) #include #endif void mono_icall_make_platform_path (gchar *path) { for (size_t i = strlen (path); i > 0; i--) if (path [i-1] == '\\') path [i-1] = '/'; } const gchar * mono_icall_get_file_path_prefix (const gchar *path) { if (*path == '/' && *(path + 1) == '/') { return "file:"; } else { return "file:///"; } } gpointer mono_icall_module_get_hinstance (MonoReflectionModuleHandle module) { MonoImage *image = MONO_HANDLE_GETVAL (module, image); if (image && image->is_module_handle) return image->raw_data; return (gpointer) (-1); } #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) MonoStringHandle mono_icall_get_machine_name (MonoError *error) { gunichar2 *buf; guint32 len; MonoStringHandle result; len = MAX_COMPUTERNAME_LENGTH + 1; buf = g_new (gunichar2, len); result = NULL; if (GetComputerName (buf, (PDWORD) &len)) { result = mono_string_new_utf16_handle (mono_domain_get (), buf, len, error); } else result = MONO_HANDLE_NEW (MonoString, NULL); g_free (buf); return result; } #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */ int mono_icall_get_platform (void) { /* Win32NT */ return 2; } MonoStringHandle mono_icall_get_new_line (MonoError *error) { error_init (error); return mono_string_new_handle (mono_domain_get (), "\r\n", error); } MonoBoolean mono_icall_is_64bit_os (void) { #if SIZEOF_VOID_P == 8 return TRUE; #else gboolean isWow64Process = FALSE; if (IsWow64Process (GetCurrentProcess (), &isWow64Process)) { return (MonoBoolean)isWow64Process; } return FALSE; #endif } MonoArray * mono_icall_get_environment_variable_names (MonoError *error) { MonoArray *names; MonoDomain *domain; MonoString *str; WCHAR* env_strings; WCHAR* env_string; WCHAR* equal_str; int n = 0; error_init (error); env_strings = GetEnvironmentStrings(); if (env_strings) { env_string = env_strings; while (*env_string != '\0') { /* weird case that MS seems to skip */ if (*env_string != '=') n++; while (*env_string != '\0') env_string++; env_string++; } } domain = mono_domain_get (); names = mono_array_new_checked (domain, mono_defaults.string_class, n, error); return_val_if_nok (error, NULL); if (env_strings) { n = 0; env_string = env_strings; while (*env_string != '\0') { /* weird case that MS seems to skip */ if (*env_string != '=') { equal_str = wcschr(env_string, '='); g_assert(equal_str); str = mono_string_new_utf16_checked (domain, env_string, (gint32)(equal_str - env_string), error); if (!is_ok (error)) goto cleanup; mono_array_setref (names, n, str); n++; } while (*env_string != '\0') env_string++; env_string++; } } cleanup: if (env_strings) FreeEnvironmentStrings (env_strings); if (!is_ok (error)) return NULL; return names; } void mono_icall_set_environment_variable (MonoString *name, MonoString *value) { gunichar2 *utf16_name, *utf16_value; utf16_name = mono_string_to_utf16 (name); if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) { SetEnvironmentVariable (utf16_name, NULL); g_free (utf16_name); return; } utf16_value = mono_string_to_utf16 (value); SetEnvironmentVariable (utf16_name, utf16_value); g_free (utf16_name); g_free (utf16_value); } #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) MonoStringHandle mono_icall_get_windows_folder_path (int folder, MonoError *error) { error_init (error); #ifndef CSIDL_FLAG_CREATE #define CSIDL_FLAG_CREATE 0x8000 #endif WCHAR path [MAX_PATH]; /* Create directory if no existing */ if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) { int len = 0; while (path [len]) ++ len; return mono_string_new_utf16_handle (mono_domain_get (), path, len, error); } return mono_string_new_handle (mono_domain_get (), "", error); } #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */ #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) MonoBoolean mono_icall_broadcast_setting_change (MonoError *error) { error_init (error); SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, (WPARAM)NULL, (LPARAM)L"Environment", SMTO_ABORTIFHUNG, 2000, 0); return TRUE; } gint32 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds) { return WaitForInputIdle (handle, milliseconds); } #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */ void mono_icall_write_windows_debug_string (MonoString *message) { OutputDebugString (mono_string_chars (message)); } #endif /* HOST_WIN32 */