{
if (s == null)
throw new ArgumentNullException ("s");
- int len = s.Length;
- IntPtr ctm = AllocCoTaskMem ((len+1) * 2 + 4);
- byte [] buffer = null;
- WriteInt32 (ctm, 0, len*2);
- try {
- buffer = s.GetBuffer ();
- for (int i = 0; i < len; i++)
- WriteInt16 (ctm, 4 + (i * 2), (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
- WriteInt16 (ctm, 4 + buffer.Length, 0);
- } finally {
- if (buffer != null)
- for (int i = buffer.Length; i > 0; ){
- i--;
- buffer [i] = 0;
- }
+ byte[] buffer = s.GetBuffer ();
+ int len = s.Length;
+
+ // SecureString doesn't take endian-ness into account.
+ // Therefore swap bytes here before we send it to c-side if little-endian.
+ if (BitConverter.IsLittleEndian) {
+ for (int i = 0; i < buffer.Length; i += 2) {
+ byte b = buffer[i];
+ buffer[i] = buffer[i + 1];
+ buffer[i + 1] = b;
+ }
}
- return (IntPtr) ((long)ctm + 4);
- }
+ return BufferToBSTR (buffer, len);
+ }
public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
{
throw ex;
}
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern static IntPtr BufferToBSTR (Array ptr, int slen);
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
mono_register_jit_icall (func, name, sig, save);
}
+gpointer
+mono_string_to_bstr(MonoString* ptr)
+{
+ if (!ptr)
+ return NULL;
+
+ return mono_ptr_to_bstr(mono_string_chars(ptr), mono_string_length(ptr));
+}
+
#ifndef DISABLE_COM
#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
}
gpointer
-mono_string_to_bstr (MonoString *string_obj)
+mono_ptr_to_bstr(gpointer ptr, int slen)
{
- if (!string_obj)
+ if (!ptr)
return NULL;
#ifdef HOST_WIN32
- return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+ return SysAllocStringLen (ptr, slen);
#else
if (com_provider == MONO_COM_DEFAULT) {
- int slen = mono_string_length (string_obj);
/* allocate len + 1 utf16 characters plus 4 byte integer for length*/
- char *ret = (char *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
+ char *ret = (char *)g_malloc((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
if (ret == NULL)
return NULL;
- memcpy (ret + sizeof(guint32), mono_string_chars (string_obj), slen * sizeof(gunichar2));
- * ((guint32 *) ret) = slen * sizeof(gunichar2);
- ret [4 + slen * sizeof(gunichar2)] = 0;
- ret [5 + slen * sizeof(gunichar2)] = 0;
+ memcpy(ret + sizeof(guint32), ptr, slen * sizeof(gunichar2));
+ *((guint32 *)ret) = slen * sizeof(gunichar2);
+ ret[4 + slen * sizeof(gunichar2)] = 0;
+ ret[5 + slen * sizeof(gunichar2)] = 0;
return ret + 4;
- } else if (com_provider == MONO_COM_MS && init_com_provider_ms ()) {
+ }
+ else if (com_provider == MONO_COM_MS && init_com_provider_ms()) {
gpointer ret = NULL;
gunichar* str = NULL;
- guint32 len;
- len = mono_string_length (string_obj);
- str = g_utf16_to_ucs4 (mono_string_chars (string_obj), len,
+ guint32 len = slen;
+ str = g_utf16_to_ucs4(ptr, len,
NULL, NULL, NULL);
- ret = sys_alloc_string_len_ms (str, len);
+ ret = sys_alloc_string_len_ms(str, len);
g_free(str);
return ret;
- } else {
- g_assert_not_reached ();
+ }
+ else {
+ g_assert_not_reached();
}
#endif
}
}
gpointer
-mono_string_to_bstr (MonoString *string_obj)
+mono_ptr_to_bstr (gpointer ptr, int slen)
{
- if (!string_obj)
+ if (!ptr)
return NULL;
#ifdef HOST_WIN32
- return SysAllocStringLen (mono_string_chars (string_obj), mono_string_length (string_obj));
+ return SysAllocStringLen (ptr, slen);
#else
{
- int slen = mono_string_length (string_obj);
/* allocate len + 1 utf16 characters plus 4 byte integer for length*/
char *ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
if (ret == NULL)
return NULL;
- memcpy (ret + sizeof(guint32), mono_string_chars (string_obj), slen * sizeof(gunichar2));
+ memcpy (ret + sizeof(guint32), ptr, slen * sizeof(gunichar2));
* ((guint32 *) ret) = slen * sizeof(gunichar2);
ret [4 + slen * sizeof(gunichar2)] = 0;
ret [5 + slen * sizeof(gunichar2)] = 0;
return mono_string_to_bstr(ptr);
}
+gpointer
+ves_icall_System_Runtime_InteropServices_Marshal_BufferToBSTR (MonoArray* ptr, int len)
+{
+ return mono_ptr_to_bstr (ptr->vector, len);
+}
+
void
ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR (gpointer ptr)
{
#endif
ICALL(MARSHAL_2, "AllocCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem)
ICALL(MARSHAL_3, "AllocHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal)
+ICALL(MARSHAL_50, "BufferToBSTR", ves_icall_System_Runtime_InteropServices_Marshal_BufferToBSTR)
ICALL(MARSHAL_4, "DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure)
ICALL(MARSHAL_5, "FreeBSTR", ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR)
ICALL(MARSHAL_6, "FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem)
ICALL(MARSHAL_33, "StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni)
ICALL(MARSHAL_34, "StructureToPtr", ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr)
ICALL(MARSHAL_35, "UnsafeAddrOfPinnedArrayElement", ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement)
+
ICALL(MARSHAL_41, "copy_from_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged)
ICALL(MARSHAL_42, "copy_to_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged)