summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs')
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs128
1 files changed, 96 insertions, 32 deletions
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
index 6fb631121b..03750bcb8b 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
@@ -15,13 +15,13 @@
namespace System.Runtime.InteropServices
{
using System;
+ using System.Runtime;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Security;
using System.Text;
using System.Threading;
- using System.Runtime.Remoting;
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Runtime.ConstrainedExecution;
@@ -31,8 +31,8 @@ namespace System.Runtime.InteropServices
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices.ComTypes;
+ using System.StubHelpers;
- [Serializable]
public enum CustomQueryInterfaceMode
{
Ignore = 0,
@@ -406,9 +406,9 @@ namespace System.Runtime.InteropServices
//====================================================================
// Read from memory
//====================================================================
- public static byte ReadByte([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
+ public static byte ReadByte(Object ptr, int ofs)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadByte(nativeHome, offset));
}
public static unsafe byte ReadByte(IntPtr ptr, int ofs)
@@ -430,9 +430,9 @@ namespace System.Runtime.InteropServices
return ReadByte(ptr, 0);
}
- public static short ReadInt16([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
+ public static short ReadInt16(Object ptr, int ofs)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadInt16(nativeHome, offset));
}
public static unsafe short ReadInt16(IntPtr ptr, int ofs)
@@ -467,9 +467,9 @@ namespace System.Runtime.InteropServices
return ReadInt16(ptr, 0);
}
- public static int ReadInt32([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
+ public static int ReadInt32(object ptr, int ofs)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadInt32(nativeHome, offset));
}
public static unsafe int ReadInt32(IntPtr ptr, int ofs)
@@ -506,7 +506,7 @@ namespace System.Runtime.InteropServices
return ReadInt32(ptr, 0);
}
- public static IntPtr ReadIntPtr([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
+ public static IntPtr ReadIntPtr(Object ptr, int ofs)
{
#if BIT64
return (IntPtr)ReadInt64(ptr, ofs);
@@ -535,7 +535,7 @@ namespace System.Runtime.InteropServices
public static long ReadInt64([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadInt64(nativeHome, offset));
}
public static unsafe long ReadInt64(IntPtr ptr, int ofs)
@@ -576,6 +576,41 @@ namespace System.Runtime.InteropServices
return ReadInt64(ptr, 0);
}
+ //====================================================================
+ // Read value from marshaled object (marshaled using AsAny)
+ // It's quite slow and can return back dangling pointers
+ // It's only there for backcompact
+ // I don't think we should spend time optimizing it
+ // People should really call the IntPtr overload instead
+ //====================================================================
+ private static unsafe T ReadValueSlow<T>(object ptr, int ofs, Func<IntPtr, int, T> readValueHelper)
+ {
+ // We AV on desktop if passing NULL. So this is technically a breaking change but is an improvement
+ if (ptr == null)
+ throw new ArgumentNullException(nameof(ptr));
+
+ int dwFlags =
+ (int)AsAnyMarshaler.AsAnyFlags.In |
+ (int)AsAnyMarshaler.AsAnyFlags.IsAnsi |
+ (int)AsAnyMarshaler.AsAnyFlags.IsBestFit;
+
+ MngdNativeArrayMarshaler.MarshalerState nativeArrayMarshalerState = new MngdNativeArrayMarshaler.MarshalerState();
+ AsAnyMarshaler marshaler = new AsAnyMarshaler(new IntPtr(&nativeArrayMarshalerState));
+
+ IntPtr pNativeHome = IntPtr.Zero;
+
+ try
+ {
+ pNativeHome = marshaler.ConvertToNative(ptr, dwFlags);
+ return readValueHelper(pNativeHome, ofs);
+ }
+ finally
+ {
+ marshaler.ClearNative(pNativeHome);
+ }
+ }
+
+
//====================================================================
// Write to memory
@@ -594,9 +629,9 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteByte([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, byte val)
+ public static void WriteByte(Object ptr, int ofs, byte val)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, byte value) => Marshal.WriteByte(nativeHome, offset, value));
}
public static void WriteByte(IntPtr ptr, byte val)
@@ -629,9 +664,9 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteInt16([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, short val)
+ public static void WriteInt16(Object ptr, int ofs, short val)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, short value) => Marshal.WriteInt16(nativeHome, offset, value));
}
public static void WriteInt16(IntPtr ptr, short val)
@@ -681,9 +716,9 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteInt32([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, int val)
+ public static void WriteInt32(Object ptr, int ofs, int val)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, int value) => Marshal.WriteInt32(nativeHome, offset, value));
}
public static void WriteInt32(IntPtr ptr, int val)
@@ -700,7 +735,7 @@ namespace System.Runtime.InteropServices
#endif
}
- public static void WriteIntPtr([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, IntPtr val)
+ public static void WriteIntPtr(Object ptr, int ofs, IntPtr val)
{
#if BIT64
WriteInt64(ptr, ofs, (long)val);
@@ -749,9 +784,9 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteInt64([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, long val)
+ public static void WriteInt64(Object ptr, int ofs, long val)
{
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
+ WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, long value) => Marshal.WriteInt64(nativeHome, offset, value));
}
public static void WriteInt64(IntPtr ptr, long val)
@@ -759,6 +794,41 @@ namespace System.Runtime.InteropServices
WriteInt64(ptr, 0, val);
}
+ //====================================================================
+ // Write value into marshaled object (marshaled using AsAny) and
+ // propagate the value back
+ // It's quite slow and is only there for backcompact
+ // I don't think we should spend time optimizing it
+ // People should really call the IntPtr overload instead
+ //====================================================================
+ private static unsafe void WriteValueSlow<T>(object ptr, int ofs, T val, Action<IntPtr, int, T> writeValueHelper)
+ {
+ // We AV on desktop if passing NULL. So this is technically a breaking change but is an improvement
+ if (ptr == null)
+ throw new ArgumentNullException(nameof(ptr));
+
+ int dwFlags =
+ (int)AsAnyMarshaler.AsAnyFlags.In |
+ (int)AsAnyMarshaler.AsAnyFlags.Out |
+ (int)AsAnyMarshaler.AsAnyFlags.IsAnsi |
+ (int)AsAnyMarshaler.AsAnyFlags.IsBestFit;
+
+ MngdNativeArrayMarshaler.MarshalerState nativeArrayMarshalerState = new MngdNativeArrayMarshaler.MarshalerState();
+ AsAnyMarshaler marshaler = new AsAnyMarshaler(new IntPtr(&nativeArrayMarshalerState));
+
+ IntPtr pNativeHome = IntPtr.Zero;
+
+ try
+ {
+ pNativeHome = marshaler.ConvertToNative(ptr, dwFlags);
+ writeValueHelper(pNativeHome, ofs, val);
+ marshaler.ConvertToManaged(ptr, pNativeHome);
+ }
+ finally
+ {
+ marshaler.ClearNative(pNativeHome);
+ }
+ }
//====================================================================
// GetLastWin32Error
@@ -1772,11 +1842,7 @@ namespace System.Runtime.InteropServices
}
Contract.EndContractBlock();
-#if FEATURE_COMINTEROP
return s.MarshalToBSTR();
-#else
- throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10443
-#endif
}
public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s)
@@ -1800,30 +1866,28 @@ namespace System.Runtime.InteropServices
return s.MarshalToString(globalAlloc: false, unicode: true);
}
-
-#if FEATURE_COMINTEROP
+
public static void ZeroFreeBSTR(IntPtr s)
{
- Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.SysStringLen(s) * 2));
+ RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.SysStringLen(s) * 2));
FreeBSTR(s);
}
-#endif
public static void ZeroFreeCoTaskMemAnsi(IntPtr s)
{
- Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
+ RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
FreeCoTaskMem(s);
}
public static void ZeroFreeCoTaskMemUnicode(IntPtr s)
{
- Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
+ RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
FreeCoTaskMem(s);
}
unsafe public static void ZeroFreeCoTaskMemUTF8(IntPtr s)
{
- Win32Native.ZeroMemory(s, (UIntPtr)System.StubHelpers.StubHelpers.strlen((sbyte*)s));
+ RuntimeImports.RhZeroMemory(s, (UIntPtr)System.StubHelpers.StubHelpers.strlen((sbyte*)s));
FreeCoTaskMem(s);
}
@@ -1851,13 +1915,13 @@ namespace System.Runtime.InteropServices
public static void ZeroFreeGlobalAllocAnsi(IntPtr s)
{
- Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
+ RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
FreeHGlobal(s);
}
public static void ZeroFreeGlobalAllocUnicode(IntPtr s)
{
- Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
+ RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
FreeHGlobal(s);
}
}