Fix StyleCop warning SA1121 (use built-in types)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / Runtime / InteropServices / Marshal.cs
blob4c67ca55b227e85c28c70071461d45fc7b9d8869
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 using System.Security;
6 using System.Reflection;
7 using System.Runtime.CompilerServices;
8 using System.Text;
10 using Internal.Runtime.CompilerServices;
11 using System.Diagnostics.CodeAnalysis;
13 #pragma warning disable SA1121 // explicitly using type aliases instead of built-in types
14 #if BIT64
15 using nuint = System.UInt64;
16 #else
17 using nuint = System.UInt32;
18 #endif
20 namespace System.Runtime.InteropServices
22 /// <summary>
23 /// This class contains methods that are mainly used to marshal between unmanaged
24 /// and managed types.
25 /// </summary>
26 public static partial class Marshal
28 /// <summary>
29 /// The default character size for the system. This is always 2 because
30 /// the framework only runs on UTF-16 systems.
31 /// </summary>
32 public static readonly int SystemDefaultCharSize = 2;
34 /// <summary>
35 /// The max DBCS character size for the system.
36 /// </summary>
37 public static readonly int SystemMaxDBCSCharSize = GetSystemMaxDBCSCharSize();
39 public static IntPtr AllocHGlobal(int cb) => AllocHGlobal((IntPtr)cb);
41 public static unsafe string? PtrToStringAnsi(IntPtr ptr)
43 if (ptr == IntPtr.Zero || IsWin32Atom(ptr))
45 return null;
48 return new string((sbyte*)ptr);
51 public static unsafe string PtrToStringAnsi(IntPtr ptr, int len)
53 if (ptr == IntPtr.Zero)
55 throw new ArgumentNullException(nameof(ptr));
57 if (len < 0)
59 throw new ArgumentOutOfRangeException(nameof(len), len, SR.ArgumentOutOfRange_NeedNonNegNum);
62 return new string((sbyte*)ptr, 0, len);
65 public static unsafe string? PtrToStringUni(IntPtr ptr)
67 if (ptr == IntPtr.Zero || IsWin32Atom(ptr))
69 return null;
72 return new string((char*)ptr);
75 public static unsafe string PtrToStringUni(IntPtr ptr, int len)
77 if (ptr == IntPtr.Zero)
79 throw new ArgumentNullException(nameof(ptr));
81 if (len < 0)
83 throw new ArgumentOutOfRangeException(nameof(len), len, SR.ArgumentOutOfRange_NeedNonNegNum);
86 return new string((char*)ptr, 0, len);
89 public static unsafe string? PtrToStringUTF8(IntPtr ptr)
91 if (ptr == IntPtr.Zero || IsWin32Atom(ptr))
93 return null;
96 int nbBytes = string.strlen((byte*)ptr);
97 return string.CreateStringFromEncoding((byte*)ptr, nbBytes, Encoding.UTF8);
100 public static unsafe string PtrToStringUTF8(IntPtr ptr, int byteLen)
102 if (ptr == IntPtr.Zero)
104 throw new ArgumentNullException(nameof(ptr));
106 if (byteLen < 0)
108 throw new ArgumentOutOfRangeException(nameof(byteLen), byteLen, SR.ArgumentOutOfRange_NeedNonNegNum);
111 return string.CreateStringFromEncoding((byte*)ptr, byteLen, Encoding.UTF8);
114 public static int SizeOf(object structure)
116 if (structure is null)
118 throw new ArgumentNullException(nameof(structure));
121 return SizeOfHelper(structure.GetType(), throwIfNotMarshalable: true);
124 public static int SizeOf<T>(T structure)
126 if (structure is null)
128 throw new ArgumentNullException(nameof(structure));
131 return SizeOfHelper(structure.GetType(), throwIfNotMarshalable: true);
134 public static int SizeOf(Type t)
136 if (t is null)
138 throw new ArgumentNullException(nameof(t));
140 if (!t.IsRuntimeImplemented())
142 throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
144 if (t.IsGenericType)
146 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
149 return SizeOfHelper(t, throwIfNotMarshalable: true);
152 public static int SizeOf<T>() => SizeOf(typeof(T));
154 /// <summary>
155 /// IMPORTANT NOTICE: This method does not do any verification on the array.
156 /// It must be used with EXTREME CAUTION since passing in invalid index or
157 /// an array that is not pinned can cause unexpected results.
158 /// </summary>
159 public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index)
161 if (arr is null)
162 throw new ArgumentNullException(nameof(arr));
164 void* pRawData = Unsafe.AsPointer(ref arr.GetRawArrayData());
165 return (IntPtr)((byte*)pRawData + (uint)index * (nuint)arr.GetElementSize());
168 public static unsafe IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index)
170 if (arr is null)
171 throw new ArgumentNullException(nameof(arr));
173 void* pRawData = Unsafe.AsPointer(ref arr.GetRawSzArrayData());
174 return (IntPtr)((byte*)pRawData + (uint)index * (nuint)Unsafe.SizeOf<T>());
177 public static IntPtr OffsetOf<T>(string fieldName) => OffsetOf(typeof(T), fieldName);
179 public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
181 CopyToNative(source, startIndex, destination, length);
184 public static void Copy(char[] source, int startIndex, IntPtr destination, int length)
186 CopyToNative(source, startIndex, destination, length);
189 public static void Copy(short[] source, int startIndex, IntPtr destination, int length)
191 CopyToNative(source, startIndex, destination, length);
194 public static void Copy(long[] source, int startIndex, IntPtr destination, int length)
196 CopyToNative(source, startIndex, destination, length);
199 public static void Copy(float[] source, int startIndex, IntPtr destination, int length)
201 CopyToNative(source, startIndex, destination, length);
204 public static void Copy(double[] source, int startIndex, IntPtr destination, int length)
206 CopyToNative(source, startIndex, destination, length);
209 public static void Copy(byte[] source, int startIndex, IntPtr destination, int length)
211 CopyToNative(source, startIndex, destination, length);
214 public static void Copy(IntPtr[] source, int startIndex, IntPtr destination, int length)
216 CopyToNative(source, startIndex, destination, length);
219 private static unsafe void CopyToNative<T>(T[] source, int startIndex, IntPtr destination, int length)
221 if (source is null)
222 throw new ArgumentNullException(nameof(source));
223 if (destination == IntPtr.Zero)
224 throw new ArgumentNullException(nameof(destination));
226 // The rest of the argument validation is done by CopyTo
228 new Span<T>(source, startIndex, length).CopyTo(new Span<T>((void*)destination, length));
231 public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
233 CopyToManaged(source, destination, startIndex, length);
236 public static void Copy(IntPtr source, char[] destination, int startIndex, int length)
238 CopyToManaged(source, destination, startIndex, length);
241 public static void Copy(IntPtr source, short[] destination, int startIndex, int length)
243 CopyToManaged(source, destination, startIndex, length);
246 public static void Copy(IntPtr source, long[] destination, int startIndex, int length)
248 CopyToManaged(source, destination, startIndex, length);
251 public static void Copy(IntPtr source, float[] destination, int startIndex, int length)
253 CopyToManaged(source, destination, startIndex, length);
256 public static void Copy(IntPtr source, double[] destination, int startIndex, int length)
258 CopyToManaged(source, destination, startIndex, length);
261 public static void Copy(IntPtr source, byte[] destination, int startIndex, int length)
263 CopyToManaged(source, destination, startIndex, length);
266 public static void Copy(IntPtr source, IntPtr[] destination, int startIndex, int length)
268 CopyToManaged(source, destination, startIndex, length);
271 private static unsafe void CopyToManaged<T>(IntPtr source, T[] destination, int startIndex, int length)
273 if (source == IntPtr.Zero)
274 throw new ArgumentNullException(nameof(source));
275 if (destination is null)
276 throw new ArgumentNullException(nameof(destination));
277 if (startIndex < 0)
278 throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
279 if (length < 0)
280 throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
282 // The rest of the argument validation is done by CopyTo
284 new Span<T>((void*)source, length).CopyTo(new Span<T>(destination, startIndex, length));
287 public static unsafe byte ReadByte(IntPtr ptr, int ofs)
291 byte* addr = (byte*)ptr + ofs;
292 return *addr;
294 catch (NullReferenceException)
296 // this method is documented to throw AccessViolationException on any AV
297 throw new AccessViolationException();
301 public static byte ReadByte(IntPtr ptr) => ReadByte(ptr, 0);
303 public static unsafe short ReadInt16(IntPtr ptr, int ofs)
307 byte* addr = (byte*)ptr + ofs;
308 if ((unchecked((int)addr) & 0x1) == 0)
310 // aligned read
311 return *((short*)addr);
313 else
315 return Unsafe.ReadUnaligned<short>(addr);
318 catch (NullReferenceException)
320 // this method is documented to throw AccessViolationException on any AV
321 throw new AccessViolationException();
325 public static short ReadInt16(IntPtr ptr) => ReadInt16(ptr, 0);
327 public static unsafe int ReadInt32(IntPtr ptr, int ofs)
331 byte* addr = (byte*)ptr + ofs;
332 if ((unchecked((int)addr) & 0x3) == 0)
334 // aligned read
335 return *((int*)addr);
337 else
339 return Unsafe.ReadUnaligned<int>(addr);
342 catch (NullReferenceException)
344 // this method is documented to throw AccessViolationException on any AV
345 throw new AccessViolationException();
349 public static int ReadInt32(IntPtr ptr) => ReadInt32(ptr, 0);
351 public static IntPtr ReadIntPtr(object ptr, int ofs)
353 #if BIT64
354 return (IntPtr)ReadInt64(ptr, ofs);
355 #else // 32
356 return (IntPtr)ReadInt32(ptr, ofs);
357 #endif
360 public static IntPtr ReadIntPtr(IntPtr ptr, int ofs)
362 #if BIT64
363 return (IntPtr)ReadInt64(ptr, ofs);
364 #else // 32
365 return (IntPtr)ReadInt32(ptr, ofs);
366 #endif
369 public static IntPtr ReadIntPtr(IntPtr ptr) => ReadIntPtr(ptr, 0);
371 public static unsafe long ReadInt64(IntPtr ptr, int ofs)
375 byte* addr = (byte*)ptr + ofs;
376 if ((unchecked((int)addr) & 0x7) == 0)
378 // aligned read
379 return *((long*)addr);
381 else
383 return Unsafe.ReadUnaligned<long>(addr);
386 catch (NullReferenceException)
388 // this method is documented to throw AccessViolationException on any AV
389 throw new AccessViolationException();
393 public static long ReadInt64(IntPtr ptr) => ReadInt64(ptr, 0);
395 public static unsafe void WriteByte(IntPtr ptr, int ofs, byte val)
399 byte* addr = (byte*)ptr + ofs;
400 *addr = val;
402 catch (NullReferenceException)
404 // this method is documented to throw AccessViolationException on any AV
405 throw new AccessViolationException();
409 public static void WriteByte(IntPtr ptr, byte val) => WriteByte(ptr, 0, val);
411 public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val)
415 byte* addr = (byte*)ptr + ofs;
416 if ((unchecked((int)addr) & 0x1) == 0)
418 // aligned write
419 *((short*)addr) = val;
421 else
423 Unsafe.WriteUnaligned(addr, val);
426 catch (NullReferenceException)
428 // this method is documented to throw AccessViolationException on any AV
429 throw new AccessViolationException();
433 public static void WriteInt16(IntPtr ptr, short val) => WriteInt16(ptr, 0, val);
435 public static void WriteInt16(IntPtr ptr, int ofs, char val) => WriteInt16(ptr, ofs, (short)val);
437 public static void WriteInt16([In, Out]object ptr, int ofs, char val) => WriteInt16(ptr, ofs, (short)val);
439 public static void WriteInt16(IntPtr ptr, char val) => WriteInt16(ptr, 0, (short)val);
441 public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val)
445 byte* addr = (byte*)ptr + ofs;
446 if ((unchecked((int)addr) & 0x3) == 0)
448 // aligned write
449 *((int*)addr) = val;
451 else
453 Unsafe.WriteUnaligned(addr, val);
456 catch (NullReferenceException)
458 // this method is documented to throw AccessViolationException on any AV
459 throw new AccessViolationException();
463 public static void WriteInt32(IntPtr ptr, int val) => WriteInt32(ptr, 0, val);
465 public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val)
467 #if BIT64
468 WriteInt64(ptr, ofs, (long)val);
469 #else // 32
470 WriteInt32(ptr, ofs, (int)val);
471 #endif
474 public static void WriteIntPtr(object ptr, int ofs, IntPtr val)
476 #if BIT64
477 WriteInt64(ptr, ofs, (long)val);
478 #else // 32
479 WriteInt32(ptr, ofs, (int)val);
480 #endif
483 public static void WriteIntPtr(IntPtr ptr, IntPtr val) => WriteIntPtr(ptr, 0, val);
485 public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val)
489 byte* addr = (byte*)ptr + ofs;
490 if ((unchecked((int)addr) & 0x7) == 0)
492 // aligned write
493 *((long*)addr) = val;
495 else
497 Unsafe.WriteUnaligned(addr, val);
500 catch (NullReferenceException)
502 // this method is documented to throw AccessViolationException on any AV
503 throw new AccessViolationException();
507 public static void WriteInt64(IntPtr ptr, long val) => WriteInt64(ptr, 0, val);
509 public static void Prelink(MethodInfo m)
511 if (m is null)
513 throw new ArgumentNullException(nameof(m));
516 PrelinkCore(m);
519 public static void PrelinkAll(Type c)
521 if (c is null)
523 throw new ArgumentNullException(nameof(c));
526 MethodInfo[] mi = c.GetMethods();
528 for (int i = 0; i < mi.Length; i++)
530 Prelink(mi[i]);
534 public static void StructureToPtr<T>([DisallowNull] T structure, IntPtr ptr, bool fDeleteOld)
536 StructureToPtr((object)structure!, ptr, fDeleteOld);
539 /// <summary>
540 /// Creates a new instance of "structuretype" and marshals data from a
541 /// native memory block to it.
542 /// </summary>
543 public static object? PtrToStructure(IntPtr ptr, Type structureType)
545 if (ptr == IntPtr.Zero)
547 return null;
550 if (structureType is null)
552 throw new ArgumentNullException(nameof(structureType));
554 if (structureType.IsGenericType)
556 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structureType));
558 if (!structureType.IsRuntimeImplemented())
560 throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(structureType));
563 return PtrToStructureHelper(ptr, structureType);
566 /// <summary>
567 /// Marshals data from a native memory block to a preallocated structure class.
568 /// </summary>
569 public static void PtrToStructure(IntPtr ptr, object structure)
571 PtrToStructureHelper(ptr, structure, allowValueClasses: false);
574 public static void PtrToStructure<T>(IntPtr ptr, [DisallowNull] T structure)
576 PtrToStructure(ptr, (object)structure!);
579 [return: MaybeNull]
580 public static T PtrToStructure<T>(IntPtr ptr) => (T)PtrToStructure(ptr, typeof(T))!;
582 public static void DestroyStructure<T>(IntPtr ptr) => DestroyStructure(ptr, typeof(T));
584 /// <summary>
585 /// Converts the HRESULT to a CLR exception.
586 /// </summary>
587 public static Exception? GetExceptionForHR(int errorCode) => GetExceptionForHR(errorCode, IntPtr.Zero);
589 public static Exception? GetExceptionForHR(int errorCode, IntPtr errorInfo)
591 if (errorCode >= 0)
593 return null;
596 return GetExceptionForHRInternal(errorCode, errorInfo);
599 /// <summary>
600 /// Throws a CLR exception based on the HRESULT.
601 /// </summary>
602 public static void ThrowExceptionForHR(int errorCode)
604 if (errorCode < 0)
606 throw GetExceptionForHR(errorCode, IntPtr.Zero)!;
610 public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo)
612 if (errorCode < 0)
614 throw GetExceptionForHR(errorCode, errorInfo)!;
618 public static IntPtr SecureStringToBSTR(SecureString s)
620 if (s is null)
622 throw new ArgumentNullException(nameof(s));
625 return s.MarshalToBSTR();
628 public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s)
630 if (s is null)
632 throw new ArgumentNullException(nameof(s));
635 return s.MarshalToString(globalAlloc: false, unicode: false);
638 public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s)
640 if (s is null)
642 throw new ArgumentNullException(nameof(s));
645 return s.MarshalToString(globalAlloc: false, unicode: true);
648 public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s)
650 if (s is null)
652 throw new ArgumentNullException(nameof(s));
655 return s.MarshalToString(globalAlloc: true, unicode: false);
658 public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s)
660 if (s is null)
662 throw new ArgumentNullException(nameof(s));
665 return s.MarshalToString(globalAlloc: true, unicode: true); ;
668 public static unsafe IntPtr StringToHGlobalAnsi(string? s)
670 if (s is null)
672 return IntPtr.Zero;
675 long lnb = (s.Length + 1) * (long)SystemMaxDBCSCharSize;
676 int nb = (int)lnb;
678 // Overflow checking
679 if (nb != lnb)
681 throw new ArgumentOutOfRangeException(nameof(s));
684 IntPtr hglobal = AllocHGlobal((IntPtr)nb);
686 StringToAnsiString(s, (byte*)hglobal, nb);
687 return hglobal;
690 public static unsafe IntPtr StringToHGlobalUni(string? s)
692 if (s is null)
694 return IntPtr.Zero;
697 int nb = (s.Length + 1) * 2;
699 // Overflow checking
700 if (nb < s.Length)
702 throw new ArgumentOutOfRangeException(nameof(s));
705 IntPtr hglobal = AllocHGlobal((IntPtr)nb);
707 fixed (char* firstChar = s)
709 string.wstrcpy((char*)hglobal, firstChar, s.Length + 1);
711 return hglobal;
714 private static unsafe IntPtr StringToHGlobalUTF8(string? s)
716 if (s is null)
718 return IntPtr.Zero;
721 int nb = Encoding.UTF8.GetMaxByteCount(s.Length);
723 IntPtr pMem = AllocHGlobal(nb + 1);
725 int nbWritten;
726 byte* pbMem = (byte*)pMem;
728 fixed (char* firstChar = s)
730 nbWritten = Encoding.UTF8.GetBytes(firstChar, s.Length, pbMem, nb);
733 pbMem[nbWritten] = 0;
735 return pMem;
738 public static unsafe IntPtr StringToCoTaskMemUni(string? s)
740 if (s is null)
742 return IntPtr.Zero;
745 int nb = (s.Length + 1) * 2;
747 // Overflow checking
748 if (nb < s.Length)
750 throw new ArgumentOutOfRangeException(nameof(s));
753 IntPtr hglobal = AllocCoTaskMem(nb);
755 fixed (char* firstChar = s)
757 string.wstrcpy((char*)hglobal, firstChar, s.Length + 1);
759 return hglobal;
762 public static unsafe IntPtr StringToCoTaskMemUTF8(string? s)
764 if (s is null)
766 return IntPtr.Zero;
769 int nb = Encoding.UTF8.GetMaxByteCount(s.Length);
771 IntPtr pMem = AllocCoTaskMem(nb + 1);
773 int nbWritten;
774 byte* pbMem = (byte*)pMem;
776 fixed (char* firstChar = s)
778 nbWritten = Encoding.UTF8.GetBytes(firstChar, s.Length, pbMem, nb);
781 pbMem[nbWritten] = 0;
783 return pMem;
786 public static unsafe IntPtr StringToCoTaskMemAnsi(string? s)
788 if (s is null)
790 return IntPtr.Zero;
793 long lnb = (s.Length + 1) * (long)SystemMaxDBCSCharSize;
794 int nb = (int)lnb;
796 // Overflow checking
797 if (nb != lnb)
799 throw new ArgumentOutOfRangeException(nameof(s));
802 IntPtr hglobal = AllocCoTaskMem(nb);
804 StringToAnsiString(s, (byte*)hglobal, nb);
805 return hglobal;
808 /// <summary>
809 /// Generates a GUID for the specified type. If the type has a GUID in the
810 /// metadata then it is returned otherwise a stable guid is generated based
811 /// on the fully qualified name of the type.
812 /// </summary>
813 public static Guid GenerateGuidForType(Type type)
815 if (type is null)
817 throw new ArgumentNullException(nameof(type));
819 if (!type.IsRuntimeImplemented())
821 throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type));
824 return type.GUID;
827 /// <summary>
828 /// This method generates a PROGID for the specified type. If the type has
829 /// a PROGID in the metadata then it is returned otherwise a stable PROGID
830 /// is generated based on the fully qualified name of the type.
831 /// </summary>
832 public static string? GenerateProgIdForType(Type type)
834 if (type is null)
836 throw new ArgumentNullException(nameof(type));
838 if (type.IsImport)
840 throw new ArgumentException(SR.Argument_TypeMustNotBeComImport, nameof(type));
842 if (type.IsGenericType)
844 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type));
847 ProgIdAttribute? progIdAttribute = type.GetCustomAttribute<ProgIdAttribute>();
848 if (progIdAttribute != null)
850 return progIdAttribute.Value ?? string.Empty;
853 // If there is no prog ID attribute then use the full name of the type as the prog id.
854 return type.FullName;
857 public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t)
859 if (ptr == IntPtr.Zero)
861 throw new ArgumentNullException(nameof(ptr));
863 if (t is null)
865 throw new ArgumentNullException(nameof(t));
867 if (!t.IsRuntimeImplemented())
869 throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
871 if (t.IsGenericType)
873 throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
876 Type? c = t.BaseType;
877 if (c != typeof(Delegate) && c != typeof(MulticastDelegate))
879 throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t));
882 return GetDelegateForFunctionPointerInternal(ptr, t);
885 public static TDelegate GetDelegateForFunctionPointer<TDelegate>(IntPtr ptr)
887 return (TDelegate)(object)GetDelegateForFunctionPointer(ptr, typeof(TDelegate));
890 public static IntPtr GetFunctionPointerForDelegate(Delegate d)
892 if (d is null)
894 throw new ArgumentNullException(nameof(d));
897 return GetFunctionPointerForDelegateInternal(d);
900 public static IntPtr GetFunctionPointerForDelegate<TDelegate>(TDelegate d) where TDelegate : notnull
902 return GetFunctionPointerForDelegate((Delegate)(object)d);
905 public static int GetHRForLastWin32Error()
907 int dwLastError = GetLastWin32Error();
908 if ((dwLastError & 0x80000000) == 0x80000000)
910 return dwLastError;
913 return (dwLastError & 0x0000FFFF) | unchecked((int)0x80070000);
916 public static IntPtr /* IDispatch */ GetIDispatchForObject(object o) => throw new PlatformNotSupportedException();
918 public static void ZeroFreeBSTR(IntPtr s)
920 if (s == IntPtr.Zero)
922 return;
924 RuntimeImports.RhZeroMemory(s, (UIntPtr)SysStringByteLen(s));
925 FreeBSTR(s);
928 public static unsafe void ZeroFreeCoTaskMemAnsi(IntPtr s)
930 ZeroFreeCoTaskMemUTF8(s);
933 public static unsafe void ZeroFreeCoTaskMemUnicode(IntPtr s)
935 if (s == IntPtr.Zero)
937 return;
939 RuntimeImports.RhZeroMemory(s, (UIntPtr)(string.wcslen((char*)s) * 2));
940 FreeCoTaskMem(s);
943 public static unsafe void ZeroFreeCoTaskMemUTF8(IntPtr s)
945 if (s == IntPtr.Zero)
947 return;
949 RuntimeImports.RhZeroMemory(s, (UIntPtr)string.strlen((byte*)s));
950 FreeCoTaskMem(s);
953 public static unsafe void ZeroFreeGlobalAllocAnsi(IntPtr s)
955 if (s == IntPtr.Zero)
957 return;
959 RuntimeImports.RhZeroMemory(s, (UIntPtr)string.strlen((byte*)s));
960 FreeHGlobal(s);
963 public static unsafe void ZeroFreeGlobalAllocUnicode(IntPtr s)
965 if (s == IntPtr.Zero)
967 return;
969 RuntimeImports.RhZeroMemory(s, (UIntPtr)(string.wcslen((char*)s) * 2));
970 FreeHGlobal(s);
973 internal static unsafe uint SysStringByteLen(IntPtr s)
975 return *(((uint*)s) - 1);