1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 /*=============================================================================
9 ** Purpose: This class contains methods that are mainly used to marshal
10 ** between unmanaged and managed types.
13 =============================================================================*/
15 namespace System.Runtime.InteropServices
19 using System.Collections.Generic;
20 using System.Reflection;
21 using System.Reflection.Emit;
22 using System.Security;
24 using System.Threading;
25 using System.Runtime.CompilerServices;
26 using System.Globalization;
27 using System.Runtime.ConstrainedExecution;
28 using System.Runtime.Versioning;
29 using Win32Native = Microsoft.Win32.Win32Native;
30 using Microsoft.Win32.SafeHandles;
31 using System.Diagnostics;
32 using System.Runtime.InteropServices.ComTypes;
33 using System.StubHelpers;
35 public enum CustomQueryInterfaceMode
41 //========================================================================
42 // All public methods, including PInvoke, are protected with linkchecks.
43 // Remove the default demands for all PInvoke methods with this global
44 // declaration on the class.
45 //========================================================================
47 public static partial class Marshal
49 //====================================================================
50 // Defines used inside the Marshal class.
51 //====================================================================
52 private const int LMEM_FIXED = 0;
53 private const int LMEM_MOVEABLE = 2;
55 private const long HIWORDMASK = unchecked((long)0xffffffffffff0000L);
57 #if FEATURE_COMINTEROP
58 private static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
59 #endif //FEATURE_COMINTEROP
61 // Win32 has the concept of Atoms, where a pointer can either be a pointer
62 // or an int. If it's less than 64K, this is guaranteed to NOT be a
63 // pointer since the bottom 64K bytes are reserved in a process' page table.
64 // We should be careful about deallocating this stuff. Extracted to
65 // a function to avoid C# problems with lack of support for IntPtr.
66 // We have 2 of these methods for slightly different semantics for NULL.
67 private static bool IsWin32Atom(IntPtr ptr)
72 long lPtr = (long)ptr;
73 return 0 == (lPtr & HIWORDMASK);
77 private static bool IsNotWin32Atom(IntPtr ptr)
82 long lPtr = (long)ptr;
83 return 0 != (lPtr & HIWORDMASK);
87 //====================================================================
88 // The default character size for the system. This is always 2 because
89 // the framework only runs on UTF-16 systems.
90 //====================================================================
91 public static readonly int SystemDefaultCharSize = 2;
93 //====================================================================
94 // The max DBCS character size for the system.
95 //====================================================================
96 public static readonly int SystemMaxDBCSCharSize = GetSystemMaxDBCSCharSize();
99 //====================================================================
100 // The name, title and description of the assembly that will contain
101 // the dynamically generated interop types.
102 //====================================================================
103 private const string s_strConvertedTypeInfoAssemblyName = "InteropDynamicTypes";
104 private const string s_strConvertedTypeInfoAssemblyTitle = "Interop Dynamic Types";
105 private const string s_strConvertedTypeInfoAssemblyDesc = "Type dynamically generated from ITypeInfo's";
106 private const string s_strConvertedTypeInfoNameSpace = "InteropDynamicTypes";
109 //====================================================================
110 // Helper method to retrieve the system's maximum DBCS character size.
111 //====================================================================
112 [MethodImplAttribute(MethodImplOptions.InternalCall)]
113 private static extern int GetSystemMaxDBCSCharSize();
115 public static unsafe string PtrToStringAnsi(IntPtr ptr)
117 if (IntPtr.Zero == ptr)
121 else if (IsWin32Atom(ptr))
127 int nb = Win32Native.lstrlenA(ptr);
134 return new string((sbyte*)ptr);
139 public static unsafe string PtrToStringAnsi(IntPtr ptr, int len)
141 if (ptr == IntPtr.Zero)
142 throw new ArgumentNullException(nameof(ptr));
144 throw new ArgumentException(null, nameof(len));
146 return new string((sbyte*)ptr, 0, len);
149 public static unsafe string PtrToStringUni(IntPtr ptr, int len)
151 if (ptr == IntPtr.Zero)
152 throw new ArgumentNullException(nameof(ptr));
154 throw new ArgumentException(null, nameof(len));
156 return new string((char*)ptr, 0, len);
159 public static string PtrToStringAuto(IntPtr ptr, int len)
161 // Ansi platforms are no longer supported
162 return PtrToStringUni(ptr, len);
165 public static unsafe string PtrToStringUni(IntPtr ptr)
167 if (IntPtr.Zero == ptr)
171 else if (IsWin32Atom(ptr))
177 return new string((char*)ptr);
181 public static string PtrToStringAuto(IntPtr ptr)
183 // Ansi platforms are no longer supported
184 return PtrToStringUni(ptr);
187 public static unsafe string PtrToStringUTF8(IntPtr ptr)
189 if (IntPtr.Zero == ptr)
195 int nbBytes = System.StubHelpers.StubHelpers.strlen((sbyte*)ptr.ToPointer());
196 return PtrToStringUTF8(ptr, nbBytes);
200 public static unsafe string PtrToStringUTF8(IntPtr ptr, int byteLen)
204 throw new ArgumentOutOfRangeException(nameof(byteLen), SR.ArgumentOutOfRange_NeedNonNegNum);
206 else if (IntPtr.Zero == ptr)
210 else if (IsWin32Atom(ptr))
214 else if (byteLen == 0)
220 byte* pByte = (byte*)ptr.ToPointer();
221 return Encoding.UTF8.GetString(pByte, byteLen);
225 //====================================================================
227 //====================================================================
228 public static int SizeOf(object structure)
230 if (structure == null)
231 throw new ArgumentNullException(nameof(structure));
232 // we never had a check for generics here
234 return SizeOfHelper(structure.GetType(), true);
237 public static int SizeOf<T>(T structure)
239 return SizeOf((object)structure);
242 public static int SizeOf(Type t)
245 throw new ArgumentNullException(nameof(t));
246 if (!(t is RuntimeType))
247 throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
249 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
251 return SizeOfHelper(t, true);
254 public static int SizeOf<T>()
256 return SizeOf(typeof(T));
259 [MethodImplAttribute(MethodImplOptions.InternalCall)]
260 internal static extern int SizeOfHelper(Type t, bool throwIfNotMarshalable);
262 //====================================================================
264 //====================================================================
265 public static IntPtr OffsetOf(Type t, string fieldName)
268 throw new ArgumentNullException(nameof(t));
270 FieldInfo f = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
272 throw new ArgumentException(SR.Format(SR.Argument_OffsetOfFieldNotFound, t.FullName), nameof(fieldName));
273 RtFieldInfo rtField = f as RtFieldInfo;
275 throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo, nameof(fieldName));
277 return OffsetOfHelper(rtField);
279 public static IntPtr OffsetOf<T>(string fieldName)
281 return OffsetOf(typeof(T), fieldName);
284 [MethodImplAttribute(MethodImplOptions.InternalCall)]
285 private static extern IntPtr OffsetOfHelper(IRuntimeFieldInfo f);
287 //====================================================================
288 // UnsafeAddrOfPinnedArrayElement()
290 // IMPORTANT NOTICE: This method does not do any verification on the
291 // array. It must be used with EXTREME CAUTION since passing in
292 // an array that is not pinned or in the fixed heap can cause
293 // unexpected results !
294 //====================================================================
295 [MethodImplAttribute(MethodImplOptions.InternalCall)]
296 public static extern IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index);
298 public static IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index)
300 return UnsafeAddrOfPinnedArrayElement((Array)arr, index);
303 //====================================================================
304 // Copy blocks from CLR arrays to native memory.
305 //====================================================================
306 public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
308 CopyToNative(source, startIndex, destination, length);
310 public static void Copy(char[] source, int startIndex, IntPtr destination, int length)
312 CopyToNative(source, startIndex, destination, length);
314 public static void Copy(short[] source, int startIndex, IntPtr destination, int length)
316 CopyToNative(source, startIndex, destination, length);
318 public static void Copy(long[] source, int startIndex, IntPtr destination, int length)
320 CopyToNative(source, startIndex, destination, length);
322 public static void Copy(float[] source, int startIndex, IntPtr destination, int length)
324 CopyToNative(source, startIndex, destination, length);
326 public static void Copy(double[] source, int startIndex, IntPtr destination, int length)
328 CopyToNative(source, startIndex, destination, length);
330 public static void Copy(byte[] source, int startIndex, IntPtr destination, int length)
332 CopyToNative(source, startIndex, destination, length);
334 public static void Copy(IntPtr[] source, int startIndex, IntPtr destination, int length)
336 CopyToNative(source, startIndex, destination, length);
338 [MethodImplAttribute(MethodImplOptions.InternalCall)]
339 private static extern void CopyToNative(object source, int startIndex, IntPtr destination, int length);
341 //====================================================================
342 // Copy blocks from native memory to CLR arrays
343 //====================================================================
344 public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
346 CopyToManaged(source, destination, startIndex, length);
348 public static void Copy(IntPtr source, char[] destination, int startIndex, int length)
350 CopyToManaged(source, destination, startIndex, length);
352 public static void Copy(IntPtr source, short[] destination, int startIndex, int length)
354 CopyToManaged(source, destination, startIndex, length);
356 public static void Copy(IntPtr source, long[] destination, int startIndex, int length)
358 CopyToManaged(source, destination, startIndex, length);
360 public static void Copy(IntPtr source, float[] destination, int startIndex, int length)
362 CopyToManaged(source, destination, startIndex, length);
364 public static void Copy(IntPtr source, double[] destination, int startIndex, int length)
366 CopyToManaged(source, destination, startIndex, length);
368 public static void Copy(IntPtr source, byte[] destination, int startIndex, int length)
370 CopyToManaged(source, destination, startIndex, length);
372 public static void Copy(IntPtr source, IntPtr[] destination, int startIndex, int length)
374 CopyToManaged(source, destination, startIndex, length);
376 [MethodImplAttribute(MethodImplOptions.InternalCall)]
377 private static extern void CopyToManaged(IntPtr source, object destination, int startIndex, int length);
379 //====================================================================
381 //====================================================================
382 public static byte ReadByte(object ptr, int ofs)
384 return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadByte(nativeHome, offset));
387 public static unsafe byte ReadByte(IntPtr ptr, int ofs)
391 byte* addr = (byte*)ptr + ofs;
394 catch (NullReferenceException)
396 // this method is documented to throw AccessViolationException on any AV
397 throw new AccessViolationException();
401 public static byte ReadByte(IntPtr ptr)
403 return ReadByte(ptr, 0);
406 public static short ReadInt16(object ptr, int ofs)
408 return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadInt16(nativeHome, offset));
411 public static unsafe short ReadInt16(IntPtr ptr, int ofs)
415 byte* addr = (byte*)ptr + ofs;
416 if ((unchecked((int)addr) & 0x1) == 0)
419 return *((short*)addr);
425 byte* valPtr = (byte*)&val;
431 catch (NullReferenceException)
433 // this method is documented to throw AccessViolationException on any AV
434 throw new AccessViolationException();
438 public static short ReadInt16(IntPtr ptr)
440 return ReadInt16(ptr, 0);
443 public static int ReadInt32(object ptr, int ofs)
445 return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadInt32(nativeHome, offset));
448 public static unsafe int ReadInt32(IntPtr ptr, int ofs)
452 byte* addr = (byte*)ptr + ofs;
453 if ((unchecked((int)addr) & 0x3) == 0)
456 return *((int*)addr);
462 byte* valPtr = (byte*)&val;
470 catch (NullReferenceException)
472 // this method is documented to throw AccessViolationException on any AV
473 throw new AccessViolationException();
477 public static int ReadInt32(IntPtr ptr)
479 return ReadInt32(ptr, 0);
482 public static IntPtr ReadIntPtr(object ptr, int ofs)
485 return (IntPtr)ReadInt64(ptr, ofs);
487 return (IntPtr)ReadInt32(ptr, ofs);
491 public static IntPtr ReadIntPtr(IntPtr ptr, int ofs)
494 return (IntPtr)ReadInt64(ptr, ofs);
496 return (IntPtr)ReadInt32(ptr, ofs);
500 public static IntPtr ReadIntPtr(IntPtr ptr)
503 return (IntPtr)ReadInt64(ptr, 0);
505 return (IntPtr)ReadInt32(ptr, 0);
509 public static long ReadInt64([MarshalAs(UnmanagedType.AsAny), In] object ptr, int ofs)
511 return ReadValueSlow(ptr, ofs, (IntPtr nativeHome, int offset) => Marshal.ReadInt64(nativeHome, offset));
514 public static unsafe long ReadInt64(IntPtr ptr, int ofs)
518 byte* addr = (byte*)ptr + ofs;
519 if ((unchecked((int)addr) & 0x7) == 0)
522 return *((long*)addr);
528 byte* valPtr = (byte*)&val;
540 catch (NullReferenceException)
542 // this method is documented to throw AccessViolationException on any AV
543 throw new AccessViolationException();
547 public static long ReadInt64(IntPtr ptr)
549 return ReadInt64(ptr, 0);
552 //====================================================================
553 // Read value from marshaled object (marshaled using AsAny)
554 // It's quite slow and can return back dangling pointers
555 // It's only there for backcompact
556 // People should instead use the IntPtr overloads
557 //====================================================================
558 private static unsafe T ReadValueSlow<T>(object ptr, int ofs, Func<IntPtr, int, T> readValueHelper)
560 // Consumers of this method are documented to throw AccessViolationException on any AV
562 throw new AccessViolationException();
565 (int)AsAnyMarshaler.AsAnyFlags.In |
566 (int)AsAnyMarshaler.AsAnyFlags.IsAnsi |
567 (int)AsAnyMarshaler.AsAnyFlags.IsBestFit;
569 MngdNativeArrayMarshaler.MarshalerState nativeArrayMarshalerState = new MngdNativeArrayMarshaler.MarshalerState();
570 AsAnyMarshaler marshaler = new AsAnyMarshaler(new IntPtr(&nativeArrayMarshalerState));
572 IntPtr pNativeHome = IntPtr.Zero;
576 pNativeHome = marshaler.ConvertToNative(ptr, dwFlags);
577 return readValueHelper(pNativeHome, ofs);
581 marshaler.ClearNative(pNativeHome);
585 //====================================================================
587 //====================================================================
588 public static unsafe void WriteByte(IntPtr ptr, int ofs, byte val)
592 byte* addr = (byte*)ptr + ofs;
595 catch (NullReferenceException)
597 // this method is documented to throw AccessViolationException on any AV
598 throw new AccessViolationException();
602 public static void WriteByte(object ptr, int ofs, byte val)
604 WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, byte value) => Marshal.WriteByte(nativeHome, offset, value));
607 public static void WriteByte(IntPtr ptr, byte val)
609 WriteByte(ptr, 0, val);
612 public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val)
616 byte* addr = (byte*)ptr + ofs;
617 if ((unchecked((int)addr) & 0x1) == 0)
620 *((short*)addr) = val;
625 byte* valPtr = (byte*)&val;
630 catch (NullReferenceException)
632 // this method is documented to throw AccessViolationException on any AV
633 throw new AccessViolationException();
637 public static void WriteInt16(object ptr, int ofs, short val)
639 WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, short value) => Marshal.WriteInt16(nativeHome, offset, value));
642 public static void WriteInt16(IntPtr ptr, short val)
644 WriteInt16(ptr, 0, val);
647 public static void WriteInt16(IntPtr ptr, int ofs, char val)
649 WriteInt16(ptr, ofs, (short)val);
652 public static void WriteInt16([In, Out]object ptr, int ofs, char val)
654 WriteInt16(ptr, ofs, (short)val);
657 public static void WriteInt16(IntPtr ptr, char val)
659 WriteInt16(ptr, 0, (short)val);
662 public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val)
666 byte* addr = (byte*)ptr + ofs;
667 if ((unchecked((int)addr) & 0x3) == 0)
675 byte* valPtr = (byte*)&val;
682 catch (NullReferenceException)
684 // this method is documented to throw AccessViolationException on any AV
685 throw new AccessViolationException();
689 public static void WriteInt32(object ptr, int ofs, int val)
691 WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, int value) => Marshal.WriteInt32(nativeHome, offset, value));
694 public static void WriteInt32(IntPtr ptr, int val)
696 WriteInt32(ptr, 0, val);
699 public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val)
702 WriteInt64(ptr, ofs, (long)val);
704 WriteInt32(ptr, ofs, (int)val);
708 public static void WriteIntPtr(object ptr, int ofs, IntPtr val)
711 WriteInt64(ptr, ofs, (long)val);
713 WriteInt32(ptr, ofs, (int)val);
717 public static void WriteIntPtr(IntPtr ptr, IntPtr val)
720 WriteInt64(ptr, 0, (long)val);
722 WriteInt32(ptr, 0, (int)val);
726 public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val)
730 byte* addr = (byte*)ptr + ofs;
731 if ((unchecked((int)addr) & 0x7) == 0)
734 *((long*)addr) = val;
739 byte* valPtr = (byte*)&val;
750 catch (NullReferenceException)
752 // this method is documented to throw AccessViolationException on any AV
753 throw new AccessViolationException();
757 public static void WriteInt64(object ptr, int ofs, long val)
759 WriteValueSlow(ptr, ofs, val, (IntPtr nativeHome, int offset, long value) => Marshal.WriteInt64(nativeHome, offset, value));
762 public static void WriteInt64(IntPtr ptr, long val)
764 WriteInt64(ptr, 0, val);
767 //====================================================================
768 // Write value into marshaled object (marshaled using AsAny) and
769 // propagate the value back
770 // It's quite slow and can return back dangling pointers
771 // It's only there for backcompact
772 // People should instead use the IntPtr overloads
773 //====================================================================
774 private static unsafe void WriteValueSlow<T>(object ptr, int ofs, T val, Action<IntPtr, int, T> writeValueHelper)
776 // Consumers of this method are documented to throw AccessViolationException on any AV
778 throw new AccessViolationException();
781 (int)AsAnyMarshaler.AsAnyFlags.In |
782 (int)AsAnyMarshaler.AsAnyFlags.Out |
783 (int)AsAnyMarshaler.AsAnyFlags.IsAnsi |
784 (int)AsAnyMarshaler.AsAnyFlags.IsBestFit;
786 MngdNativeArrayMarshaler.MarshalerState nativeArrayMarshalerState = new MngdNativeArrayMarshaler.MarshalerState();
787 AsAnyMarshaler marshaler = new AsAnyMarshaler(new IntPtr(&nativeArrayMarshalerState));
789 IntPtr pNativeHome = IntPtr.Zero;
793 pNativeHome = marshaler.ConvertToNative(ptr, dwFlags);
794 writeValueHelper(pNativeHome, ofs, val);
795 marshaler.ConvertToManaged(ptr, pNativeHome);
799 marshaler.ClearNative(pNativeHome);
803 //====================================================================
805 //====================================================================
806 [MethodImplAttribute(MethodImplOptions.InternalCall)]
807 public static extern int GetLastWin32Error();
810 //====================================================================
812 //====================================================================
813 [MethodImplAttribute(MethodImplOptions.InternalCall)]
814 internal static extern void SetLastWin32Error(int error);
817 //====================================================================
818 // GetHRForLastWin32Error
819 //====================================================================
820 public static int GetHRForLastWin32Error()
822 int dwLastError = GetLastWin32Error();
823 if ((dwLastError & 0x80000000) == 0x80000000)
826 return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000);
830 //====================================================================
832 //====================================================================
833 public static void Prelink(MethodInfo m)
836 throw new ArgumentNullException(nameof(m));
838 RuntimeMethodInfo rmi = m as RuntimeMethodInfo;
841 throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo);
843 InternalPrelink(rmi);
846 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
847 private static extern void InternalPrelink(IRuntimeMethodInfo m);
849 public static void PrelinkAll(Type c)
852 throw new ArgumentNullException(nameof(c));
854 MethodInfo[] mi = c.GetMethods();
857 for (int i = 0; i < mi.Length; i++)
864 [MethodImplAttribute(MethodImplOptions.InternalCall)]
865 public static extern /* struct _EXCEPTION_POINTERS* */ IntPtr GetExceptionPointers();
867 [MethodImplAttribute(MethodImplOptions.InternalCall)]
868 public static extern int GetExceptionCode();
871 //====================================================================
872 // Marshals data from a structure class to a native memory block.
873 // If the structure contains pointers to allocated blocks and
874 // "fDeleteOld" is true, this routine will call DestroyStructure() first.
875 //====================================================================
876 [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
877 public static extern void StructureToPtr(object structure, IntPtr ptr, bool fDeleteOld);
879 public static void StructureToPtr<T>(T structure, IntPtr ptr, bool fDeleteOld)
881 StructureToPtr((object)structure, ptr, fDeleteOld);
884 //====================================================================
885 // Marshals data from a native memory block to a preallocated structure class.
886 //====================================================================
887 public static void PtrToStructure(IntPtr ptr, object structure)
889 PtrToStructureHelper(ptr, structure, false);
892 public static void PtrToStructure<T>(IntPtr ptr, T structure)
894 PtrToStructure(ptr, (object)structure);
897 //====================================================================
898 // Creates a new instance of "structuretype" and marshals data from a
899 // native memory block to it.
900 //====================================================================
901 public static object PtrToStructure(IntPtr ptr, Type structureType)
903 if (ptr == IntPtr.Zero) return null;
905 if (structureType == null)
906 throw new ArgumentNullException(nameof(structureType));
908 if (structureType.IsGenericType)
909 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structureType));
911 RuntimeType rt = structureType.UnderlyingSystemType as RuntimeType;
914 throw new ArgumentException(SR.Arg_MustBeType, nameof(structureType));
916 object structure = rt.CreateInstanceDefaultCtor(false /*publicOnly*/, false /*skipCheckThis*/, false /*fillCache*/, true /*wrapExceptions*/);
917 PtrToStructureHelper(ptr, structure, true);
921 public static T PtrToStructure<T>(IntPtr ptr)
923 return (T)PtrToStructure(ptr, typeof(T));
926 //====================================================================
927 // Helper function to copy a pointer into a preallocated structure.
928 //====================================================================
929 [MethodImplAttribute(MethodImplOptions.InternalCall)]
930 private static extern void PtrToStructureHelper(IntPtr ptr, object structure, bool allowValueClasses);
933 //====================================================================
934 // Freeds all substructures pointed to by the native memory block.
935 // "structureclass" is used to provide layout information.
936 //====================================================================
937 [MethodImplAttribute(MethodImplOptions.InternalCall)]
938 public static extern void DestroyStructure(IntPtr ptr, Type structuretype);
940 public static void DestroyStructure<T>(IntPtr ptr)
942 DestroyStructure(ptr, typeof(T));
945 #if FEATURE_COMINTEROP
946 //====================================================================
947 // Returns the HInstance for this module. Returns -1 if the module
948 // doesn't have an HInstance. In Memory (Dynamic) Modules won't have
950 //====================================================================
951 public static IntPtr GetHINSTANCE(Module m)
954 throw new ArgumentNullException(nameof(m));
956 RuntimeModule rtModule = m as RuntimeModule;
957 if (rtModule == null)
959 ModuleBuilder mb = m as ModuleBuilder;
961 rtModule = mb.InternalModule;
964 if (rtModule == null)
965 throw new ArgumentNullException(nameof(m), SR.Argument_MustBeRuntimeModule);
967 return GetHINSTANCE(rtModule.GetNativeHandle());
970 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
971 private static extern IntPtr GetHINSTANCE(RuntimeModule m);
973 #endif // FEATURE_COMINTEROP
974 //====================================================================
975 // Throws a CLR exception based on the HRESULT.
976 //====================================================================
977 public static void ThrowExceptionForHR(int errorCode)
980 ThrowExceptionForHRInternal(errorCode, IntPtr.Zero);
982 public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo)
985 ThrowExceptionForHRInternal(errorCode, errorInfo);
988 [MethodImplAttribute(MethodImplOptions.InternalCall)]
989 internal static extern void ThrowExceptionForHRInternal(int errorCode, IntPtr errorInfo);
992 //====================================================================
993 // Converts the HRESULT to a CLR exception.
994 //====================================================================
995 public static Exception GetExceptionForHR(int errorCode)
998 return GetExceptionForHRInternal(errorCode, IntPtr.Zero);
1002 public static Exception GetExceptionForHR(int errorCode, IntPtr errorInfo)
1005 return GetExceptionForHRInternal(errorCode, errorInfo);
1010 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1011 internal static extern Exception GetExceptionForHRInternal(int errorCode, IntPtr errorInfo);
1014 //====================================================================
1015 // Memory allocation and deallocation.
1016 //====================================================================
1017 public static IntPtr AllocHGlobal(IntPtr cb)
1019 // For backwards compatibility on 32 bit platforms, ensure we pass values between
1020 // int.MaxValue and uint.MaxValue to Windows. If the binary has had the
1021 // LARGEADDRESSAWARE bit set in the PE header, it may get 3 or 4 GB of user mode
1022 // address space. It is remotely that those allocations could have succeeded,
1023 // though I couldn't reproduce that. In either case, that means we should continue
1024 // throwing an OOM instead of an ArgumentOutOfRangeException for "negative" amounts of memory.
1027 numBytes = new UIntPtr(unchecked((ulong)cb.ToInt64()));
1029 numBytes = new UIntPtr(unchecked((uint)cb.ToInt32()));
1032 IntPtr pNewMem = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, unchecked(numBytes));
1034 if (pNewMem == IntPtr.Zero)
1036 throw new OutOfMemoryException();
1041 public static IntPtr AllocHGlobal(int cb)
1043 return AllocHGlobal((IntPtr)cb);
1046 public static void FreeHGlobal(IntPtr hglobal)
1048 if (IsNotWin32Atom(hglobal))
1050 if (IntPtr.Zero != Win32Native.LocalFree(hglobal))
1052 ThrowExceptionForHR(GetHRForLastWin32Error());
1057 public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb)
1059 IntPtr pNewMem = Win32Native.LocalReAlloc(pv, cb, LMEM_MOVEABLE);
1060 if (pNewMem == IntPtr.Zero)
1062 throw new OutOfMemoryException();
1068 //====================================================================
1069 // String convertions.
1070 //====================================================================
1071 public static unsafe IntPtr StringToHGlobalAnsi(string s)
1079 int nb = (s.Length + 1) * SystemMaxDBCSCharSize;
1081 // Overflow checking
1083 throw new ArgumentOutOfRangeException(nameof(s));
1085 UIntPtr len = new UIntPtr((uint)nb);
1086 IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
1088 if (hglobal == IntPtr.Zero)
1090 throw new OutOfMemoryException();
1094 s.ConvertToAnsi((byte*)hglobal, nb, false, false);
1100 public static unsafe IntPtr StringToHGlobalUni(string s)
1108 int nb = (s.Length + 1) * 2;
1110 // Overflow checking
1112 throw new ArgumentOutOfRangeException(nameof(s));
1114 UIntPtr len = new UIntPtr((uint)nb);
1115 IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
1117 if (hglobal == IntPtr.Zero)
1119 throw new OutOfMemoryException();
1123 fixed (char* firstChar = s)
1125 string.wstrcpy((char*)hglobal, firstChar, s.Length + 1);
1132 public static IntPtr StringToHGlobalAuto(string s)
1134 // Ansi platforms are no longer supported
1135 return StringToHGlobalUni(s);
1138 #if FEATURE_COMINTEROP
1140 //====================================================================
1141 // Converts the CLR exception to an HRESULT. This function also sets
1142 // up an IErrorInfo for the exception.
1143 //====================================================================
1144 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1145 public static extern int GetHRForException(Exception e);
1147 //====================================================================
1148 // Converts the CLR exception to an HRESULT. This function also sets
1149 // up an IErrorInfo for the exception.
1150 // This function is only used in WinRT and converts ObjectDisposedException
1152 //====================================================================
1153 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1154 internal static extern int GetHRForException_WinRT(Exception e);
1156 internal static readonly Guid ManagedNameGuid = new Guid("{0F21F359-AB84-41E8-9A78-36D110E6D2F9}");
1158 //====================================================================
1159 // Given a managed object that wraps an ITypeInfo, return its name
1160 //====================================================================
1161 public static string GetTypeInfoName(ITypeInfo typeInfo)
1163 if (typeInfo == null)
1164 throw new ArgumentNullException(nameof(typeInfo));
1166 string strTypeLibName = null;
1167 string strDocString = null;
1168 int dwHelpContext = 0;
1169 string strHelpFile = null;
1171 typeInfo.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
1173 return strTypeLibName;
1176 // This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it
1177 // on Marshal for more consistent API surface.
1178 public static Type GetTypeFromCLSID(Guid clsid)
1180 return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
1183 //====================================================================
1184 // return the IUnknown* for an Object if the current context
1185 // is the one where the RCW was first seen. Will return null
1187 //====================================================================
1188 public static IntPtr /* IUnknown* */ GetIUnknownForObject(object o)
1190 return GetIUnknownForObjectNative(o, false);
1193 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1194 private static extern IntPtr /* IUnknown* */ GetIUnknownForObjectNative(object o, bool onlyInContext);
1196 //====================================================================
1197 // return the raw IUnknown* for a COM Object not related to current
1199 // Does not call AddRef
1200 //====================================================================
1201 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1202 internal static extern IntPtr /* IUnknown* */ GetRawIUnknownForComObjectNoAddRef(object o);
1203 #endif // FEATURE_COMINTEROP
1205 //====================================================================
1206 // return the IDispatch* for an Object
1207 //====================================================================
1208 public static IntPtr /* IDispatch */ GetIDispatchForObject(object o)
1210 throw new PlatformNotSupportedException();
1213 #if FEATURE_COMINTEROP
1215 //====================================================================
1216 // return the IUnknown* representing the interface for the Object
1217 // Object o should support Type T
1218 //====================================================================
1219 public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T)
1221 return GetComInterfaceForObjectNative(o, T, false, true);
1224 public static IntPtr GetComInterfaceForObject<T, TInterface>(T o)
1226 return GetComInterfaceForObject(o, typeof(TInterface));
1229 //====================================================================
1230 // return the IUnknown* representing the interface for the Object
1231 // Object o should support Type T, it refer the value of mode to
1232 // invoke customized QueryInterface or not
1233 //====================================================================
1234 public static IntPtr /* IUnknown* */ GetComInterfaceForObject(object o, Type T, CustomQueryInterfaceMode mode)
1236 bool bEnableCustomizedQueryInterface = ((mode == CustomQueryInterfaceMode.Allow) ? true : false);
1237 return GetComInterfaceForObjectNative(o, T, false, bEnableCustomizedQueryInterface);
1240 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1241 private static extern IntPtr /* IUnknown* */ GetComInterfaceForObjectNative(object o, Type t, bool onlyInContext, bool fEnalbeCustomizedQueryInterface);
1243 //====================================================================
1244 // return an Object for IUnknown
1245 //====================================================================
1246 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1247 public static extern object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk);
1249 //====================================================================
1250 // Return a unique Object given an IUnknown. This ensures that you
1251 // receive a fresh object (we will not look in the cache to match up this
1252 // IUnknown to an already existing object). This is useful in cases
1253 // where you want to be able to call ReleaseComObject on a RCW
1254 // and not worry about other active uses of said RCW.
1255 //====================================================================
1256 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1257 public static extern object GetUniqueObjectForIUnknown(IntPtr unknown);
1259 //====================================================================
1260 // return an Object for IUnknown, using the Type T,
1262 // Type T should be either a COM imported Type or a sub-type of COM
1264 //====================================================================
1265 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1266 public static extern object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t);
1268 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1269 public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, object o);
1271 public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o)
1273 return CreateAggregatedObject(pOuter, (object)o);
1276 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1277 public static extern void CleanupUnusedObjectsInCurrentContext();
1279 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1280 public static extern bool AreComObjectsAvailableForCleanup();
1282 //====================================================================
1283 // check if the object is classic COM component
1284 //====================================================================
1285 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1286 public static extern bool IsComObject(object o);
1288 #endif // FEATURE_COMINTEROP
1290 public static IntPtr AllocCoTaskMem(int cb)
1292 IntPtr pNewMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)cb));
1293 if (pNewMem == IntPtr.Zero)
1295 throw new OutOfMemoryException();
1300 public static unsafe IntPtr StringToCoTaskMemUni(string s)
1308 int nb = (s.Length + 1) * 2;
1310 // Overflow checking
1312 throw new ArgumentOutOfRangeException(nameof(s));
1314 IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
1316 if (hglobal == IntPtr.Zero)
1318 throw new OutOfMemoryException();
1322 fixed (char* firstChar = s)
1324 string.wstrcpy((char*)hglobal, firstChar, s.Length + 1);
1331 public static unsafe IntPtr StringToCoTaskMemUTF8(string s)
1339 int nb = Encoding.UTF8.GetMaxByteCount(s.Length);
1341 IntPtr pMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb + 1));
1343 if (pMem == IntPtr.Zero)
1345 throw new OutOfMemoryException();
1349 fixed (char* firstChar = s)
1351 byte* pbMem = (byte*)pMem;
1352 int nbWritten = Encoding.UTF8.GetBytes(firstChar, s.Length, pbMem, nb);
1353 pbMem[nbWritten] = 0;
1360 public static IntPtr StringToCoTaskMemAuto(string s)
1362 // Ansi platforms are no longer supported
1363 return StringToCoTaskMemUni(s);
1366 public static unsafe IntPtr StringToCoTaskMemAnsi(string s)
1374 int nb = (s.Length + 1) * SystemMaxDBCSCharSize;
1376 // Overflow checking
1378 throw new ArgumentOutOfRangeException(nameof(s));
1380 IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
1382 if (hglobal == IntPtr.Zero)
1384 throw new OutOfMemoryException();
1388 s.ConvertToAnsi((byte*)hglobal, nb, false, false);
1394 public static void FreeCoTaskMem(IntPtr ptr)
1396 if (IsNotWin32Atom(ptr))
1398 Win32Native.CoTaskMemFree(ptr);
1402 public static IntPtr ReAllocCoTaskMem(IntPtr pv, int cb)
1404 IntPtr pNewMem = Win32Native.CoTaskMemRealloc(pv, new UIntPtr((uint)cb));
1405 if (pNewMem == IntPtr.Zero && cb != 0)
1407 throw new OutOfMemoryException();
1412 //====================================================================
1413 // BSTR allocation and dealocation.
1414 //====================================================================
1415 public static void FreeBSTR(IntPtr ptr)
1417 if (IsNotWin32Atom(ptr))
1419 Win32Native.SysFreeString(ptr);
1423 public static IntPtr StringToBSTR(string s)
1428 // Overflow checking
1429 if (s.Length + 1 < s.Length)
1430 throw new ArgumentOutOfRangeException(nameof(s));
1432 IntPtr bstr = Win32Native.SysAllocStringLen(s, s.Length);
1433 if (bstr == IntPtr.Zero)
1434 throw new OutOfMemoryException();
1439 public static string PtrToStringBSTR(IntPtr ptr)
1441 return PtrToStringUni(ptr, (int)Win32Native.SysStringLen(ptr));
1444 #if FEATURE_COMINTEROP
1445 //====================================================================
1446 // release the COM component and if the reference hits 0 zombie this object
1447 // further usage of this Object might throw an exception
1448 //====================================================================
1449 public static int ReleaseComObject(object o)
1451 __ComObject co = null;
1453 // Make sure the obj is an __ComObject.
1456 co = (__ComObject)o;
1458 catch (InvalidCastException)
1460 throw new ArgumentException(SR.Argument_ObjNotComObject, nameof(o));
1463 return co.ReleaseSelf();
1466 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1467 internal static extern int InternalReleaseComObject(object o);
1470 //====================================================================
1471 // release the COM component and zombie this object
1472 // further usage of this Object might throw an exception
1473 //====================================================================
1474 public static int FinalReleaseComObject(object o)
1477 throw new ArgumentNullException(nameof(o));
1479 __ComObject co = null;
1481 // Make sure the obj is an __ComObject.
1484 co = (__ComObject)o;
1486 catch (InvalidCastException)
1488 throw new ArgumentException(SR.Argument_ObjNotComObject, nameof(o));
1491 co.FinalReleaseSelf();
1496 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1497 internal static extern void InternalFinalReleaseComObject(object o);
1498 #endif // FEATURE_COMINTEROP
1500 //====================================================================
1501 // This method retrieves data from the COM object.
1502 //====================================================================
1503 public static object GetComObjectData(object obj, object key)
1505 throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported);
1508 //====================================================================
1509 // This method sets data on the COM object. The data can only be set
1510 // once for a given key and cannot be removed. This function returns
1511 // true if the data has been added, false if the data could not be
1512 // added because there already was data for the specified key.
1513 //====================================================================
1514 public static bool SetComObjectData(object obj, object key, object data)
1516 throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported);
1519 #if FEATURE_COMINTEROP
1520 //====================================================================
1521 // This method takes the given COM object and wraps it in an object
1522 // of the specified type. The type must be derived from __ComObject.
1523 //====================================================================
1524 public static object CreateWrapperOfType(object o, Type t)
1526 // Validate the arguments.
1528 throw new ArgumentNullException(nameof(t));
1530 throw new ArgumentException(SR.Argument_TypeNotComObject, nameof(t));
1531 if (t.IsGenericType)
1532 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
1534 if (t.IsWindowsRuntimeObject)
1535 throw new ArgumentException(SR.Argument_TypeIsWinRTType, nameof(t));
1537 // Check for the null case.
1541 // Make sure the object is a COM object.
1542 if (!o.GetType().IsCOMObject)
1543 throw new ArgumentException(SR.Argument_ObjNotComObject, nameof(o));
1544 if (o.GetType().IsWindowsRuntimeObject)
1545 throw new ArgumentException(SR.Argument_ObjIsWinRTObject, nameof(o));
1547 // Check to see if the type of the object is the requested type.
1548 if (o.GetType() == t)
1551 // Check to see if we already have a cached wrapper for this type.
1552 object Wrapper = GetComObjectData(o, t);
1553 if (Wrapper == null)
1555 // Create the wrapper for the specified type.
1556 Wrapper = InternalCreateWrapperOfType(o, t);
1558 // Attempt to cache the wrapper on the object.
1559 if (!SetComObjectData(o, t, Wrapper))
1561 // Another thead already cached the wrapper so use that one instead.
1562 Wrapper = GetComObjectData(o, t);
1569 public static TWrapper CreateWrapperOfType<T, TWrapper>(T o)
1571 return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper));
1574 //====================================================================
1575 // Helper method called from CreateWrapperOfType.
1576 //====================================================================
1577 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1578 private static extern object InternalCreateWrapperOfType(object o, Type t);
1580 //====================================================================
1582 //====================================================================
1583 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1584 public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv);
1586 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1587 public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk);
1588 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1589 public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk);
1591 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1592 public static extern void GetNativeVariantForObject(object obj, /* VARIANT * */ IntPtr pDstNativeVariant);
1594 public static void GetNativeVariantForObject<T>(T obj, IntPtr pDstNativeVariant)
1596 GetNativeVariantForObject((object)obj, pDstNativeVariant);
1599 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1600 public static extern object GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant);
1602 public static T GetObjectForNativeVariant<T>(IntPtr pSrcNativeVariant)
1604 return (T)GetObjectForNativeVariant(pSrcNativeVariant);
1607 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1608 public static extern object[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);
1610 public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int cVars)
1612 object[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);
1615 if (objects != null)
1617 result = new T[objects.Length];
1618 Array.Copy(objects, result, objects.Length);
1625 /// <para>Returns the first valid COM slot that GetMethodInfoForSlot will work on
1626 /// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces. </para>
1628 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1629 public static extern int GetStartComSlot(Type t);
1631 #endif // FEATURE_COMINTEROP
1633 //====================================================================
1634 // This method generates a GUID for the specified type. If the type
1635 // has a GUID in the metadata then it is returned otherwise a stable
1636 // guid GUID is generated based on the fully qualified name of the
1638 //====================================================================
1639 public static Guid GenerateGuidForType(Type type)
1644 //====================================================================
1645 // This method generates a PROGID for the specified type. If the type
1646 // has a PROGID in the metadata then it is returned otherwise a stable
1647 // PROGID is generated based on the fully qualified name of the
1649 //====================================================================
1650 public static string GenerateProgIdForType(Type type)
1653 throw new ArgumentNullException(nameof(type));
1655 throw new ArgumentException(SR.Argument_TypeMustNotBeComImport, nameof(type));
1656 if (type.IsGenericType)
1657 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type));
1659 IList<CustomAttributeData> cas = CustomAttributeData.GetCustomAttributes(type);
1660 for (int i = 0; i < cas.Count; i++)
1662 if (cas[i].Constructor.DeclaringType == typeof(ProgIdAttribute))
1664 // Retrieve the PROGID string from the ProgIdAttribute.
1665 IList<CustomAttributeTypedArgument> caConstructorArgs = cas[i].ConstructorArguments;
1666 Debug.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1");
1668 CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0];
1669 Debug.Assert(progIdConstructorArg.ArgumentType == typeof(string), "progIdConstructorArg.ArgumentType == typeof(String)");
1671 string strProgId = (string)progIdConstructorArg.Value;
1673 if (strProgId == null)
1674 strProgId = string.Empty;
1680 // If there is no prog ID attribute then use the full name of the type as the prog id.
1681 return type.FullName;
1684 #if FEATURE_COMINTEROP
1685 //====================================================================
1686 // This method binds to the specified moniker.
1687 //====================================================================
1688 public static object BindToMoniker(string monikerName)
1691 IBindCtx bindctx = null;
1692 CreateBindCtx(0, out bindctx);
1695 IMoniker pmoniker = null;
1696 MkParseDisplayName(bindctx, monikerName, out cbEaten, out pmoniker);
1698 BindMoniker(pmoniker, 0, ref IID_IUnknown, out obj);
1702 [DllImport(Interop.Libraries.Ole32, PreserveSig = false)]
1703 private static extern void CreateBindCtx(uint reserved, out IBindCtx ppbc);
1705 [DllImport(Interop.Libraries.Ole32, PreserveSig = false)]
1706 private static extern void MkParseDisplayName(IBindCtx pbc, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out uint pchEaten, out IMoniker ppmk);
1708 [DllImport(Interop.Libraries.Ole32, PreserveSig = false)]
1709 private static extern void BindMoniker(IMoniker pmk, uint grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out object ppvResult);
1711 //========================================================================
1712 // Private method called from EE upon use of license/ICF2 marshaling.
1713 //========================================================================
1714 private static IntPtr LoadLicenseManager()
1716 Type t = Type.GetType("System.ComponentModel.LicenseManager, System", throwOnError: true);
1717 return t.TypeHandle.Value;
1720 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1721 public static extern void ChangeWrapperHandleStrength(object otp, bool fIsWeak);
1723 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1724 internal static extern void InitializeWrapperForWinRT(object o, ref IntPtr pUnk);
1726 #if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
1727 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1728 internal static extern void InitializeManagedWinRTFactoryObject(object o, RuntimeType runtimeClassType);
1731 //========================================================================
1732 // Create activation factory and wraps it with a unique RCW
1733 //========================================================================
1734 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1735 internal static extern object GetNativeActivationFactory(Type type);
1737 #endif // FEATURE_COMINTEROP
1739 public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t)
1741 // Validate the parameters
1742 if (ptr == IntPtr.Zero)
1743 throw new ArgumentNullException(nameof(ptr));
1746 throw new ArgumentNullException(nameof(t));
1748 if ((t as RuntimeType) == null)
1749 throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
1751 if (t.IsGenericType)
1752 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
1754 Type c = t.BaseType;
1755 if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
1756 throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t));
1758 return GetDelegateForFunctionPointerInternal(ptr, t);
1761 public static TDelegate GetDelegateForFunctionPointer<TDelegate>(IntPtr ptr)
1763 return (TDelegate)(object)GetDelegateForFunctionPointer(ptr, typeof(TDelegate));
1766 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1767 internal static extern Delegate GetDelegateForFunctionPointerInternal(IntPtr ptr, Type t);
1769 public static IntPtr GetFunctionPointerForDelegate(Delegate d)
1772 throw new ArgumentNullException(nameof(d));
1774 return GetFunctionPointerForDelegateInternal(d);
1777 public static IntPtr GetFunctionPointerForDelegate<TDelegate>(TDelegate d)
1779 return GetFunctionPointerForDelegate((Delegate)(object)d);
1782 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1783 internal static extern IntPtr GetFunctionPointerForDelegateInternal(Delegate d);
1785 public static IntPtr SecureStringToBSTR(SecureString s)
1789 throw new ArgumentNullException(nameof(s));
1792 return s.MarshalToBSTR();
1795 public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s)
1799 throw new ArgumentNullException(nameof(s));
1802 return s.MarshalToString(globalAlloc: false, unicode: false);
1805 public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s)
1809 throw new ArgumentNullException(nameof(s));
1812 return s.MarshalToString(globalAlloc: false, unicode: true);
1815 public static void ZeroFreeBSTR(IntPtr s)
1817 RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.SysStringLen(s) * 2));
1821 public static void ZeroFreeCoTaskMemAnsi(IntPtr s)
1823 RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
1827 public static void ZeroFreeCoTaskMemUnicode(IntPtr s)
1829 RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
1833 public static unsafe void ZeroFreeCoTaskMemUTF8(IntPtr s)
1835 RuntimeImports.RhZeroMemory(s, (UIntPtr)System.StubHelpers.StubHelpers.strlen((sbyte*)s));
1839 public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s)
1843 throw new ArgumentNullException(nameof(s));
1846 return s.MarshalToString(globalAlloc: true, unicode: false);
1849 public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s)
1853 throw new ArgumentNullException(nameof(s));
1856 return s.MarshalToString(globalAlloc: true, unicode: true); ;
1859 public static void ZeroFreeGlobalAllocAnsi(IntPtr s)
1861 RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
1865 public static void ZeroFreeGlobalAllocUnicode(IntPtr s)
1867 RuntimeImports.RhZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));