Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / metadata / marshal-windows.c
1 /**
2  * \file
3  * Windows marshal 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
11 #if defined(HOST_WIN32)
12 #include <winsock2.h>
13 #include <windows.h>
14 #include <objbase.h>
15 #include "mono/metadata/marshal-windows-internals.h"
16
17 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
18 void*
19 mono_marshal_alloc_hglobal (size_t size)
20 {
21         return GlobalAlloc (GMEM_FIXED, size);
22 }
23
24 gpointer
25 mono_marshal_realloc_hglobal (gpointer ptr, size_t size)
26 {
27         return GlobalReAlloc (ptr, size, GMEM_MOVEABLE);
28 }
29
30 void
31 mono_marshal_free_hglobal (gpointer ptr)
32 {
33         GlobalFree (ptr);
34         return;
35 }
36 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
37
38 void*
39 mono_marshal_alloc_co_task_mem (size_t size)
40 {
41         return CoTaskMemAlloc (size);
42 }
43
44 void
45 mono_marshal_free_co_task_mem (void *ptr)
46 {
47         CoTaskMemFree (ptr);
48         return;
49 }
50
51 gpointer
52 mono_marshal_realloc_co_task_mem (gpointer ptr, size_t size)
53 {
54         return CoTaskMemRealloc (ptr, size);
55 }
56
57 gpointer
58 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string)
59 {
60         MonoError error;
61         char* tres, *ret;
62         size_t len;
63         tres = mono_string_to_utf8_checked (string, &error);
64         if (mono_error_set_pending_exception (&error))
65                 return NULL;
66         if (!tres)
67                 return tres;
68
69         /*
70          * mono_string_to_utf8_checked() returns a memory area at least as large as the size of the
71          * MonoString, even if it contains NULL characters. The copy we allocate here has to be equally
72          * large.
73          */
74         len = MAX (strlen (tres) + 1, string->length);
75         ret = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal ((gpointer)len);
76         memcpy (ret, tres, len);
77         g_free (tres);
78         return ret;
79 }
80
81 gpointer
82 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString *string)
83 {
84         if (string == NULL)
85                 return NULL;
86         else {
87                 size_t len = ((mono_string_length (string) + 1) * 2);
88                 gunichar2 *res = ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal ((gpointer)len);
89
90                 memcpy (res, mono_string_chars (string), mono_string_length (string) * 2);
91                 res [mono_string_length (string)] = 0;
92                 return res;
93         }
94 }
95
96 gpointer
97 mono_string_to_utf8str (MonoString *s)
98 {
99         char *as, *tmp;
100         glong len;
101         GError *error = NULL;
102
103         if (s == NULL)
104                 return NULL;
105
106         if (!s->length) {
107                 as = CoTaskMemAlloc (1);
108                 as [0] = '\0';
109                 return as;
110         }
111
112         tmp = g_utf16_to_utf8 (mono_string_chars (s), s->length, NULL, &len, &error);
113         if (error) {
114                 MonoException *exc = mono_get_exception_argument ("string", error->message);
115                 g_error_free (error);
116                 mono_set_pending_exception (exc);
117                 return NULL;
118         } else {
119                 as = CoTaskMemAlloc (len + 1);
120                 memcpy (as, tmp, len + 1);
121                 g_free (tmp);
122                 return as;
123         }
124 }
125
126 #endif /* HOST_WIN32 */