Merge pull request #944 from ermshiperete/bug-novell-496138
[mono.git] / mcs / class / corlib / System.Runtime.InteropServices / Marshal.cs
index fa0344c771e185b9b0bf8ce078f780851b8e666d..243984706ceaaf1c27f77ccacd711eaf450bcce6 100644 (file)
@@ -31,6 +31,7 @@
 //
 
 using System.Collections;
+using System.Collections.Generic;
 using System.Runtime.CompilerServices;
 using System;
 using System.Security;
@@ -38,36 +39,33 @@ using System.Reflection;
 using System.Threading;
 
 using System.Runtime.ConstrainedExecution;
-#if !MOONLIGHT
+#if !FULL_AOT_RUNTIME
 using System.Runtime.InteropServices.ComTypes;
-#endif
-
-#if !MOONLIGHT
 using Mono.Interop;
 #endif
 
 namespace System.Runtime.InteropServices
 {
-       [SuppressUnmanagedCodeSecurity ()]
        public static class Marshal
        {
                /* fields */
                public static readonly int SystemMaxDBCSCharSize = 2; // don't know what this is
-               public static readonly int SystemDefaultCharSize;
-
-               static Marshal ()
-               {
-                       SystemDefaultCharSize = Environment.OSVersion.Platform == PlatformID.Win32NT ? 2 : 1;
-               }
+               public static readonly int SystemDefaultCharSize = Environment.IsRunningOnWindows ? 2 : 1;
 
+#if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static int AddRefInternal (IntPtr pUnk);
+#endif
 
                public static int AddRef (IntPtr pUnk)
                {
+#if !MOBILE
                        if (pUnk == IntPtr.Zero)
                                throw new ArgumentException ("Value cannot be null.", "pUnk");
                        return AddRefInternal (pUnk);
+#else
+                       throw new NotImplementedException ();
+#endif
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -189,7 +187,13 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-#if !MOONLIGHT
+#if NET_4_5
+               public static IntPtr CreateAggregatedObject<T> (IntPtr pOuter, T o) {
+                       return CreateAggregatedObject (pOuter, (object)o);
+               }
+#endif
+
+#if !FULL_AOT_RUNTIME
                public static object CreateWrapperOfType (object o, Type t)
                {
                        __ComObject co = o as __ComObject;
@@ -206,12 +210,24 @@ namespace System.Runtime.InteropServices
 
                        return ComInteropProxy.GetProxy (co.IUnknown, t).GetTransparentProxy ();
                }
+
+#if NET_4_5
+               public static TWrapper CreateWrapperOfType<T, TWrapper> (T o) {
+                       return (TWrapper)CreateWrapperOfType ((object)o, typeof (TWrapper));
+               }
+#endif
 #endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                [ComVisible (true)]
                public extern static void DestroyStructure (IntPtr ptr, Type structuretype);
 
+#if NET_4_5
+               public static void DestroyStructure<T> (IntPtr ptr) {
+                       DestroyStructure (ptr, typeof (T));
+               }
+#endif                 
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void FreeBSTR (IntPtr ptr);
 
@@ -272,16 +288,33 @@ namespace System.Runtime.InteropServices
                        FreeHGlobal (s);
                }
 
-#if !MOONLIGHT
+#if !FULL_AOT_RUNTIME
                public static Guid GenerateGuidForType (Type type)
                {
                        return type.GUID;
                }
 
-               [MonoTODO]
                public static string GenerateProgIdForType (Type type)
                {
-                       throw new NotImplementedException ();
+                       IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (type);
+
+                       foreach (var a in attrs)
+                       {
+                               var dt = a.Constructor.DeclaringType;
+                               string name = dt.Name;
+                               if (name == "ProgIdAttribute")
+                               {
+                                       var args = a.ConstructorArguments;
+                                       string text = a.ConstructorArguments[0].Value as string;
+                                       if (text == null)
+                                       {
+                                               text = string.Empty;
+                                       }
+                                       return text;
+                               }
+                       }
+
+                       return type.FullName;
                }
 
                [MonoTODO]
@@ -290,6 +323,7 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
+#if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static IntPtr GetCCW (object o, Type T);
 
@@ -300,13 +334,24 @@ namespace System.Runtime.InteropServices
                        else
                                return GetCCW (o, T);
                }
+#endif
 
                public static IntPtr GetComInterfaceForObject (object o, Type T)
                {
+#if !MOBILE
                        IntPtr pItf = GetComInterfaceForObjectInternal (o, T);
                        AddRef (pItf);
                        return pItf;
+#else
+                       throw new NotImplementedException ();
+#endif
+               }
+
+#if NET_4_5
+               public static IntPtr GetComInterfaceForObject<T, TInterface> (T o) {
+                       return GetComInterfaceForObject ((object)o, typeof (T));
                }
+#endif                 
 
                [MonoTODO]
                public static IntPtr GetComInterfaceForObjectInContext (object o, Type t)
@@ -320,11 +365,14 @@ namespace System.Runtime.InteropServices
                        throw new NotSupportedException ("MSDN states user code should never need to call this method.");
                }
 
+#if !MOBILE
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern static int GetComSlotForMethodInfoInternal (MemberInfo m);
+#endif
 
                public static int GetComSlotForMethodInfo (MemberInfo m)
                {
+#if !MOBILE
                        if (m == null)
                                throw new ArgumentNullException ("m");
                        if (!(m is MethodInfo))
@@ -332,6 +380,9 @@ namespace System.Runtime.InteropServices
                        if (!m.DeclaringType.IsInterface)
                                throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
                        return GetComSlotForMethodInfoInternal (m);
+#else
+                       throw new NotImplementedException ();
+#endif
                }
 
                [MonoTODO]
@@ -360,11 +411,14 @@ namespace System.Runtime.InteropServices
 
                        return m.GetHINSTANCE ();
                }
-#endif // !NET_2_1
+#endif // !FULL_AOT_RUNTIME
 
-               [MonoTODO ("SetErrorInfo")]
+#if !FULL_AOT_RUNTIME
                public static int GetHRForException (Exception e)
                {
+                       var errorInfo = new ManagedErrorInfo(e);
+                       SetErrorInfo (0, errorInfo);
+
                        return e.hresult;
                }
 
@@ -374,7 +428,7 @@ namespace System.Runtime.InteropServices
                {
                        throw new NotImplementedException ();
                }
-#if !MOONLIGHT
+
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static IntPtr GetIDispatchForObjectInternal (object o);
 
@@ -435,11 +489,20 @@ namespace System.Runtime.InteropServices
                        Marshal.StructureToPtr(vt, pDstNativeVariant, false);
                }
 
+#if NET_4_5
+               public static void GetNativeVariantForObject<T> (T obj, IntPtr pDstNativeVariant) {
+                       GetNativeVariantForObject ((object)obj, pDstNativeVariant);
+               }
+#endif
+
+#if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private static extern object GetObjectForCCW (IntPtr pUnk);
+#endif
 
                public static object GetObjectForIUnknown (IntPtr pUnk)
                {
+#if !MOBILE
                        object obj = GetObjectForCCW (pUnk);
                        // was not a CCW
                        if (obj == null) {
@@ -447,6 +510,9 @@ namespace System.Runtime.InteropServices
                                obj = proxy.GetTransparentProxy ();
                        }
                        return obj;
+#else
+                       throw new NotImplementedException ();
+#endif
                }
 
                public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant)
@@ -455,6 +521,13 @@ namespace System.Runtime.InteropServices
                        return vt.GetValue();
                }
 
+#if NET_4_5
+               public static T GetObjectForNativeVariant<T> (IntPtr pSrcNativeVariant) {
+                       Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
+                       return (T)vt.GetValue();
+               }
+#endif
+
                public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars)
                {
                        if (cVars < 0)
@@ -466,6 +539,18 @@ namespace System.Runtime.InteropServices
                        return objects;
                }
 
+#if NET_4_5
+               public static T[] GetObjectsForNativeVariants<T> (IntPtr aSrcNativeVariant, int cVars) {
+                       if (cVars < 0)
+                               throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
+                       T[] objects = new T[cVars];
+                       for (int i = 0; i < cVars; i++)
+                               objects[i] = GetObjectForNativeVariant<T> ((IntPtr)(aSrcNativeVariant.ToInt64 () +
+                                       i * SizeOf (typeof(Variant))));
+                       return objects;
+               }
+#endif
+
                [MonoTODO]
                public static int GetStartComSlot (Type t)
                {
@@ -498,6 +583,14 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
+#if NET_4_5
+               public static Type GetTypeFromCLSID (Guid clsid)
+               {
+                       throw new NotImplementedException ();                   
+               }
+#endif
+
+#if !FULL_AOT_RUNTIME
                [Obsolete]
                [MonoTODO]
                public static string GetTypeInfoName (UCOMITypeInfo pTI)
@@ -565,6 +658,7 @@ namespace System.Runtime.InteropServices
                {
                        throw new NotImplementedException ();
                }
+#endif
 
                [MonoTODO]
                [Obsolete ("This method has been deprecated")]
@@ -573,8 +667,15 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
+#if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static bool IsComObject (object o);
+#else
+               public static bool IsComObject (object o)
+               {
+                       throw new NotImplementedException ();
+               }
+#endif         
 
                [MonoTODO]
                public static bool IsTypeVisibleFromCom (Type t)
@@ -587,7 +688,7 @@ namespace System.Runtime.InteropServices
                {
                        throw new NotImplementedException ();
                }
-#endif // !NET_2_1
+#endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
@@ -596,6 +697,12 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr OffsetOf (Type t, string fieldName);
 
+#if NET_4_5
+               public static IntPtr OffsetOf<T> (string fieldName) {
+                       return OffsetOf (typeof (T), fieldName);
+               }
+#endif
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void Prelink (MethodInfo m);
 
@@ -626,8 +733,15 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static string PtrToStringUni (IntPtr ptr, int len);
 
+#if !MOBILE
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static string PtrToStringBSTR (IntPtr ptr);
+#else
+               public static string PtrToStringBSTR (IntPtr ptr)
+               {
+                       throw new NotImplementedException ();
+               }
+#endif
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                [ComVisible (true)]
@@ -637,73 +751,151 @@ namespace System.Runtime.InteropServices
                [ComVisible (true)]
                public extern static object PtrToStructure (IntPtr ptr, Type structureType);
 
+#if NET_4_5
+               public static void PtrToStructure<T> (IntPtr ptr, T structure) {
+                       PtrToStructure (ptr, (object)structure);
+               }
+
+               public static T PtrToStructure<T> (IntPtr ptr) {
+                       return (T) PtrToStructure (ptr, typeof (T));
+               }
+#endif
+
+#if !MOBILE
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static int QueryInterfaceInternal (IntPtr pUnk, ref Guid iid, out IntPtr ppv);
+#endif
 
                public static int QueryInterface (IntPtr pUnk, ref Guid iid, out IntPtr ppv)
                {
+#if !MOBILE
                        if (pUnk == IntPtr.Zero)
                                throw new ArgumentException ("Value cannot be null.", "pUnk");
                        return QueryInterfaceInternal (pUnk, ref iid, out ppv);
+#else
+                       throw new NotImplementedException ();
+#endif
                }
 
                public static byte ReadByte (IntPtr ptr)
                {
-                       return ReadByte (ptr, 0);
+                       unsafe {
+                               return *(byte*)ptr;
+                       }
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static byte ReadByte (IntPtr ptr, int ofs);
+               public static byte ReadByte (IntPtr ptr, int ofs) {
+                       unsafe {
+                               return *((byte*)ptr + ofs);
+                       }
+               }
 
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static byte ReadByte ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
                {
                        throw new NotImplementedException ();
                }
 
-               public static short ReadInt16 (IntPtr ptr)
+               public unsafe static short ReadInt16 (IntPtr ptr)
                {
-                       return ReadInt16 (ptr, 0);
+                       byte *addr = (byte *) ptr;
+                       
+                       // The mono JIT can't inline this due to the hight number of calls
+                       // return ReadInt16 (ptr, 0);
+                       
+                       if (((uint)addr & 1) == 0) 
+                               return *(short*)addr;
+
+                       short s;
+                       String.memcpy ((byte*)&s, (byte*)ptr, 2);
+                       return s;
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static short ReadInt16 (IntPtr ptr, int ofs);
+               public unsafe static short ReadInt16 (IntPtr ptr, int ofs)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint) addr & 1) == 0)
+                               return *(short*)addr;
+
+                       short s;
+                       String.memcpy ((byte*)&s, addr, 2);
+                       return s;
+               }
 
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static short ReadInt16 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
                {
                        throw new NotImplementedException ();
                }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static int ReadInt32 (IntPtr ptr)
+               public unsafe static int ReadInt32 (IntPtr ptr)
                {
-                       return ReadInt32 (ptr, 0);
+                       byte *addr = (byte *) ptr;
+                       
+                       if (((uint)addr & 3) == 0) 
+                               return *(int*)addr;
+
+                       int s;
+                       String.memcpy ((byte*)&s, addr, 4);
+                       return s;
                }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static int ReadInt32 (IntPtr ptr, int ofs);
+               public unsafe static int ReadInt32 (IntPtr ptr, int ofs)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+                       
+                       if ((((int) addr) & 3) == 0)
+                               return *(int*)addr;
+                       else {
+                               int s;
+                               String.memcpy ((byte*)&s, addr, 4);
+                               return s;
+                       }
+               }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static int ReadInt32 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
                {
                        throw new NotImplementedException ();
                }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               public static long ReadInt64 (IntPtr ptr)
+               public unsafe static long ReadInt64 (IntPtr ptr)
                {
-                       return ReadInt64 (ptr, 0);
+                       byte *addr = (byte *) ptr;
+                               
+                       // The real alignment might be 4 on some platforms, but this is just an optimization,
+                       // so it doesn't matter.
+                       if (((uint) addr & 7) == 0)
+                               return *(long*)ptr;
+
+                       long s;
+                       String.memcpy ((byte*)&s, addr, 8);
+                       return s;
                }
 
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static long ReadInt64 (IntPtr ptr, int ofs);
+               public unsafe static long ReadInt64 (IntPtr ptr, int ofs)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint) addr & 7) == 0)
+                               return *(long*)addr;
+                       
+                       long s;
+                       String.memcpy ((byte*)&s, addr, 8);
+                       return s;
+               }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static long ReadInt64 ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
                {
                        throw new NotImplementedException ();
@@ -712,12 +904,20 @@ namespace System.Runtime.InteropServices
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                public static IntPtr ReadIntPtr (IntPtr ptr)
                {
-                       return ReadIntPtr (ptr, 0);
+                       if (IntPtr.Size == 4)
+                               return (IntPtr)ReadInt32 (ptr);
+                       else
+                               return (IntPtr)ReadInt64 (ptr);
                }
                
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static IntPtr ReadIntPtr (IntPtr ptr, int ofs);
+               public static IntPtr ReadIntPtr (IntPtr ptr, int ofs)
+               {
+                       if (IntPtr.Size == 4)
+                               return (IntPtr)ReadInt32 (ptr, ofs);
+                       else
+                               return (IntPtr)ReadInt64 (ptr, ofs);
+               }
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                [MonoTODO]
@@ -732,19 +932,26 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr ReAllocHGlobal (IntPtr pv, IntPtr cb);
 
+#if !MOBILE
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static int ReleaseInternal (IntPtr pUnk);
+#endif
 
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                public static int Release (IntPtr pUnk)
                {
+#if !MOBILE
                        if (pUnk == IntPtr.Zero)
                                throw new ArgumentException ("Value cannot be null.", "pUnk");
+
                        return ReleaseInternal (pUnk);
+#else
+                       throw new NotImplementedException ();
+#endif
                }
 
-#if !MOONLIGHT
+#if !FULL_AOT_RUNTIME
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static int ReleaseComObjectInternal (object co);
 
@@ -769,7 +976,7 @@ namespace System.Runtime.InteropServices
                {
                        throw new NotSupportedException ("MSDN states user code should never need to call this method.");
                }
-#endif // !NET_2_1
+#endif
 
                [ComVisible (true)]
                public static int SizeOf (object structure)
@@ -780,6 +987,16 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static int SizeOf (Type t);
 
+#if NET_4_5
+               public static int SizeOf<T> () {
+                       return SizeOf (typeof (T));
+               }
+
+               public static int SizeOf<T> (T structure) {
+                       return SizeOf (structure.GetType ());
+               }
+#endif
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr StringToBSTR (string s);
 
@@ -833,7 +1050,6 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr StringToHGlobalUni (string s);
 
-#if !MOONLIGHT
                public static IntPtr SecureStringToBSTR (SecureString s)
                {
                        if (s == null)
@@ -921,13 +1137,18 @@ namespace System.Runtime.InteropServices
                                throw new ArgumentNullException ("s");
                        return SecureStringToCoTaskMemUnicode (s);
                }
-#endif
 
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
                [ComVisible (true)]
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);
 
+#if NET_4_5
+               public static void StructureToPtr<T> (T structure, IntPtr ptr, bool fDeleteOld) {
+                       StructureToPtr ((object)structure, ptr, fDeleteOld);
+               }
+#endif
+
                public static void ThrowExceptionForHR (int errorCode) {
                        Exception ex = GetExceptionForHR (errorCode);
                        if (ex != null)
@@ -943,29 +1164,55 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
 
+#if NET_4_5
+               public static IntPtr UnsafeAddrOfPinnedArrayElement<T> (T[] arr, int index) {
+                       return UnsafeAddrOfPinnedArrayElement ((Array)arr, index);
+               }
+#endif
+
                public static void WriteByte (IntPtr ptr, byte val)
                {
-                       WriteByte (ptr, 0, val);
+                       unsafe {
+                               *(byte*)ptr = val;
+                       }
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void WriteByte (IntPtr ptr, int ofs, byte val);
+               public static void WriteByte (IntPtr ptr, int ofs, byte val) {
+                       unsafe {
+                               *(byte*)(IntPtr.Add (ptr, ofs)) = val;
+                       }
+               }
 
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static void WriteByte ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, byte val)
                {
                        throw new NotImplementedException ();
                }
 
-               public static void WriteInt16 (IntPtr ptr, short val)
+               public static unsafe void WriteInt16 (IntPtr ptr, short val)
                {
-                       WriteInt16 (ptr, 0, val);
+                       byte *addr = (byte *) ptr;
+                       
+                       if (((uint)addr & 1) == 0)
+                               *(short*)addr = val;
+                       else
+                               String.memcpy (addr, (byte*)&val, 2);
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void WriteInt16 (IntPtr ptr, int ofs, short val);
+               public static unsafe void WriteInt16 (IntPtr ptr, int ofs, short val)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint)addr & 1) == 0)
+                               *(short*)addr = val;
+                       else {
+                               String.memcpy (addr, (byte*)&val, 2);
+                       }
+               }
 
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static void WriteInt16 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, short val)
                {
                        throw new NotImplementedException ();
@@ -973,12 +1220,13 @@ namespace System.Runtime.InteropServices
 
                public static void WriteInt16 (IntPtr ptr, char val)
                {
-                       WriteInt16 (ptr, 0, val);
+                       WriteInt16 (ptr, 0, (short)val);
                }
 
-               [MonoTODO]
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void WriteInt16 (IntPtr ptr, int ofs, char val);
+               public static void WriteInt16 (IntPtr ptr, int ofs, char val)
+               {
+                       WriteInt16 (ptr, ofs, (short)val);
+               }
 
                [MonoTODO]
                public static void WriteInt16([In, Out] object ptr, int ofs, char val)
@@ -986,29 +1234,61 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static void WriteInt32 (IntPtr ptr, int val)
+               public static unsafe void WriteInt32 (IntPtr ptr, int val)
                {
-                       WriteInt32 (ptr, 0, val);
+                       byte *addr = (byte *) ptr;
+                       
+                       if (((uint)addr & 3) == 0) 
+                               *(int*)addr = val;
+                       else {
+                               String.memcpy (addr, (byte*)&val, 4);
+                       }
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void WriteInt32 (IntPtr ptr, int ofs, int val);
+               public unsafe static void WriteInt32 (IntPtr ptr, int ofs, int val)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       if (((uint)addr & 3) == 0) 
+                               *(int*)addr = val;
+                       else {
+                               String.memcpy (addr, (byte*)&val, 4);
+                       }
+               }
 
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static void WriteInt32([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, int val)
                {
                        throw new NotImplementedException ();
                }
 
-               public static void WriteInt64 (IntPtr ptr, long val)
+               public static unsafe void WriteInt64 (IntPtr ptr, long val)
                {
-                       WriteInt64 (ptr, 0, val);
+                       byte *addr = (byte *) ptr;
+                       
+                       // The real alignment might be 4 on some platforms, but this is just an optimization,
+                       // so it doesn't matter.
+                       if (((uint)addr & 7) == 0) 
+                               *(long*)addr = val;
+                       else 
+                               String.memcpy (addr, (byte*)&val, 8);
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void WriteInt64 (IntPtr ptr, int ofs, long val);
+               public static unsafe void WriteInt64 (IntPtr ptr, int ofs, long val)
+               {
+                       byte *addr = ((byte *) ptr) + ofs;
+
+                       // The real alignment might be 4 on some platforms, but this is just an optimization,
+                       // so it doesn't matter.
+                       if (((uint)addr & 7) == 0) 
+                               *(long*)addr = val;
+                       else 
+                               String.memcpy (addr, (byte*)&val, 8);
+               }
 
                [MonoTODO]
+               [SuppressUnmanagedCodeSecurity]
                public static void WriteInt64 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, long val)
                {
                        throw new NotImplementedException ();
@@ -1016,11 +1296,19 @@ namespace System.Runtime.InteropServices
 
                public static void WriteIntPtr (IntPtr ptr, IntPtr val)
                {
-                       WriteIntPtr (ptr, 0, val);
+                       if (IntPtr.Size == 4)
+                               WriteInt32 (ptr, (int)val);
+                       else
+                               WriteInt64 (ptr, (long)val);
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val);
+               public static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val)
+               {
+                       if (IntPtr.Size == 4)
+                               WriteInt32 (ptr, ofs, (int)val);
+                       else
+                               WriteInt64 (ptr, ofs, (long)val);
+               }
 
                [MonoTODO]
                public static void WriteIntPtr([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, IntPtr val)
@@ -1028,28 +1316,311 @@ namespace System.Runtime.InteropServices
                        throw new NotImplementedException ();
                }
 
-               public static Exception GetExceptionForHR (int errorCode) {
-                       return GetExceptionForHR (errorCode, IntPtr.Zero);
-               }
-
-               public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo) {
-
+               private static Exception ConvertHrToException (int errorCode)
+               {
+                       const int MSEE_E_APPDOMAINUNLOADED = unchecked ((int)0x80131014L);
+                       const int COR_E_APPLICATION = unchecked ((int)0x80131600L);
+                       const int E_INVALIDARG = unchecked ((int)0x80070057);
+                       const int COR_E_ARGUMENTOUTOFRANGE = unchecked ((int)0x80131502L);
+                       const int COR_E_ARITHMETIC = unchecked ((int)0x80070216);
+                       const int COR_E_ARRAYTYPEMISMATCH = unchecked ((int)0x80131503L);
+                       const int COR_E_BADIMAGEFORMAT = unchecked ((int)0x8007000BL);
+                       const int ERROR_BAD_FORMAT = unchecked ((int)0x0B);
+                       //const int COR_E_COMEMULATE_ERROR = unchecked ((int)?);
+                       const int COR_E_CONTEXTMARSHAL = unchecked ((int)0x80131504L);
+                       //const int COR_E_CORE = unchecked ((int)?);
+                       const int NTE_FAIL = unchecked ((int)0x80090020L);
+                       const int COR_E_DIRECTORYNOTFOUND = unchecked ((int)0x80070003L);
+                       const int ERROR_PATH_NOT_FOUND = unchecked ((int)0x03);
+                       const int COR_E_DIVIDEBYZERO = unchecked ((int)0x80020012L);
+                       const int COR_E_DUPLICATEWAITOBJECT = unchecked ((int)0x80131529L);
+                       const int COR_E_ENDOFSTREAM = unchecked ((int)0x80070026L);
+                       const int COR_E_TYPELOAD = unchecked ((int)0x80131522L);
+                       const int COR_E_EXCEPTION = unchecked ((int)0x80131500L);
+                       const int COR_E_EXECUTIONENGINE = unchecked ((int)0x80131506L);
+                       const int COR_E_FIELDACCESS = unchecked ((int)0x80131507L);
+                       const int COR_E_FILENOTFOUND = unchecked ((int)0x80070002L);
+                       const int ERROR_FILE_NOT_FOUND = unchecked ((int)0x02);
+                       const int COR_E_FORMAT = unchecked ((int)0x80131537L);
+                       const int COR_E_INDEXOUTOFRANGE = unchecked ((int)0x80131508L);
+                       const int COR_E_INVALIDCAST = unchecked ((int)0x80004002L);
+                       const int COR_E_INVALIDCOMOBJECT = unchecked ((int)0x80131527L);
+                       const int COR_E_INVALIDFILTERCRITERIA = unchecked ((int)0x80131601L);
+                       const int COR_E_INVALIDOLEVARIANTTYPE = unchecked ((int)0x80131531L);
+                       const int COR_E_INVALIDOPERATION = unchecked ((int)0x80131509L);
+                       const int COR_E_IO = unchecked ((int)0x80131620L);
+                       const int COR_E_MEMBERACCESS = unchecked ((int)0x8013151AL);
+                       const int COR_E_METHODACCESS = unchecked ((int)0x80131510L);
+                       const int COR_E_MISSINGFIELD = unchecked ((int)0x80131511L);
+                       const int COR_E_MISSINGMANIFESTRESOURCE = unchecked ((int)0x80131532L);
+                       const int COR_E_MISSINGMEMBER = unchecked ((int)0x80131512L);
+                       const int COR_E_MISSINGMETHOD = unchecked ((int)0x80131513L);
+                       const int COR_E_MULTICASTNOTSUPPORTED = unchecked ((int)0x80131514L);
+                       const int COR_E_NOTFINITENUMBER = unchecked ((int)0x80131528L);
+                       const int E_NOTIMPL = unchecked ((int)0x80004001L);
+                       const int COR_E_NOTSUPPORTED = unchecked ((int)0x80131515L);
+                       const int COR_E_NULLREFERENCE = unchecked ((int)0x80004003L);
                        const int E_OUTOFMEMORY = unchecked ((int)0x8007000EL);
-                       const int E_INVALIDARG = unchecked ((int)0X80070057);
-                       
-                       switch (errorCode)
-                       {
-                       case E_OUTOFMEMORY:
-                               return new OutOfMemoryException ();
-                       case E_INVALIDARG:
-                               return new ArgumentException ();
+                       const int COR_E_OVERFLOW = unchecked ((int)0x80131516L);
+                       const int COR_E_PATHTOOLONG = unchecked ((int)0x800700CEL);
+                       const int ERROR_FILENAME_EXCED_RANGE = unchecked ((int)0xCE);
+                       const int COR_E_RANK = unchecked ((int)0x80131517L);
+                       const int COR_E_REFLECTIONTYPELOAD = unchecked ((int)0x80131602L);
+                       const int COR_E_REMOTING = unchecked ((int)0x8013150BL);
+                       const int COR_E_SAFEARRAYTYPEMISMATCH = unchecked ((int)0x80131533L);
+                       const int COR_E_SECURITY = unchecked ((int)0x8013150AL);
+                       const int COR_E_SERIALIZATION = unchecked ((int)0x8013150CL);
+                       const int COR_E_STACKOVERFLOW = unchecked ((int)0x800703E9L);
+                       const int ERROR_STACK_OVERFLOW = unchecked ((int)0x03E9);
+                       const int COR_E_SYNCHRONIZATIONLOCK = unchecked ((int)0x80131518L);
+                       const int COR_E_SYSTEM = unchecked ((int)0x80131501L);
+                       const int COR_E_TARGET = unchecked ((int)0x80131603L);
+                       const int COR_E_TARGETINVOCATION = unchecked ((int)0x80131604L);
+                       const int COR_E_TARGETPARAMCOUNT = unchecked ((int)0x8002000EL);
+                       const int COR_E_THREADABORTED = unchecked ((int)0x80131530L);
+                       const int COR_E_THREADINTERRUPTED = unchecked ((int)0x80131519L);
+                       const int COR_E_THREADSTATE = unchecked ((int)0x80131520L);
+                       const int COR_E_THREADSTOP = unchecked ((int)0x80131521L);
+                       const int COR_E_TYPEINITIALIZATION = unchecked ((int)0x80131534L);
+                       const int COR_E_VERIFICATION = unchecked ((int)0x8013150DL);
+                       //const int COR_E_WEAKREFERENCE = unchecked ((int)?);
+                       //const int COR_E_VTABLECALLSNOTSUPPORTED = unchecked ((int));
+
+                       switch (errorCode) {
+                               case MSEE_E_APPDOMAINUNLOADED:
+                                       return new AppDomainUnloadedException ();
+                               case COR_E_APPLICATION:
+                                       return new ApplicationException ();
+                               case E_INVALIDARG:
+                                       return new ArgumentException ();
+                               case COR_E_ARGUMENTOUTOFRANGE:
+                                       return new ArgumentOutOfRangeException ();
+                               case COR_E_ARITHMETIC:
+                                       return new ArithmeticException ();
+                               case COR_E_ARRAYTYPEMISMATCH:
+                                       return new ArrayTypeMismatchException ();
+                               case COR_E_BADIMAGEFORMAT:
+                               case ERROR_BAD_FORMAT:
+                                       return new BadImageFormatException ();
+//                             case COR_E_COMEMULATE_ERROR:
+//                                     return new COMEmulateException ();
+                               case COR_E_CONTEXTMARSHAL:
+                                       return new ContextMarshalException ();
+//                             case COR_E_CORE:
+//                                     return new CoreException ();
+                               case NTE_FAIL:
+                                       return new System.Security.Cryptography.CryptographicException ();
+                               case COR_E_DIRECTORYNOTFOUND:
+                               case ERROR_PATH_NOT_FOUND:
+                                       return new System.IO.DirectoryNotFoundException ();
+                               case COR_E_DIVIDEBYZERO:
+                                       return new DivideByZeroException ();
+                               case COR_E_DUPLICATEWAITOBJECT:
+                                       return new DuplicateWaitObjectException ();
+                               case COR_E_ENDOFSTREAM:
+                                       return new System.IO.EndOfStreamException ();
+                               case COR_E_EXCEPTION:
+                                       return new Exception ();
+                               case COR_E_EXECUTIONENGINE:
+                                       return new ExecutionEngineException ();
+                               case COR_E_FIELDACCESS:
+                                       return new FieldAccessException ();
+                               case COR_E_FILENOTFOUND:
+                               case ERROR_FILE_NOT_FOUND:
+                                       return new System.IO.FileNotFoundException ();
+                               case COR_E_FORMAT:
+                                       return new FormatException ();
+                               case COR_E_INDEXOUTOFRANGE:
+                                       return new IndexOutOfRangeException ();
+                               case COR_E_INVALIDCAST:
+                               // E_NOINTERFACE has same value as COR_E_INVALIDCAST
+                                       return new InvalidCastException ();
+                               case COR_E_INVALIDCOMOBJECT:
+                                       return new InvalidComObjectException ();
+                               case COR_E_INVALIDFILTERCRITERIA:
+                                       return new InvalidFilterCriteriaException ();
+                               case COR_E_INVALIDOLEVARIANTTYPE:
+                                       return new InvalidOleVariantTypeException ();
+                               case COR_E_INVALIDOPERATION:
+                                       return new InvalidOperationException ();
+                               case COR_E_IO:
+                                       return new System.IO.IOException ();
+                               case COR_E_MEMBERACCESS:
+                                       return new MemberAccessException ();
+                               case COR_E_METHODACCESS:
+                                       return new MethodAccessException ();
+                               case COR_E_MISSINGFIELD:
+                                       return new MissingFieldException ();
+                               case COR_E_MISSINGMANIFESTRESOURCE:
+                                       return new System.Resources.MissingManifestResourceException ();
+                               case COR_E_MISSINGMEMBER:
+                                       return new MissingMemberException ();
+                               case COR_E_MISSINGMETHOD:
+                                       return new MissingMethodException ();
+                               case COR_E_MULTICASTNOTSUPPORTED:
+                                       return new MulticastNotSupportedException ();
+                               case COR_E_NOTFINITENUMBER:
+                                       return new NotFiniteNumberException ();
+                               case E_NOTIMPL:
+                                       return new NotImplementedException ();
+                               case COR_E_NOTSUPPORTED:
+                                       return new NotSupportedException ();
+                               case COR_E_NULLREFERENCE:
+                               // E_POINTER has the same value as COR_E_NULLREFERENCE
+                                       return new NullReferenceException ();
+                               case E_OUTOFMEMORY:
+                               // COR_E_OUTOFMEMORY has the same value as E_OUTOFMEMORY
+                                       return new OutOfMemoryException ();
+                               case COR_E_OVERFLOW:
+                                       return new OverflowException ();
+                               case COR_E_PATHTOOLONG:
+                               case ERROR_FILENAME_EXCED_RANGE:
+                                       return new System.IO.PathTooLongException ();
+                               case COR_E_RANK:
+                                       return new RankException ();
+                               case COR_E_REFLECTIONTYPELOAD:
+                                       return new System.Reflection.ReflectionTypeLoadException (new Type[] { }, new Exception[] { });
+                               case COR_E_REMOTING:
+                                       return new System.Runtime.Remoting.RemotingException ();
+                               case COR_E_SAFEARRAYTYPEMISMATCH:
+                                       return new SafeArrayTypeMismatchException ();
+                               case COR_E_SECURITY:
+                                       return new SecurityException ();
+                               case COR_E_SERIALIZATION:
+                                       return new System.Runtime.Serialization.SerializationException ();
+                               case COR_E_STACKOVERFLOW:
+                               case ERROR_STACK_OVERFLOW:
+                                       return new StackOverflowException ();
+                               case COR_E_SYNCHRONIZATIONLOCK:
+                                       return new SynchronizationLockException ();
+                               case COR_E_SYSTEM:
+                                       return new SystemException ();
+                               case COR_E_TARGET:
+                                       return new TargetException ();
+                               case COR_E_TARGETINVOCATION:
+                                       return new System.Reflection.TargetInvocationException (null);
+                               case COR_E_TARGETPARAMCOUNT:
+                                       return new TargetParameterCountException ();
+//                             case COR_E_THREADABORTED:
+//                                     ThreadAbortException c'tor is inaccessible
+//                                     return new System.Threading.ThreadAbortException ();
+                               case COR_E_THREADINTERRUPTED:
+                                       return new ThreadInterruptedException ();
+                               case COR_E_THREADSTATE:
+                                       return new ThreadStateException ();
+//                             case COR_E_THREADSTOP:
+//                                     ThreadStopException does not exist
+//                                     return new System.Threading.ThreadStopException ();
+                               case COR_E_TYPELOAD:
+                                       return new TypeLoadException ();
+                               // MSDN lists COR_E_TYPELOAD twice with different exceptions.
+                               // return new EntryPointNotFoundException ();
+                               case COR_E_TYPEINITIALIZATION:
+                                       return new TypeInitializationException("", null);
+                               case COR_E_VERIFICATION:
+                                       return new VerificationException ();
+//                             case COR_E_WEAKREFERENCE:
+//                                     return new WeakReferenceException ();
+//                             case COR_E_VTABLECALLSNOTSUPPORTED:
+//                                     return new VTableCallsNotSupportedException ();
                        }
                        if (errorCode < 0)
                                return new COMException ("", errorCode);
                        return null;
                }
 
-#if !MOONLIGHT
+               [DllImport ("oleaut32.dll", CharSet=CharSet.Unicode, EntryPoint = "SetErrorInfo")]
+               static extern int _SetErrorInfo (int dwReserved,
+                       [MarshalAs(UnmanagedType.Interface)] IErrorInfo pIErrorInfo);
+
+               [DllImport ("oleaut32.dll", CharSet=CharSet.Unicode, EntryPoint = "GetErrorInfo")]
+               static extern int _GetErrorInfo (int dwReserved,
+                       [MarshalAs(UnmanagedType.Interface)] out IErrorInfo ppIErrorInfo);
+
+               static bool SetErrorInfoNotAvailable;
+               static bool GetErrorInfoNotAvailable;
+
+               internal static int SetErrorInfo (int dwReserved, IErrorInfo errorInfo)
+               {
+                       int retVal = 0;
+                       errorInfo = null;
+
+                       if (SetErrorInfoNotAvailable)
+                               return -1;
+
+                       try {
+                               retVal = _SetErrorInfo (dwReserved, errorInfo);
+                       }
+                       catch (Exception) {
+                               // ignore any exception - probably there's no suitable SetErrorInfo
+                               // method available.
+                               SetErrorInfoNotAvailable = true;
+                       }
+                       return retVal;
+               }
+
+               internal static int GetErrorInfo (int dwReserved, out IErrorInfo errorInfo)
+               {
+                       int retVal = 0;
+                       errorInfo = null;
+
+                       if (GetErrorInfoNotAvailable)
+                               return -1;
+
+                       try {
+                               retVal = _GetErrorInfo (dwReserved, out errorInfo);
+                       }
+                       catch (Exception) {
+                               // ignore any exception - probably there's no suitable GetErrorInfo
+                               // method available.
+                               GetErrorInfoNotAvailable = true;
+                       }
+                       return retVal;
+               }
+
+               public static Exception GetExceptionForHR (int errorCode)
+               {
+                       return GetExceptionForHR (errorCode, IntPtr.Zero);
+               }
+
+               public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfoPtr)
+               {
+                       IErrorInfo errorInfo = null;
+                       if (errorInfoPtr != (IntPtr)(-1)) {
+                               if (errorInfoPtr == IntPtr.Zero) {
+                                       if (GetErrorInfo (0, out errorInfo) != 0) {
+                                               errorInfo = null;
+                                       }
+                               } else {
+                                       errorInfo = Marshal.GetObjectForIUnknown (errorInfoPtr) as IErrorInfo;
+                               }
+                       }
+
+                       if (errorInfo is ManagedErrorInfo && ((ManagedErrorInfo)errorInfo).Exception.hresult == errorCode) {
+                               return ((ManagedErrorInfo)errorInfo).Exception;
+                       }
+
+                       Exception e = ConvertHrToException (errorCode);
+                       if (errorInfo != null && e != null) {
+                               uint helpContext;
+                               errorInfo.GetHelpContext (out helpContext);
+                               string str;
+                               errorInfo.GetSource (out str);
+                               e.Source = str;
+                               errorInfo.GetDescription (out str);
+                               e.SetMessage (str);
+                               errorInfo.GetHelpFile (out str);
+
+                               if (helpContext == 0) {
+                                       e.HelpLink = str;
+                               } else {
+                                       e.HelpLink = string.Format ("{0}#{1}", str, helpContext);
+                               }
+                       }
+                       return e;
+               }
+
+#if !FULL_AOT_RUNTIME
                public static int FinalReleaseComObject (object o)
                {
                        while (ReleaseComObject (o) != 0);
@@ -1066,12 +1637,20 @@ namespace System.Runtime.InteropServices
                                throw new ArgumentNullException ("t");
                        if (!t.IsSubclassOf (typeof (MulticastDelegate)) || (t == typeof (MulticastDelegate)))
                                throw new ArgumentException ("Type is not a delegate", "t");
+                       if (t.IsGenericType)
+                               throw new ArgumentException ("The specified Type must not be a generic type definition.");
                        if (ptr == IntPtr.Zero)
                                throw new ArgumentNullException ("ptr");
 
                        return GetDelegateForFunctionPointerInternal (ptr, t);
                }
 
+#if NET_4_5
+               public static TDelegate GetDelegateForFunctionPointer<TDelegate> (IntPtr ptr) {
+                       return (TDelegate) (object) GetDelegateForFunctionPointer (ptr, typeof (TDelegate));
+               }
+#endif
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern IntPtr GetFunctionPointerForDelegateInternal (Delegate d);
                
@@ -1082,5 +1661,14 @@ namespace System.Runtime.InteropServices
                        
                        return GetFunctionPointerForDelegateInternal (d);
                }
+
+#if NET_4_5
+               public static IntPtr GetFunctionPointerForDelegate<TDelegate> (TDelegate d) {
+                       if (d == null)
+                               throw new ArgumentNullException ("d");
+                       
+                       return GetFunctionPointerForDelegateInternal ((Delegate)(object)d);
+               }
+#endif
        }
 }