X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Runtime.InteropServices%2FMarshal.cs;h=e339f94955ad4463ee6de55a20d018c6b0157cd2;hb=9afab4092501a7e7e240a2dd9ed0892d1e0821de;hp=43cf9bfe2ea147e350cbaaa314d07a366256f953;hpb=0a1e3ddf05121c7a43349babb5915db3eb1da4c6;p=mono.git diff --git a/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs b/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs index 43cf9bfe2ea..a1b028b08c1 100644 --- a/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs +++ b/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs @@ -31,6 +31,7 @@ // using System.Collections; +using System.Collections.Generic; using System.Runtime.CompilerServices; using System; using System.Security; @@ -38,11 +39,8 @@ 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 @@ -52,16 +50,22 @@ namespace System.Runtime.InteropServices { /* fields */ public static readonly int SystemMaxDBCSCharSize = 2; // don't know what this is - public static readonly int 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)] @@ -183,7 +187,11 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } -#if !MOONLIGHT + public static IntPtr CreateAggregatedObject (IntPtr pOuter, T o) { + return CreateAggregatedObject (pOuter, (object)o); + } + +#if !FULL_AOT_RUNTIME public static object CreateWrapperOfType (object o, Type t) { __ComObject co = o as __ComObject; @@ -200,12 +208,20 @@ namespace System.Runtime.InteropServices return ComInteropProxy.GetProxy (co.IUnknown, t).GetTransparentProxy (); } + + public static TWrapper CreateWrapperOfType (T o) { + return (TWrapper)CreateWrapperOfType ((object)o, typeof (TWrapper)); + } #endif [MethodImplAttribute(MethodImplOptions.InternalCall)] [ComVisible (true)] public extern static void DestroyStructure (IntPtr ptr, Type structuretype); + public static void DestroyStructure (IntPtr ptr) { + DestroyStructure (ptr, typeof (T)); + } + [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static void FreeBSTR (IntPtr ptr); @@ -266,16 +282,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 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] @@ -284,6 +317,7 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } +#if !MOBILE [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static IntPtr GetCCW (object o, Type T); @@ -294,12 +328,21 @@ 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 + } + + public static IntPtr GetComInterfaceForObject (T o) { + return GetComInterfaceForObject ((object)o, typeof (T)); } [MonoTODO] @@ -314,11 +357,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)) @@ -326,6 +372,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] @@ -354,12 +403,19 @@ 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) { - return e.hresult; +#if FEATURE_COMINTEROP + var errorInfo = new ManagedErrorInfo(e); + SetErrorInfo (0, errorInfo); + + return e._HResult; +#else + return -1; +#endif } [MonoTODO] @@ -368,7 +424,7 @@ namespace System.Runtime.InteropServices { throw new NotImplementedException (); } -#if !MOONLIGHT + [MethodImplAttribute (MethodImplOptions.InternalCall)] private extern static IntPtr GetIDispatchForObjectInternal (object o); @@ -429,11 +485,18 @@ namespace System.Runtime.InteropServices Marshal.StructureToPtr(vt, pDstNativeVariant, false); } + public static void GetNativeVariantForObject (T obj, IntPtr pDstNativeVariant) { + GetNativeVariantForObject ((object)obj, pDstNativeVariant); + } + +#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) { @@ -441,6 +504,9 @@ namespace System.Runtime.InteropServices obj = proxy.GetTransparentProxy (); } return obj; +#else + throw new NotImplementedException (); +#endif } public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant) @@ -449,6 +515,11 @@ namespace System.Runtime.InteropServices return vt.GetValue(); } + public static T GetObjectForNativeVariant (IntPtr pSrcNativeVariant) { + Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant)); + return (T)vt.GetValue(); + } + public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars) { if (cVars < 0) @@ -460,6 +531,16 @@ namespace System.Runtime.InteropServices return objects; } + public static T[] GetObjectsForNativeVariants (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 ((IntPtr)(aSrcNativeVariant.ToInt64 () + + i * SizeOf (typeof(Variant)))); + return objects; + } + [MonoTODO] public static int GetStartComSlot (Type t) { @@ -492,6 +573,12 @@ namespace System.Runtime.InteropServices throw new NotImplementedException (); } + public static Type GetTypeFromCLSID (Guid clsid) + { + throw new NotImplementedException (); + } + +#if !FULL_AOT_RUNTIME [Obsolete] [MonoTODO] public static string GetTypeInfoName (UCOMITypeInfo pTI) @@ -559,6 +646,7 @@ namespace System.Runtime.InteropServices { throw new NotImplementedException (); } +#endif [MonoTODO] [Obsolete ("This method has been deprecated")] @@ -567,8 +655,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) @@ -581,7 +676,7 @@ namespace System.Runtime.InteropServices { throw new NotImplementedException (); } -#endif // !NET_2_1 +#endif [MethodImplAttribute(MethodImplOptions.InternalCall)] [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] @@ -590,6 +685,10 @@ namespace System.Runtime.InteropServices [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static IntPtr OffsetOf (Type t, string fieldName); + public static IntPtr OffsetOf (string fieldName) { + return OffsetOf (typeof (T), fieldName); + } + [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static void Prelink (MethodInfo m); @@ -620,8 +719,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)] @@ -631,23 +737,42 @@ namespace System.Runtime.InteropServices [ComVisible (true)] public extern static object PtrToStructure (IntPtr ptr, Type structureType); + public static void PtrToStructure (IntPtr ptr, T structure) { + PtrToStructure (ptr, (object)structure); + } + + public static T PtrToStructure (IntPtr ptr) { + return (T) PtrToStructure (ptr, typeof (T)); + } + +#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] @@ -656,13 +781,32 @@ namespace System.Runtime.InteropServices 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; + Buffer.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; + Buffer.Memcpy ((byte*)&s, addr, 2); + return s; + } [MonoTODO] [SuppressUnmanagedCodeSecurity] @@ -672,14 +816,31 @@ namespace System.Runtime.InteropServices } [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; + Buffer.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; + Buffer.Memcpy ((byte*)&s, addr, 4); + return s; + } + } [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] [MonoTODO] @@ -690,13 +851,31 @@ namespace System.Runtime.InteropServices } [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; + Buffer.Memcpy ((byte*)&s, addr, 8); + return s; } - [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; + Buffer.Memcpy ((byte*)&s, addr, 8); + return s; + } [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)] [MonoTODO] @@ -709,12 +888,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] @@ -729,19 +916,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); @@ -766,7 +960,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) @@ -777,6 +971,29 @@ namespace System.Runtime.InteropServices [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static int SizeOf (Type t); + public static int SizeOf () { + return SizeOf (typeof (T)); + } + + public static int SizeOf (T structure) { + return SizeOf (structure.GetType ()); + } + + internal static uint SizeOfType (Type type) + { + return (uint) SizeOf (type); + } + + internal static uint AlignedSizeOf () where T : struct + { + uint size = SizeOfType (typeof (T)); + if (size == 1 || size == 2) + return size; + if (IntPtr.Size == 8 && size == 4) + return size; + return (size + 3) & (~((uint)3)); + } + [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static IntPtr StringToBSTR (string s); @@ -830,7 +1047,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) @@ -918,13 +1134,16 @@ 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); + public static void StructureToPtr (T structure, IntPtr ptr, bool fDeleteOld) { + StructureToPtr ((object)structure, ptr, fDeleteOld); + } + public static void ThrowExceptionForHR (int errorCode) { Exception ex = GetExceptionForHR (errorCode); if (ex != null) @@ -940,13 +1159,22 @@ namespace System.Runtime.InteropServices [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index); + public static IntPtr UnsafeAddrOfPinnedArrayElement (T[] arr, int index) { + return UnsafeAddrOfPinnedArrayElement ((Array)arr, index); + } + 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] @@ -955,13 +1183,26 @@ namespace System.Runtime.InteropServices 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 + Buffer.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 { + Buffer.Memcpy (addr, (byte*)&val, 2); + } + } [MonoTODO] [SuppressUnmanagedCodeSecurity] @@ -972,12 +1213,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) @@ -985,13 +1227,27 @@ 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 { + Buffer.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 { + Buffer.Memcpy (addr, (byte*)&val, 4); + } + } [MonoTODO] [SuppressUnmanagedCodeSecurity] @@ -1000,13 +1256,29 @@ namespace System.Runtime.InteropServices 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 + Buffer.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 + Buffer.Memcpy (addr, (byte*)&val, 8); + } [MonoTODO] [SuppressUnmanagedCodeSecurity] @@ -1017,11 +1289,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) @@ -1029,28 +1309,316 @@ 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 +#if FEATURE_COMINTEROP + [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; + } +#endif + public static Exception GetExceptionForHR (int errorCode) + { + return GetExceptionForHR (errorCode, IntPtr.Zero); + } + + public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo) + { +#if FEATURE_COMINTEROP + IErrorInfo info = null; + if (errorInfo != (IntPtr)(-1)) { + if (errorInfo == IntPtr.Zero) { + if (GetErrorInfo (0, out info) != 0) { + info = null; + } + } else { + info = Marshal.GetObjectForIUnknown (errorInfo) as IErrorInfo; + } + } + + if (info is ManagedErrorInfo && ((ManagedErrorInfo) info).Exception._HResult == errorCode) { + return ((ManagedErrorInfo) info).Exception; + } + + Exception e = ConvertHrToException (errorCode); + if (info != null && e != null) { + uint helpContext; + info.GetHelpContext (out helpContext); + string str; + info.GetSource (out str); + e.Source = str; + info.GetDescription (out str); + e.SetMessage (str); + info.GetHelpFile (out str); + + if (helpContext == 0) { + e.HelpLink = str; + } else { + e.HelpLink = string.Format ("{0}#{1}", str, helpContext); + } + } + return e; +#else + return ConvertHrToException (errorCode); +#endif + } + +#if !FULL_AOT_RUNTIME public static int FinalReleaseComObject (object o) { while (ReleaseComObject (o) != 0); @@ -1075,6 +1643,10 @@ namespace System.Runtime.InteropServices return GetDelegateForFunctionPointerInternal (ptr, t); } + public static TDelegate GetDelegateForFunctionPointer (IntPtr ptr) { + return (TDelegate) (object) GetDelegateForFunctionPointer (ptr, typeof (TDelegate)); + } + [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern IntPtr GetFunctionPointerForDelegateInternal (Delegate d); @@ -1085,5 +1657,16 @@ namespace System.Runtime.InteropServices return GetFunctionPointerForDelegateInternal (d); } + + public static IntPtr GetFunctionPointerForDelegate (TDelegate d) { + if (d == null) + throw new ArgumentNullException ("d"); + + return GetFunctionPointerForDelegateInternal ((Delegate)(object)d); + } + + internal static void SetLastWin32Error (int error) + { + } } }