/** * \file * Windows marshal 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 #include "mono/metadata/marshal-windows-internals.h" #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) void* mono_marshal_alloc_hglobal (size_t size) { return GlobalAlloc (GMEM_FIXED, size); } gpointer mono_marshal_realloc_hglobal (gpointer ptr, size_t size) { return GlobalReAlloc (ptr, size, GMEM_MOVEABLE); } void mono_marshal_free_hglobal (gpointer ptr) { GlobalFree (ptr); return; } #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */ void* mono_marshal_alloc_co_task_mem (size_t size) { return CoTaskMemAlloc (size); } void mono_marshal_free_co_task_mem (void *ptr) { CoTaskMemFree (ptr); return; } gpointer mono_marshal_realloc_co_task_mem (gpointer ptr, size_t size) { return CoTaskMemRealloc (ptr, size); } gpointer ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string) { MonoError error; char* tres, *ret; size_t len; tres = mono_string_to_utf8_checked (string, &error); if (mono_error_set_pending_exception (&error)) return NULL; if (!tres) return tres; /* * mono_string_to_utf8_checked() returns a memory area at least as large as the size of the * MonoString, even if it contains NULL characters. The copy we allocate here has to be equally * large. */ len = MAX (strlen (tres) + 1, string->length); ret = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal ((gpointer)len); memcpy (ret, tres, len); g_free (tres); return ret; } gpointer ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString *string) { if (string == NULL) return NULL; else { size_t len = ((mono_string_length (string) + 1) * 2); gunichar2 *res = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal ((gpointer)len); memcpy (res, mono_string_chars (string), mono_string_length (string) * 2); res [mono_string_length (string)] = 0; return res; } } gpointer mono_string_to_utf8str (MonoString *s) { char *as, *tmp; glong len; GError *error = NULL; if (s == NULL) return NULL; if (!s->length) { as = CoTaskMemAlloc (1); as [0] = '\0'; return as; } tmp = g_utf16_to_utf8 (mono_string_chars (s), s->length, NULL, &len, &error); if (error) { MonoException *exc = mono_get_exception_argument ("string", error->message); g_error_free (error); mono_set_pending_exception (exc); return NULL; } else { as = CoTaskMemAlloc (len + 1); memcpy (as, tmp, len + 1); g_free (tmp); return as; } } #endif /* HOST_WIN32 */