Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / mscorlib / system / stubhelpers.cs
blob56a6975641ddb5ca27abbcc63a4c347d8d233768
1 // ==++==
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // ==--==
7 namespace System.StubHelpers {
9 using System.Text;
10 using Microsoft.Win32;
11 using System.Security;
12 using System.Collections.Generic;
13 using System.Runtime;
14 using System.Runtime.InteropServices;
15 #if FEATURE_COMINTEROP
16 using System.Runtime.InteropServices.WindowsRuntime;
17 #endif // FEATURE_COMINTEROP
18 using System.Runtime.CompilerServices;
19 using System.Runtime.ConstrainedExecution;
20 using System.Diagnostics.Contracts;
22 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
23 internal static class AnsiCharMarshaler
25 // The length of the returned array is an approximation based on the length of the input string and the system
26 // character set. It is only guaranteed to be larger or equal to cbLength, don't depend on the exact value.
27 [System.Security.SecurityCritical]
28 unsafe static internal byte[] DoAnsiConversion(string str, bool fBestFit, bool fThrowOnUnmappableChar, out int cbLength)
30 byte[] buffer = new byte[(str.Length + 1) * Marshal.SystemMaxDBCSCharSize];
31 fixed (byte *bufferPtr = buffer)
33 cbLength = str.ConvertToAnsi(bufferPtr, buffer.Length, fBestFit, fThrowOnUnmappableChar);
35 return buffer;
38 [System.Security.SecurityCritical]
39 unsafe static internal byte ConvertToNative(char managedChar, bool fBestFit, bool fThrowOnUnmappableChar)
41 int cbAllocLength = (1 + 1) * Marshal.SystemMaxDBCSCharSize;
42 byte* bufferPtr = stackalloc byte[cbAllocLength];
44 int cbLength = managedChar.ToString().ConvertToAnsi(bufferPtr, cbAllocLength, fBestFit, fThrowOnUnmappableChar);
46 BCLDebug.Assert(cbLength > 0, "Zero bytes returned from DoAnsiConversion in AnsiCharMarshaler.ConvertToNative");
47 return bufferPtr[0];
50 static internal char ConvertToManaged(byte nativeChar)
52 byte[] bytes = new byte[1] { nativeChar };
53 string str = Encoding.Default.GetString(bytes);
54 return str[0];
56 } // class AnsiCharMarshaler
58 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
59 internal static class CSTRMarshaler
61 [System.Security.SecurityCritical] // auto-generated
62 static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
64 if (null == strManaged)
66 return IntPtr.Zero;
69 StubHelpers.CheckStringLength(strManaged.Length);
71 int nb;
72 byte *pbNativeBuffer = (byte *)pNativeBuffer;
74 if (pbNativeBuffer != null || Marshal.SystemMaxDBCSCharSize == 1)
76 // If we are marshaling into a stack buffer or we can accurately estimate the size of the required heap
77 // space, we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer.
79 // + 1 for the null character from the user
80 nb = (strManaged.Length + 1) * Marshal.SystemMaxDBCSCharSize;
82 // Use the pre-allocated buffer (allocated by localloc IL instruction) if not NULL,
83 // otherwise fallback to AllocCoTaskMem
84 if (pbNativeBuffer == null)
86 // + 1 for the null character we put in
87 pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1);
90 nb = strManaged.ConvertToAnsi(pbNativeBuffer, nb + 1, 0 != (flags & 0xFF), 0 != (flags >> 8));
92 else
94 // Otherwise we use a slower "2-pass" mode where we first marshal the string into an intermediate buffer
95 // (managed byte array) and then allocate exactly the right amount of unmanaged memory. This is to avoid
96 // wasting memory on systems with multibyte character sets where the buffer we end up with is often much
97 // smaller than the upper bound for the given managed string.
99 byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb);
101 // + 1 for the null character from the user. + 1 for the null character we put in.
102 pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 2);
104 Buffer.Memcpy(pbNativeBuffer, 0, bytes, 0, nb);
107 pbNativeBuffer[nb] = 0x00;
108 pbNativeBuffer[nb + 1] = 0x00;
110 return (IntPtr)pbNativeBuffer;
113 [System.Security.SecurityCritical] // auto-generated
114 static internal unsafe string ConvertToManaged(IntPtr cstr)
116 if (IntPtr.Zero == cstr)
117 return null;
118 else
119 return new String((sbyte*)cstr);
122 [System.Security.SecurityCritical] // auto-generated
123 static internal void ClearNative(IntPtr pNative)
125 Win32Native.CoTaskMemFree(pNative);
127 } // class CSTRMarshaler
129 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
130 internal static class UTF8Marshaler
132 const int MAX_UTF8_CHAR_SIZE = 3;
133 [System.Security.SecurityCritical]
134 static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
136 if (null == strManaged)
138 return IntPtr.Zero;
140 StubHelpers.CheckStringLength(strManaged.Length);
142 int nb;
143 byte* pbNativeBuffer = (byte*)pNativeBuffer;
145 // If we are marshaling into a stack buffer allocated by the ILStub
146 // we will use a "1-pass" mode where we convert the string directly into the unmanaged buffer.
147 // else we will allocate the precise native heap memory.
148 if (pbNativeBuffer != null)
150 // this is the number of bytes allocated by the ILStub.
151 nb = (strManaged.Length + 1) * MAX_UTF8_CHAR_SIZE;
153 // nb is the actual number of bytes written by Encoding.GetBytes.
154 // use nb to de-limit the string since we are allocating more than
155 // required on stack
156 nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8);
158 // required bytes > 260 , allocate required bytes on heap
159 else
161 nb = Encoding.UTF8.GetByteCount(strManaged);
162 // + 1 for the null character.
163 pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1);
164 strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8);
166 pbNativeBuffer[nb] = 0x0;
167 return (IntPtr)pbNativeBuffer;
170 [System.Security.SecurityCritical]
171 static internal unsafe string ConvertToManaged(IntPtr cstr)
173 if (IntPtr.Zero == cstr)
174 return null;
175 int nbBytes = StubHelpers.strlen((sbyte*)cstr);
176 return String.CreateStringFromEncoding((byte*)cstr, nbBytes, Encoding.UTF8);
179 [System.Security.SecurityCritical]
180 static internal void ClearNative(IntPtr pNative)
182 if (pNative != IntPtr.Zero)
184 Win32Native.CoTaskMemFree(pNative);
189 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
190 internal static class UTF8BufferMarshaler
192 [System.Security.SecurityCritical]
193 static internal unsafe IntPtr ConvertToNative(StringBuilder sb, IntPtr pNativeBuffer, int flags)
195 if (null == sb)
197 return IntPtr.Zero;
200 // Convert to string first
201 string strManaged = sb.ToString();
203 // Get byte count
204 int nb = Encoding.UTF8.GetByteCount(strManaged);
206 // EmitConvertSpaceCLRToNative allocates memory
207 byte* pbNativeBuffer = (byte*)pNativeBuffer;
208 nb = strManaged.GetBytesFromEncoding(pbNativeBuffer, nb, Encoding.UTF8);
210 pbNativeBuffer[nb] = 0x0;
211 return (IntPtr)pbNativeBuffer;
214 [System.Security.SecurityCritical]
215 static internal unsafe void ConvertToManaged(StringBuilder sb, IntPtr pNative)
217 if (pNative == null)
218 return;
220 int nbBytes = StubHelpers.strlen((sbyte*)pNative);
221 int numChar = Encoding.UTF8.GetCharCount((byte*)pNative, nbBytes);
223 // +1 GetCharCount return 0 if the pNative points to a
224 // an empty buffer.We still need to allocate an empty
225 // buffer with a '\0' to distingiush it from null.
226 // Note that pinning on (char *pinned = new char[0])
227 // return null and Encoding.UTF8.GetChars do not like
228 // null argument.
229 char[] cCharBuffer = new char[numChar + 1];
230 cCharBuffer[numChar] = '\0';
231 fixed (char* pBuffer = cCharBuffer)
233 numChar = Encoding.UTF8.GetChars((byte*)pNative, nbBytes, pBuffer, numChar);
234 // replace string builder internal buffer
235 sb.ReplaceBufferInternal(pBuffer, numChar);
240 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
241 internal static class BSTRMarshaler
243 [System.Security.SecurityCritical] // auto-generated
244 static internal unsafe IntPtr ConvertToNative(string strManaged, IntPtr pNativeBuffer)
246 if (null == strManaged)
248 return IntPtr.Zero;
250 else
252 StubHelpers.CheckStringLength(strManaged.Length);
254 byte trailByte;
255 bool hasTrailByte = strManaged.TryGetTrailByte(out trailByte);
257 uint lengthInBytes = (uint)strManaged.Length * 2;
259 if (hasTrailByte)
261 // this is an odd-sized string with a trailing byte stored in its sync block
262 lengthInBytes++;
265 byte *ptrToFirstChar;
267 if (pNativeBuffer != IntPtr.Zero)
269 // If caller provided a buffer, construct the BSTR manually. The size
270 // of the buffer must be at least (lengthInBytes + 6) bytes.
271 #if _DEBUG
272 uint length = *((uint *)pNativeBuffer.ToPointer());
273 BCLDebug.Assert(length >= lengthInBytes + 6, "BSTR localloc'ed buffer is too small");
274 #endif // _DEBUG
276 // set length
277 *((uint *)pNativeBuffer.ToPointer()) = lengthInBytes;
279 ptrToFirstChar = (byte *)pNativeBuffer.ToPointer() + 4;
281 else
283 // If not provided, allocate the buffer using SysAllocStringByteLen so
284 // that odd-sized strings will be handled as well.
285 ptrToFirstChar = (byte *)Win32Native.SysAllocStringByteLen(null, lengthInBytes).ToPointer();
288 // copy characters from the managed string
289 fixed (char* ch = strManaged)
291 Buffer.Memcpy(
292 ptrToFirstChar,
293 (byte *)ch,
294 (strManaged.Length + 1) * 2);
297 // copy the trail byte if present
298 if (hasTrailByte)
300 ptrToFirstChar[lengthInBytes - 1] = trailByte;
303 // return ptr to first character
304 return (IntPtr)ptrToFirstChar;
308 [System.Security.SecurityCritical] // auto-generated
309 static internal unsafe string ConvertToManaged(IntPtr bstr)
311 if (IntPtr.Zero == bstr)
313 return null;
315 else
317 uint length = Win32Native.SysStringByteLen(bstr);
319 // Intentionally checking the number of bytes not characters to match the behavior
320 // of ML marshalers. This prevents roundtripping of very large strings as the check
321 // in the managed->native direction is done on String length but considering that
322 // it's completely moot on 32-bit and not expected to be important on 64-bit either,
323 // the ability to catch random garbage in the BSTR's length field outweighs this
324 // restriction. If an ordinary null-terminated string is passed instead of a BSTR,
325 // chances are that the length field - possibly being unallocated memory - contains
326 // a heap fill pattern that will have the highest bit set, caught by the check.
327 StubHelpers.CheckStringLength(length);
329 string ret;
330 if (length == 1)
332 // In the empty string case, we need to use FastAllocateString rather than the
333 // String .ctor, since newing up a 0 sized string will always return String.Emtpy.
334 // When we marshal that out as a bstr, it can wind up getting modified which
335 // corrupts String.Empty.
336 ret = String.FastAllocateString(0);
338 else
340 ret = new String((char*)bstr, 0, (int)(length / 2));
343 if ((length & 1) == 1)
345 // odd-sized strings need to have the trailing byte saved in their sync block
346 ret.SetTrailByte(((byte *)bstr.ToPointer())[length - 1]);
349 return ret;
353 [System.Security.SecurityCritical] // auto-generated
354 static internal void ClearNative(IntPtr pNative)
356 if (IntPtr.Zero != pNative)
358 Win32Native.SysFreeString(pNative);
361 } // class BSTRMarshaler
363 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
364 internal static class VBByValStrMarshaler
366 [System.Security.SecurityCritical] // auto-generated
367 static internal unsafe IntPtr ConvertToNative(string strManaged, bool fBestFit, bool fThrowOnUnmappableChar, ref int cch)
369 if (null == strManaged)
371 return IntPtr.Zero;
374 byte* pNative;
376 cch = strManaged.Length;
378 StubHelpers.CheckStringLength(cch);
380 // length field at negative offset + (# of characters incl. the terminator) * max ANSI char size
381 int nbytes = sizeof(uint) + ((cch + 1) * Marshal.SystemMaxDBCSCharSize);
383 pNative = (byte*)Marshal.AllocCoTaskMem(nbytes);
384 int* pLength = (int*)pNative;
386 pNative = pNative + sizeof(uint);
388 if (0 == cch)
390 *pNative = 0;
391 *pLength = 0;
393 else
395 int nbytesused;
396 byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, fBestFit, fThrowOnUnmappableChar, out nbytesused);
398 BCLDebug.Assert(nbytesused < nbytes, "Insufficient buffer allocated in VBByValStrMarshaler.ConvertToNative");
399 Buffer.Memcpy(pNative, 0, bytes, 0, nbytesused);
401 pNative[nbytesused] = 0;
402 *pLength = nbytesused;
405 return new IntPtr(pNative);
408 [System.Security.SecurityCritical] // auto-generated
409 static internal unsafe string ConvertToManaged(IntPtr pNative, int cch)
411 if (IntPtr.Zero == pNative)
413 return null;
416 return new String((sbyte*)pNative, 0, cch);
419 [System.Security.SecurityCritical] // auto-generated
420 static internal unsafe void ClearNative(IntPtr pNative)
422 if (IntPtr.Zero != pNative)
424 Win32Native.CoTaskMemFree((IntPtr)(((long)pNative) - sizeof(uint)));
427 } // class VBByValStrMarshaler
429 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
430 internal static class AnsiBSTRMarshaler
432 [System.Security.SecurityCritical] // auto-generated
433 static internal unsafe IntPtr ConvertToNative(int flags, string strManaged)
435 if (null == strManaged)
437 return IntPtr.Zero;
440 int length = strManaged.Length;
442 StubHelpers.CheckStringLength(length);
444 byte[] bytes = null;
445 int nb = 0;
447 if (length > 0)
449 bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb);
452 return Win32Native.SysAllocStringByteLen(bytes, (uint)nb);
455 [System.Security.SecurityCritical] // auto-generated
456 static internal unsafe string ConvertToManaged(IntPtr bstr)
458 if (IntPtr.Zero == bstr)
460 return null;
462 else
464 // We intentionally ignore the length field of the BSTR for back compat reasons.
465 // Unfortunately VB.NET uses Ansi BSTR marshaling when a string is passed ByRef
466 // and we cannot afford to break this common scenario.
467 return new String((sbyte*)bstr);
471 [System.Security.SecurityCritical] // auto-generated
472 static internal unsafe void ClearNative(IntPtr pNative)
474 if (IntPtr.Zero != pNative)
476 Win32Native.SysFreeString(pNative);
479 } // class AnsiBSTRMarshaler
481 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
482 internal static class WSTRBufferMarshaler
484 static internal IntPtr ConvertToNative(string strManaged)
486 Contract.Assert(false, "NYI");
487 return IntPtr.Zero;
490 static internal unsafe string ConvertToManaged(IntPtr bstr)
492 Contract.Assert(false, "NYI");
493 return null;
496 static internal void ClearNative(IntPtr pNative)
498 Contract.Assert(false, "NYI");
500 } // class WSTRBufferMarshaler
503 #if FEATURE_COMINTEROP
506 [StructLayout(LayoutKind.Sequential)]
507 internal struct DateTimeNative
509 public Int64 UniversalTime;
512 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
513 internal static class DateTimeOffsetMarshaler {
515 // Numer of ticks counted between 0001-01-01, 00:00:00 and 1601-01-01, 00:00:00.
516 // You can get this through: (new DateTimeOffset(1601, 1, 1, 0, 0, 1, TimeSpan.Zero)).Ticks;
517 private const Int64 ManagedUtcTicksAtNativeZero = 504911232000000000;
519 [SecurityCritical]
520 internal static void ConvertToNative(ref DateTimeOffset managedDTO, out DateTimeNative dateTime) {
522 Int64 managedUtcTicks = managedDTO.UtcTicks;
523 dateTime.UniversalTime = managedUtcTicks - ManagedUtcTicksAtNativeZero;
526 [SecurityCritical]
527 internal static void ConvertToManaged(out DateTimeOffset managedLocalDTO, ref DateTimeNative nativeTicks) {
529 Int64 managedUtcTicks = ManagedUtcTicksAtNativeZero + nativeTicks.UniversalTime;
530 DateTimeOffset managedUtcDTO = new DateTimeOffset(managedUtcTicks, TimeSpan.Zero);
532 // Some Utc times cannot be represented in local time in certain timezones. E.g. 0001-01-01 12:00:00 AM cannot
533 // be represented in any timezones with a negative offset from Utc. We throw an ArgumentException in that case.
534 managedLocalDTO = managedUtcDTO.ToLocalTime(true);
536 } // class DateTimeOffsetMarshaler
538 #endif // FEATURE_COMINTEROP
541 #if FEATURE_COMINTEROP
542 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
543 internal static class HStringMarshaler
545 // Slow-path, which requires making a copy of the managed string into the resulting HSTRING
546 [SecurityCritical]
547 internal static unsafe IntPtr ConvertToNative(string managed)
549 if (!Environment.IsWinRTSupported)
550 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
551 if (managed == null)
552 throw new ArgumentNullException(); // We don't have enough information to get the argument name just yet - that support will be coming in M3
554 IntPtr hstring;
555 int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString(managed, managed.Length, &hstring);
556 Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
557 return hstring;
560 // Fast-path, which creates a reference over a pinned managed string. This may only be used if the
561 // pinned string and HSTRING_HEADER will outlive the HSTRING produced (for instance, as an in parameter).
563 // Note that the managed string input to this method MUST be pinned, and stay pinned for the lifetime of
564 // the returned HSTRING object. If the string is not pinned, or becomes unpinned before the HSTRING's
565 // lifetime ends, the HSTRING instance will be corrupted.
566 [SecurityCritical]
567 internal static unsafe IntPtr ConvertToNativeReference(string managed,
568 [Out] HSTRING_HEADER *hstringHeader)
570 if (!Environment.IsWinRTSupported)
571 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
572 if (managed == null)
573 throw new ArgumentNullException(); // We don't have enough information to get the argument name just yet - that support will be coming in M3
575 // The string must also be pinned by the caller to ConvertToNativeReference, which also owns
576 // the HSTRING_HEADER.
577 fixed (char *pManaged = managed)
579 IntPtr hstring;
580 int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateStringReference(pManaged, managed.Length, hstringHeader, &hstring);
581 Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
582 return hstring;
586 [SecurityCritical]
587 internal static string ConvertToManaged(IntPtr hstring)
589 if (!Environment.IsWinRTSupported)
591 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
594 return WindowsRuntimeMarshal.HStringToString(hstring);
597 [SecurityCritical]
598 internal static void ClearNative(IntPtr hstring)
600 Contract.Assert(Environment.IsWinRTSupported);
602 if (hstring != IntPtr.Zero)
604 System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString(hstring);
607 } // class HStringMarshaler
609 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
610 internal static class ObjectMarshaler
612 [MethodImplAttribute(MethodImplOptions.InternalCall)]
613 static internal extern void ConvertToNative(object objSrc, IntPtr pDstVariant);
615 [MethodImplAttribute(MethodImplOptions.InternalCall)]
616 static internal extern object ConvertToManaged(IntPtr pSrcVariant);
618 [MethodImplAttribute(MethodImplOptions.InternalCall)]
619 static internal extern void ClearNative(IntPtr pVariant);
620 } // class ObjectMarshaler
622 #endif // FEATURE_COMINTEROP
624 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
625 internal static class ValueClassMarshaler
627 [SecurityCritical]
628 [MethodImplAttribute(MethodImplOptions.InternalCall)]
629 static internal extern void ConvertToNative(IntPtr dst, IntPtr src, IntPtr pMT, ref CleanupWorkList pCleanupWorkList);
631 [MethodImplAttribute(MethodImplOptions.InternalCall)]
632 static internal extern void ConvertToManaged(IntPtr dst, IntPtr src, IntPtr pMT);
634 [MethodImplAttribute(MethodImplOptions.InternalCall)]
635 static internal extern void ClearNative(IntPtr dst, IntPtr pMT);
636 } // class ValueClassMarshaler
638 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
639 internal static class DateMarshaler
641 [MethodImplAttribute(MethodImplOptions.InternalCall)]
642 static internal extern double ConvertToNative(DateTime managedDate);
644 // The return type is really DateTime but we use long to avoid the pain associated with returning structures.
645 [MethodImplAttribute(MethodImplOptions.InternalCall)]
646 static internal extern long ConvertToManaged(double nativeDate);
647 } // class DateMarshaler
649 #if FEATURE_COMINTEROP
650 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
651 [FriendAccessAllowed]
652 internal static class InterfaceMarshaler
654 [MethodImplAttribute(MethodImplOptions.InternalCall)]
655 static internal extern IntPtr ConvertToNative(object objSrc, IntPtr itfMT, IntPtr classMT, int flags);
657 [MethodImplAttribute(MethodImplOptions.InternalCall)]
658 static internal extern object ConvertToManaged(IntPtr pUnk, IntPtr itfMT, IntPtr classMT, int flags);
660 [SecurityCritical]
661 [DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
662 static internal extern void ClearNative(IntPtr pUnk);
664 [FriendAccessAllowed]
665 [MethodImplAttribute(MethodImplOptions.InternalCall)]
666 static internal extern object ConvertToManagedWithoutUnboxing(IntPtr pNative);
667 } // class InterfaceMarshaler
668 #endif // FEATURE_COMINTEROP
670 #if FEATURE_COMINTEROP
671 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
672 internal static class UriMarshaler
674 [MethodImplAttribute(MethodImplOptions.InternalCall)]
675 static internal extern string GetRawUriFromNative(IntPtr pUri);
677 [MethodImplAttribute(MethodImplOptions.InternalCall)]
678 [System.Security.SecurityCritical]
679 static unsafe internal extern IntPtr CreateNativeUriInstanceHelper(char* rawUri, int strLen);
681 [System.Security.SecurityCritical]
682 static unsafe internal IntPtr CreateNativeUriInstance(string rawUri)
684 fixed(char* pManaged = rawUri)
686 return CreateNativeUriInstanceHelper(pManaged, rawUri.Length);
690 } // class InterfaceMarshaler
692 [FriendAccessAllowed]
693 internal static class EventArgsMarshaler
695 [SecurityCritical]
696 [FriendAccessAllowed]
697 static internal IntPtr CreateNativeNCCEventArgsInstance(int action, object newItems, object oldItems, int newIndex, int oldIndex)
699 IntPtr newItemsIP = IntPtr.Zero;
700 IntPtr oldItemsIP = IntPtr.Zero;
702 RuntimeHelpers.PrepareConstrainedRegions();
705 if (newItems != null)
706 newItemsIP = Marshal.GetComInterfaceForObject(newItems, typeof(IBindableVector));
707 if (oldItems != null)
708 oldItemsIP = Marshal.GetComInterfaceForObject(oldItems, typeof(IBindableVector));
710 return CreateNativeNCCEventArgsInstanceHelper(action, newItemsIP, oldItemsIP, newIndex, oldIndex);
712 finally
714 if (!oldItemsIP.IsNull())
715 Marshal.Release(oldItemsIP);
716 if (!newItemsIP.IsNull())
717 Marshal.Release(newItemsIP);
721 [SecurityCritical]
722 [FriendAccessAllowed]
723 [DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
724 static extern internal IntPtr CreateNativePCEventArgsInstance([MarshalAs(UnmanagedType.HString)]string name);
726 [SecurityCritical]
727 [DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
728 static extern internal IntPtr CreateNativeNCCEventArgsInstanceHelper(int action, IntPtr newItem, IntPtr oldItem, int newIndex, int oldIndex);
730 #endif // FEATURE_COMINTEROP
732 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
733 internal static class MngdNativeArrayMarshaler
735 [MethodImplAttribute(MethodImplOptions.InternalCall)]
736 static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags);
738 [MethodImplAttribute(MethodImplOptions.InternalCall)]
739 static internal extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
741 [MethodImplAttribute(MethodImplOptions.InternalCall)]
742 static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
744 [MethodImplAttribute(MethodImplOptions.InternalCall)]
745 static internal extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome,
746 int cElements);
748 [MethodImplAttribute(MethodImplOptions.InternalCall)]
749 static internal extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
751 [MethodImplAttribute(MethodImplOptions.InternalCall)]
752 static internal extern void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
754 [MethodImplAttribute(MethodImplOptions.InternalCall)]
755 static internal extern void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
756 } // class MngdNativeArrayMarshaler
758 #if FEATURE_COMINTEROP
759 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
760 internal static class MngdSafeArrayMarshaler
762 [MethodImplAttribute(MethodImplOptions.InternalCall)]
763 static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int iRank, int dwFlags);
765 [MethodImplAttribute(MethodImplOptions.InternalCall)]
766 static internal extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
768 [MethodImplAttribute(MethodImplOptions.InternalCall)]
769 static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, object pOriginalManaged);
771 [MethodImplAttribute(MethodImplOptions.InternalCall)]
772 static internal extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
774 [MethodImplAttribute(MethodImplOptions.InternalCall)]
775 static internal extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
777 [MethodImplAttribute(MethodImplOptions.InternalCall)]
778 static internal extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
779 } // class MngdSafeArrayMarshaler
781 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
782 internal static class MngdHiddenLengthArrayMarshaler
784 [SecurityCritical]
785 [MethodImplAttribute(MethodImplOptions.InternalCall)]
786 static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, IntPtr cbElementSize, ushort vt);
788 [SecurityCritical]
789 [MethodImplAttribute(MethodImplOptions.InternalCall)]
790 internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
792 [SecurityCritical]
793 [MethodImplAttribute(MethodImplOptions.InternalCall)]
794 internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
796 [SecurityCritical]
797 internal static unsafe void ConvertContentsToNative_DateTime(ref DateTimeOffset[] managedArray, IntPtr pNativeHome)
799 if (managedArray != null)
801 DateTimeNative *nativeBuffer = *(DateTimeNative **)pNativeHome;
802 for (int i = 0; i < managedArray.Length; i++)
804 DateTimeOffsetMarshaler.ConvertToNative(ref managedArray[i], out nativeBuffer[i]);
809 [SecurityCritical]
810 internal static unsafe void ConvertContentsToNative_Type(ref System.Type[] managedArray, IntPtr pNativeHome)
812 if (managedArray != null)
814 TypeNameNative *nativeBuffer = *(TypeNameNative **)pNativeHome;
815 for (int i = 0; i < managedArray.Length; i++)
817 SystemTypeMarshaler.ConvertToNative(managedArray[i], &nativeBuffer[i]);
822 [SecurityCritical]
823 internal static unsafe void ConvertContentsToNative_Exception(ref Exception[] managedArray, IntPtr pNativeHome)
825 if (managedArray != null)
827 Int32 *nativeBuffer = *(Int32 **)pNativeHome;
828 for (int i = 0; i < managedArray.Length; i++)
830 nativeBuffer[i] = HResultExceptionMarshaler.ConvertToNative(managedArray[i]);
835 [SecurityCritical]
836 internal static unsafe void ConvertContentsToNative_Nullable<T>(ref Nullable<T>[] managedArray, IntPtr pNativeHome)
837 where T : struct
839 if (managedArray != null)
841 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
842 for (int i = 0; i < managedArray.Length; i++)
844 nativeBuffer[i] = NullableMarshaler.ConvertToNative<T>(ref managedArray[i]);
849 [SecurityCritical]
850 internal static unsafe void ConvertContentsToNative_KeyValuePair<K, V>(ref KeyValuePair<K, V>[] managedArray, IntPtr pNativeHome)
852 if (managedArray != null)
854 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
855 for (int i = 0; i < managedArray.Length; i++)
857 nativeBuffer[i] = KeyValuePairMarshaler.ConvertToNative<K, V>(ref managedArray[i]);
862 [SecurityCritical]
863 [MethodImplAttribute(MethodImplOptions.InternalCall)]
864 internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, int elementCount);
866 [SecurityCritical]
867 [MethodImplAttribute(MethodImplOptions.InternalCall)]
868 internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
870 [SecurityCritical]
871 internal static unsafe void ConvertContentsToManaged_DateTime(ref DateTimeOffset[] managedArray, IntPtr pNativeHome)
873 if (managedArray != null)
875 DateTimeNative *nativeBuffer = *(DateTimeNative **)pNativeHome;
876 for (int i = 0; i < managedArray.Length; i++)
878 DateTimeOffsetMarshaler.ConvertToManaged(out managedArray[i], ref nativeBuffer[i]);
883 [SecurityCritical]
884 internal static unsafe void ConvertContentsToManaged_Type(ref System.Type[] managedArray, IntPtr pNativeHome)
886 if (managedArray != null)
888 TypeNameNative *nativeBuffer = *(TypeNameNative **)pNativeHome;
889 for (int i = 0; i < managedArray.Length; i++)
891 SystemTypeMarshaler.ConvertToManaged(&nativeBuffer[i], ref managedArray[i]);
896 [SecurityCritical]
897 internal static unsafe void ConvertContentsToManaged_Exception(ref Exception[] managedArray, IntPtr pNativeHome)
899 if (managedArray != null)
901 Int32 *nativeBuffer = *(Int32 **)pNativeHome;
902 for (int i = 0; i < managedArray.Length; i++)
904 managedArray[i] = HResultExceptionMarshaler.ConvertToManaged(nativeBuffer[i]);
909 [SecurityCritical]
910 internal static unsafe void ConvertContentsToManaged_Nullable<T>(ref Nullable<T>[] managedArray, IntPtr pNativeHome)
911 where T : struct
913 if (managedArray != null)
915 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
916 for (int i = 0; i < managedArray.Length; i++)
918 managedArray[i] = NullableMarshaler.ConvertToManaged<T>(nativeBuffer[i]);
923 [SecurityCritical]
924 internal static unsafe void ConvertContentsToManaged_KeyValuePair<K, V>(ref KeyValuePair<K, V>[] managedArray, IntPtr pNativeHome)
926 if (managedArray != null)
928 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
929 for (int i = 0; i < managedArray.Length; i++)
931 managedArray[i] = KeyValuePairMarshaler.ConvertToManaged<K, V>(nativeBuffer[i]);
936 [SecurityCritical]
937 [MethodImplAttribute(MethodImplOptions.InternalCall)]
938 internal static extern void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
940 [SecurityCritical]
941 internal static unsafe void ClearNativeContents_Type(IntPtr pNativeHome, int cElements)
943 Contract.Assert(Environment.IsWinRTSupported);
945 TypeNameNative *pNativeTypeArray = *(TypeNameNative **)pNativeHome;
946 if (pNativeTypeArray != null)
948 for (int i = 0; i < cElements; ++i)
950 SystemTypeMarshaler.ClearNative(pNativeTypeArray);
951 pNativeTypeArray++;
955 } // class MngdHiddenLengthArrayMarshaler
957 #endif // FEATURE_COMINTEROP
959 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
960 internal static class MngdRefCustomMarshaler
962 [MethodImplAttribute(MethodImplOptions.InternalCall)]
963 static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pCMHelper);
965 [MethodImplAttribute(MethodImplOptions.InternalCall)]
966 static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
968 [MethodImplAttribute(MethodImplOptions.InternalCall)]
969 static internal extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
971 [MethodImplAttribute(MethodImplOptions.InternalCall)]
972 static internal extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
974 [MethodImplAttribute(MethodImplOptions.InternalCall)]
975 static internal extern void ClearManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
976 } // class MngdRefCustomMarshaler
978 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
979 [System.Security.SecurityCritical]
980 internal struct AsAnyMarshaler
982 private const ushort VTHACK_ANSICHAR = 253;
983 private const ushort VTHACK_WINBOOL = 254;
985 private enum BackPropAction
987 None,
988 Array,
989 Layout,
990 StringBuilderAnsi,
991 StringBuilderUnicode
994 // Pointer to MngdNativeArrayMarshaler, ownership not assumed.
995 private IntPtr pvArrayMarshaler;
997 // Type of action to perform after the CLR-to-unmanaged call.
998 private BackPropAction backPropAction;
1000 // The managed layout type for BackPropAction.Layout.
1001 private Type layoutType;
1003 // Cleanup list to be destroyed when clearing the native view (for layouts with SafeHandles).
1004 private CleanupWorkList cleanupWorkList;
1006 private static bool IsIn(int dwFlags) { return ((dwFlags & 0x10000000) != 0); }
1007 private static bool IsOut(int dwFlags) { return ((dwFlags & 0x20000000) != 0); }
1008 private static bool IsAnsi(int dwFlags) { return ((dwFlags & 0x00FF0000) != 0); }
1009 private static bool IsThrowOn(int dwFlags) { return ((dwFlags & 0x0000FF00) != 0); }
1010 private static bool IsBestFit(int dwFlags) { return ((dwFlags & 0x000000FF) != 0); }
1012 internal AsAnyMarshaler(IntPtr pvArrayMarshaler)
1014 // we need this in case the value being marshaled turns out to be array
1015 BCLDebug.Assert(pvArrayMarshaler != IntPtr.Zero, "pvArrayMarshaler must not be null");
1017 this.pvArrayMarshaler = pvArrayMarshaler;
1018 this.backPropAction = BackPropAction.None;
1019 this.layoutType = null;
1020 this.cleanupWorkList = null;
1023 #region ConvertToNative helpers
1025 [System.Security.SecurityCritical]
1026 private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags)
1028 Type elementType = pManagedHome.GetType().GetElementType();
1029 VarEnum vt = VarEnum.VT_EMPTY;
1031 switch (Type.GetTypeCode(elementType))
1033 case TypeCode.SByte: vt = VarEnum.VT_I1; break;
1034 case TypeCode.Byte: vt = VarEnum.VT_UI1; break;
1035 case TypeCode.Int16: vt = VarEnum.VT_I2; break;
1036 case TypeCode.UInt16: vt = VarEnum.VT_UI2; break;
1037 case TypeCode.Int32: vt = VarEnum.VT_I4; break;
1038 case TypeCode.UInt32: vt = VarEnum.VT_UI4; break;
1039 case TypeCode.Int64: vt = VarEnum.VT_I8; break;
1040 case TypeCode.UInt64: vt = VarEnum.VT_UI8; break;
1041 case TypeCode.Single: vt = VarEnum.VT_R4; break;
1042 case TypeCode.Double: vt = VarEnum.VT_R8; break;
1043 case TypeCode.Char: vt = (IsAnsi(dwFlags) ? (VarEnum)VTHACK_ANSICHAR : VarEnum.VT_UI2); break;
1044 case TypeCode.Boolean: vt = (VarEnum)VTHACK_WINBOOL; break;
1046 case TypeCode.Object:
1048 if (elementType == typeof(IntPtr))
1050 vt = (IntPtr.Size == 4 ? VarEnum.VT_I4 : VarEnum.VT_I8);
1052 else if (elementType == typeof(UIntPtr))
1054 vt = (IntPtr.Size == 4 ? VarEnum.VT_UI4 : VarEnum.VT_UI8);
1056 else goto default;
1057 break;
1060 default:
1061 throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject"));
1064 // marshal the object as C-style array (UnmanagedType.LPArray)
1065 int dwArrayMarshalerFlags = (int)vt;
1066 if (IsBestFit(dwFlags)) dwArrayMarshalerFlags |= (1 << 16);
1067 if (IsThrowOn(dwFlags)) dwArrayMarshalerFlags |= (1 << 24);
1069 MngdNativeArrayMarshaler.CreateMarshaler(
1070 pvArrayMarshaler,
1071 IntPtr.Zero, // not needed as we marshal primitive VTs only
1072 dwArrayMarshalerFlags);
1074 IntPtr pNativeHome;
1075 IntPtr pNativeHomeAddr = new IntPtr(&pNativeHome);
1077 MngdNativeArrayMarshaler.ConvertSpaceToNative(
1078 pvArrayMarshaler,
1079 ref pManagedHome,
1080 pNativeHomeAddr);
1082 if (IsIn(dwFlags))
1084 MngdNativeArrayMarshaler.ConvertContentsToNative(
1085 pvArrayMarshaler,
1086 ref pManagedHome,
1087 pNativeHomeAddr);
1089 if (IsOut(dwFlags))
1091 backPropAction = BackPropAction.Array;
1094 return pNativeHome;
1097 [System.Security.SecurityCritical]
1098 private static IntPtr ConvertStringToNative(string pManagedHome, int dwFlags)
1100 IntPtr pNativeHome;
1102 // IsIn, IsOut are ignored for strings - they're always in-only
1103 if (IsAnsi(dwFlags))
1105 // marshal the object as Ansi string (UnmanagedType.LPStr)
1106 pNativeHome = CSTRMarshaler.ConvertToNative(
1107 dwFlags & 0xFFFF, // (throw on unmappable char << 8 | best fit)
1108 pManagedHome, //
1109 IntPtr.Zero); // unmanaged buffer will be allocated
1111 else
1113 // marshal the object as Unicode string (UnmanagedType.LPWStr)
1114 StubHelpers.CheckStringLength(pManagedHome.Length);
1116 int allocSize = (pManagedHome.Length + 1) * 2;
1117 pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1119 String.InternalCopy(pManagedHome, pNativeHome, allocSize);
1122 return pNativeHome;
1125 [System.Security.SecurityCritical]
1126 private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags)
1128 IntPtr pNativeHome;
1130 // P/Invoke can be used to call Win32 apis that don't strictly follow CLR in/out semantics and thus may
1131 // leave garbage in the buffer in circumstances that we can't detect. To prevent us from crashing when
1132 // converting the contents back to managed, put a hidden NULL terminator past the end of the official buffer.
1134 // Unmanaged layout:
1135 // +====================================+
1136 // | Extra hidden NULL |
1137 // +====================================+ \
1138 // | | |
1139 // | [Converted] NULL-terminated string | |- buffer that the target may change
1140 // | | |
1141 // +====================================+ / <-- native home
1143 // Note that StringBuilder.Capacity is the number of characters NOT including any terminators.
1145 if (IsAnsi(dwFlags))
1147 StubHelpers.CheckStringLength(pManagedHome.Capacity);
1149 // marshal the object as Ansi string (UnmanagedType.LPStr)
1150 int allocSize = (pManagedHome.Capacity * Marshal.SystemMaxDBCSCharSize) + 4;
1151 pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1153 byte* ptr = (byte*)pNativeHome;
1154 *(ptr + allocSize - 3) = 0;
1155 *(ptr + allocSize - 2) = 0;
1156 *(ptr + allocSize - 1) = 0;
1158 if (IsIn(dwFlags))
1160 int length;
1162 byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(
1163 pManagedHome.ToString(),
1164 IsBestFit(dwFlags),
1165 IsThrowOn(dwFlags),
1166 out length);
1168 Buffer.Memcpy(
1169 ptr, // dst buffer
1170 0, // dts index
1171 bytes, // src array
1172 0, // src index
1173 length); // len
1175 // null-terminate the native string
1176 *(ptr + length) = 0;
1178 if (IsOut(dwFlags))
1180 backPropAction = BackPropAction.StringBuilderAnsi;
1183 else
1185 // marshal the object as Unicode string (UnmanagedType.LPWStr)
1186 int allocSize = (pManagedHome.Capacity * 2) + 4;
1187 pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1189 byte* ptr = (byte*)pNativeHome;
1190 *(ptr + allocSize - 1) = 0;
1191 *(ptr + allocSize - 2) = 0;
1193 if (IsIn(dwFlags))
1195 int length = pManagedHome.Length * 2;
1196 pManagedHome.InternalCopy(pNativeHome, length);
1198 // null-terminate the native string
1199 *(ptr + length + 0) = 0;
1200 *(ptr + length + 1) = 0;
1202 if (IsOut(dwFlags))
1204 backPropAction = BackPropAction.StringBuilderUnicode;
1208 return pNativeHome;
1211 [System.Security.SecurityCritical]
1212 private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags)
1214 // Note that the following call will not throw exception if the type
1215 // of pManagedHome is not marshalable. That's intentional because we
1216 // want to maintain the original behavior where this was indicated
1217 // by TypeLoadException during the actual field marshaling.
1218 int allocSize = Marshal.SizeOfHelper(pManagedHome.GetType(), false);
1219 IntPtr pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1221 // marshal the object as class with layout (UnmanagedType.LPStruct)
1222 if (IsIn(dwFlags))
1224 StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte *)pNativeHome.ToPointer(), ref cleanupWorkList);
1226 if (IsOut(dwFlags))
1228 backPropAction = BackPropAction.Layout;
1230 layoutType = pManagedHome.GetType();
1232 return pNativeHome;
1235 #endregion
1237 [System.Security.SecurityCritical]
1238 internal IntPtr ConvertToNative(object pManagedHome, int dwFlags)
1240 if (pManagedHome == null)
1241 return IntPtr.Zero;
1243 if (pManagedHome is ArrayWithOffset)
1244 throw new ArgumentException(Environment.GetResourceString("Arg_MarshalAsAnyRestriction"));
1246 IntPtr pNativeHome;
1248 if (pManagedHome.GetType().IsArray)
1250 // array (LPArray)
1251 pNativeHome = ConvertArrayToNative(pManagedHome, dwFlags);
1253 else
1255 string strValue;
1256 StringBuilder sbValue;
1258 if ((strValue = pManagedHome as string) != null)
1260 // string (LPStr or LPWStr)
1261 pNativeHome = ConvertStringToNative(strValue, dwFlags);
1263 else if ((sbValue = pManagedHome as StringBuilder) != null)
1265 // StringBuilder (LPStr or LPWStr)
1266 pNativeHome = ConvertStringBuilderToNative(sbValue, dwFlags);
1268 else if (pManagedHome.GetType().IsLayoutSequential || pManagedHome.GetType().IsExplicitLayout)
1270 // layout (LPStruct)
1271 pNativeHome = ConvertLayoutToNative(pManagedHome, dwFlags);
1273 else
1275 // this type is not supported for AsAny marshaling
1276 throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject"));
1280 return pNativeHome;
1283 [System.Security.SecurityCritical]
1284 internal unsafe void ConvertToManaged(object pManagedHome, IntPtr pNativeHome)
1286 switch (backPropAction)
1288 case BackPropAction.Array:
1290 MngdNativeArrayMarshaler.ConvertContentsToManaged(
1291 pvArrayMarshaler,
1292 ref pManagedHome,
1293 new IntPtr(&pNativeHome));
1294 break;
1297 case BackPropAction.Layout:
1299 StubHelpers.FmtClassUpdateCLRInternal(pManagedHome, (byte *)pNativeHome.ToPointer());
1300 break;
1303 case BackPropAction.StringBuilderAnsi:
1305 sbyte* ptr = (sbyte*)pNativeHome.ToPointer();
1306 ((StringBuilder)pManagedHome).ReplaceBufferAnsiInternal(ptr, Win32Native.lstrlenA(pNativeHome));
1307 break;
1310 case BackPropAction.StringBuilderUnicode:
1312 char* ptr = (char*)pNativeHome.ToPointer();
1313 ((StringBuilder)pManagedHome).ReplaceBufferInternal(ptr, Win32Native.lstrlenW(pNativeHome));
1314 break;
1317 // nothing to do for BackPropAction.None
1321 [System.Security.SecurityCritical]
1322 internal void ClearNative(IntPtr pNativeHome)
1324 if (pNativeHome != IntPtr.Zero)
1326 if (layoutType != null)
1328 // this must happen regardless of BackPropAction
1329 Marshal.DestroyStructure(pNativeHome, layoutType);
1331 Win32Native.CoTaskMemFree(pNativeHome);
1333 StubHelpers.DestroyCleanupList(ref cleanupWorkList);
1335 } // struct AsAnyMarshaler
1337 #if FEATURE_COMINTEROP
1338 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1339 internal static class NullableMarshaler
1341 [SecurityCritical]
1342 static internal IntPtr ConvertToNative<T>(ref Nullable<T> pManaged) where T : struct
1344 if (pManaged.HasValue)
1346 object impl = IReferenceFactory.CreateIReference(pManaged);
1347 return Marshal.GetComInterfaceForObject(impl, typeof(IReference<T>));
1349 else
1351 return IntPtr.Zero;
1355 [SecurityCritical]
1356 static internal void ConvertToManagedRetVoid<T>(IntPtr pNative, ref Nullable<T> retObj) where T : struct
1358 retObj = ConvertToManaged<T>(pNative);
1362 [SecurityCritical]
1363 static internal Nullable<T> ConvertToManaged<T>(IntPtr pNative) where T : struct
1365 if (pNative != IntPtr.Zero)
1367 object wrapper = InterfaceMarshaler.ConvertToManagedWithoutUnboxing(pNative);
1368 return (Nullable<T>)CLRIReferenceImpl<T>.UnboxHelper(wrapper);
1370 else
1372 return new Nullable<T>();
1375 } // class NullableMarshaler
1377 // Corresponds to Windows.UI.Xaml.Interop.TypeName
1378 [StructLayout(LayoutKind.Sequential)]
1379 internal struct TypeNameNative
1382 internal IntPtr typeName; // HSTRING
1383 internal TypeKind typeKind; // TypeKind enum
1386 // Corresponds to Windows.UI.Xaml.TypeSource
1387 internal enum TypeKind
1389 Primitive,
1390 Metadata,
1391 Projection
1394 internal static class WinRTTypeNameConverter
1396 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1397 internal static extern string ConvertToWinRTTypeName(System.Type managedType, out bool isPrimitive);
1399 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1400 internal static extern System.Type GetTypeFromWinRTTypeName(string typeName, out bool isPrimitive);
1403 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1404 internal static class SystemTypeMarshaler
1406 [SecurityCritical]
1407 internal static unsafe void ConvertToNative(System.Type managedType, TypeNameNative *pNativeType)
1409 if (!Environment.IsWinRTSupported)
1411 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1414 string typeName;
1415 if (managedType != null)
1417 if (managedType.GetType() != typeof(System.RuntimeType))
1418 { // The type should be exactly System.RuntimeType (and not its child System.ReflectionOnlyType, or other System.Type children)
1419 throw new ArgumentException(Environment.GetResourceString("Argument_WinRTSystemRuntimeType", managedType.GetType().ToString()));
1422 bool isPrimitive;
1423 string winrtTypeName = WinRTTypeNameConverter.ConvertToWinRTTypeName(managedType, out isPrimitive);
1424 if (winrtTypeName != null)
1426 // Must be a WinRT type, either in a WinMD or a Primitive
1427 typeName = winrtTypeName;
1428 if (isPrimitive)
1429 pNativeType->typeKind = TypeKind.Primitive;
1430 else
1431 pNativeType->typeKind = TypeKind.Metadata;
1433 else
1435 // Custom .NET type
1436 typeName = managedType.AssemblyQualifiedName;
1437 pNativeType->typeKind = TypeKind.Projection;
1440 else
1441 { // Marshal null as empty string + Projection
1442 typeName = "";
1443 pNativeType->typeKind = TypeKind.Projection;
1446 int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString(typeName, typeName.Length, &pNativeType->typeName);
1447 Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
1450 [SecurityCritical]
1451 internal static unsafe void ConvertToManaged(TypeNameNative *pNativeType, ref System.Type managedType)
1453 if (!Environment.IsWinRTSupported)
1455 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1458 string typeName = WindowsRuntimeMarshal.HStringToString(pNativeType->typeName);
1459 if (String.IsNullOrEmpty(typeName))
1461 managedType = null;
1462 return;
1465 if (pNativeType->typeKind == TypeKind.Projection)
1467 managedType = Type.GetType(typeName, /* throwOnError = */ true);
1469 else
1471 bool isPrimitive;
1472 managedType = WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out isPrimitive);
1474 // TypeSource must match
1475 if (isPrimitive != (pNativeType->typeKind == TypeKind.Primitive))
1476 throw new ArgumentException(Environment.GetResourceString("Argument_Unexpected_TypeSource"));
1480 [SecurityCritical]
1481 internal static unsafe void ClearNative(TypeNameNative *pNativeType)
1483 Contract.Assert(Environment.IsWinRTSupported);
1485 if (pNativeType->typeName != null)
1487 System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString(pNativeType->typeName);
1490 } // class SystemTypeMarshaler
1492 // For converting WinRT's Windows.Foundation.HResult into System.Exception and vice versa.
1493 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1494 internal static class HResultExceptionMarshaler
1496 static internal unsafe int ConvertToNative(Exception ex)
1498 if (!Environment.IsWinRTSupported)
1500 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1503 if (ex == null)
1504 return 0; // S_OK;
1506 return ex._HResult;
1509 [SecuritySafeCritical]
1510 static internal unsafe Exception ConvertToManaged(int hr)
1512 Contract.Ensures(Contract.Result<Exception>() != null || hr >= 0);
1514 if (!Environment.IsWinRTSupported)
1516 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1519 Exception e = null;
1520 if (hr < 0)
1522 e = StubHelpers.InternalGetCOMHRExceptionObject(hr, IntPtr.Zero, null, /* fForWinRT */ true);
1525 // S_OK should be marshaled as null. WinRT API's should not return S_FALSE by convention.
1526 // We've chosen to treat S_FALSE as success and return null.
1527 Contract.Assert(e != null || hr == 0 || hr == 1, "Unexpected HRESULT - it is a success HRESULT (without the high bit set) other than S_OK & S_FALSE.");
1528 return e;
1530 } // class HResultExceptionMarshaler
1532 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1533 internal static class KeyValuePairMarshaler
1535 [SecurityCritical]
1536 internal static IntPtr ConvertToNative<K, V>([In] ref KeyValuePair<K, V> pair)
1538 IKeyValuePair<K, V> impl = new CLRIKeyValuePairImpl<K, V>(ref pair);
1539 return Marshal.GetComInterfaceForObject(impl, typeof(IKeyValuePair<K, V>));
1542 [SecurityCritical]
1543 internal static KeyValuePair<K, V> ConvertToManaged<K, V>(IntPtr pInsp)
1545 object obj = InterfaceMarshaler.ConvertToManagedWithoutUnboxing(pInsp);
1547 IKeyValuePair<K, V> pair = (IKeyValuePair<K, V>)obj;
1548 return new KeyValuePair<K, V>(pair.Key, pair.Value);
1551 // Called from COMInterfaceMarshaler
1552 [SecurityCritical]
1553 internal static object ConvertToManagedBox<K, V>(IntPtr pInsp)
1555 return (object)ConvertToManaged<K, V>(pInsp);
1557 } // class KeyValuePairMarshaler
1559 #endif // FEATURE_COMINTEROP
1561 [StructLayout(LayoutKind.Sequential)]
1562 internal struct NativeVariant
1564 ushort vt;
1565 ushort wReserved1;
1566 ushort wReserved2;
1567 ushort wReserved3;
1569 // The union portion of the structure contains at least one 64-bit type that on some 32-bit platforms
1570 // (notably ARM) requires 64-bit alignment. So on 32-bit platforms we'll actually size the variant
1571 // portion of the struct with an Int64 so the type loader notices this requirement (a no-op on x86,
1572 // but on ARM it will allow us to correctly determine the layout of native argument lists containing
1573 // VARIANTs). Note that the field names here don't matter: none of the code refers to these fields,
1574 // the structure just exists to provide size information to the IL marshaler.
1575 #if WIN64
1576 IntPtr data1;
1577 IntPtr data2;
1578 #else
1579 Int64 data1;
1580 #endif
1581 } // struct NativeVariant
1583 #if !WIN64 && !FEATURE_CORECLR
1584 // Structure filled by IL stubs if copy constructor(s) and destructor(s) need to be called
1585 // on value types pushed on the stack. The structure is stored in s_copyCtorStubDesc by
1586 // SetCopyCtorCookieChain and fetched by CopyCtorCallStubWorker. Must be stack-allocated.
1587 [StructLayout(LayoutKind.Sequential)]
1588 unsafe internal struct CopyCtorStubCookie
1590 public void SetData(IntPtr srcInstancePtr, uint dstStackOffset, IntPtr ctorPtr, IntPtr dtorPtr)
1592 m_srcInstancePtr = srcInstancePtr;
1593 m_dstStackOffset = dstStackOffset;
1594 m_ctorPtr = ctorPtr;
1595 m_dtorPtr = dtorPtr;
1598 public void SetNext(IntPtr pNext)
1600 m_pNext = pNext;
1603 public IntPtr m_srcInstancePtr; // pointer to the source instance
1604 public uint m_dstStackOffset; // offset from the start of stack arguments of the pushed 'this' instance
1606 public IntPtr m_ctorPtr; // fnptr to the managed copy constructor, result of ldftn
1607 public IntPtr m_dtorPtr; // fnptr to the managed destructor, result of ldftn
1609 public IntPtr m_pNext; // pointer to next cookie in the chain or IntPtr.Zero
1610 } // struct CopyCtorStubCookie
1612 // Aggregates pointer to CopyCtorStubCookie and the target of the interop call.
1613 [StructLayout(LayoutKind.Sequential)]
1614 unsafe internal struct CopyCtorStubDesc
1616 public IntPtr m_pCookie;
1617 public IntPtr m_pTarget;
1618 } // struct CopyCtorStubDes
1619 #endif // !WIN64 && !FEATURE_CORECLR
1621 // Aggregates SafeHandle and the "owned" bit which indicates whether the SafeHandle
1622 // has been successfully AddRef'ed. This allows us to do realiable cleanup (Release)
1623 // if and only if it is needed.
1624 [System.Security.SecurityCritical]
1625 internal sealed class CleanupWorkListElement
1627 public CleanupWorkListElement(SafeHandle handle)
1629 m_handle = handle;
1632 public SafeHandle m_handle;
1634 // This field is passed by-ref to SafeHandle.DangerousAddRef.
1635 // CleanupWorkList.Destroy ignores this element if m_owned is not set to true.
1636 public bool m_owned;
1637 } // class CleanupWorkListElement
1639 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1640 [System.Security.SecurityCritical]
1641 internal sealed class CleanupWorkList
1643 private List<CleanupWorkListElement> m_list = new List<CleanupWorkListElement>();
1645 public void Add(CleanupWorkListElement elem)
1647 BCLDebug.Assert(elem.m_owned == false, "m_owned is supposed to be false and set later by DangerousAddRef");
1648 m_list.Add(elem);
1651 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1652 public void Destroy()
1654 for (int i = m_list.Count - 1; i >= 0; i--)
1656 if (m_list[i].m_owned)
1657 StubHelpers.SafeHandleRelease(m_list[i].m_handle);
1660 } // class CleanupWorkList
1662 [System.Security.SecurityCritical] // auto-generated
1663 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1664 [SuppressUnmanagedCodeSecurityAttribute()]
1665 internal static class StubHelpers
1667 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1668 static internal extern bool IsQCall(IntPtr pMD);
1670 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1671 static internal extern void InitDeclaringType(IntPtr pMD);
1673 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1674 static internal extern IntPtr GetNDirectTarget(IntPtr pMD);
1676 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1677 static internal extern IntPtr GetDelegateTarget(Delegate pThis, ref IntPtr pStubArg);
1679 #if !WIN64 && !FEATURE_CORECLR
1680 // Written to by a managed stub helper, read by CopyCtorCallStubWorker in VM.
1681 [ThreadStatic]
1682 static CopyCtorStubDesc s_copyCtorStubDesc;
1684 static internal void SetCopyCtorCookieChain(IntPtr pStubArg, IntPtr pUnmngThis, int dwStubFlags, IntPtr pCookie)
1686 // we store both the cookie chain head and the target of the copy ctor stub to a thread
1687 // static field to be accessed by the copy ctor (see code:CopyCtorCallStubWorker)
1688 s_copyCtorStubDesc.m_pCookie = pCookie;
1689 s_copyCtorStubDesc.m_pTarget = GetFinalStubTarget(pStubArg, pUnmngThis, dwStubFlags);
1692 // Returns the final unmanaged stub target, ignores interceptors.
1693 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1694 static internal extern IntPtr GetFinalStubTarget(IntPtr pStubArg, IntPtr pUnmngThis, int dwStubFlags);
1695 #endif // !FEATURE_CORECLR && !WIN64
1697 #if !FEATURE_CORECLR
1698 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1699 static internal extern void DemandPermission(IntPtr pNMD);
1700 #endif // !FEATURE_CORECLR
1702 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1703 static internal extern void SetLastError();
1705 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1706 static internal extern void ThrowInteropParamException(int resID, int paramIdx);
1708 [System.Security.SecurityCritical]
1709 static internal IntPtr AddToCleanupList(ref CleanupWorkList pCleanupWorkList, SafeHandle handle)
1711 if (pCleanupWorkList == null)
1712 pCleanupWorkList = new CleanupWorkList();
1714 CleanupWorkListElement element = new CleanupWorkListElement(handle);
1715 pCleanupWorkList.Add(element);
1717 // element.m_owned will be true iff the AddRef succeeded
1718 return SafeHandleAddRef(handle, ref element.m_owned);
1721 [System.Security.SecurityCritical]
1722 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1723 static internal void DestroyCleanupList(ref CleanupWorkList pCleanupWorkList)
1725 if (pCleanupWorkList != null)
1727 pCleanupWorkList.Destroy();
1728 pCleanupWorkList = null;
1732 static internal Exception GetHRExceptionObject(int hr)
1734 Exception ex = InternalGetHRExceptionObject(hr);
1735 ex.InternalPreserveStackTrace();
1736 return ex;
1739 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1740 static internal extern Exception InternalGetHRExceptionObject(int hr);
1742 #if FEATURE_COMINTEROP
1743 static internal Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis)
1745 Exception ex = InternalGetCOMHRExceptionObject(hr, pCPCMD, pThis, false);
1746 ex.InternalPreserveStackTrace();
1747 return ex;
1750 static internal Exception GetCOMHRExceptionObject_WinRT(int hr, IntPtr pCPCMD, object pThis)
1752 Exception ex = InternalGetCOMHRExceptionObject(hr, pCPCMD, pThis, true);
1753 ex.InternalPreserveStackTrace();
1754 return ex;
1757 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1758 static internal extern Exception InternalGetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis, bool fForWinRT);
1760 #endif // FEATURE_COMINTEROP
1762 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1763 static internal extern IntPtr CreateCustomMarshalerHelper(IntPtr pMD, int paramToken, IntPtr hndManagedType);
1765 //-------------------------------------------------------
1766 // SafeHandle Helpers
1767 //-------------------------------------------------------
1769 // AddRefs the SH and returns the underlying unmanaged handle.
1770 [System.Security.SecurityCritical] // auto-generated
1771 static internal IntPtr SafeHandleAddRef(SafeHandle pHandle, ref bool success)
1773 if (pHandle == null)
1775 throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_SafeHandle"));
1777 Contract.EndContractBlock();
1779 pHandle.DangerousAddRef(ref success);
1781 return (success ? pHandle.DangerousGetHandle() : IntPtr.Zero);
1784 // Releases the SH (to be called from finally block).
1785 [System.Security.SecurityCritical] // auto-generated
1786 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1787 static internal void SafeHandleRelease(SafeHandle pHandle)
1789 if (pHandle == null)
1791 throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_SafeHandle"));
1793 Contract.EndContractBlock();
1797 pHandle.DangerousRelease();
1799 #if MDA_SUPPORTED
1800 catch (Exception ex)
1802 Mda.ReportErrorSafeHandleRelease(ex);
1804 #else // MDA_SUPPORTED
1805 catch (Exception)
1807 #endif // MDA_SUPPORTED
1810 #if FEATURE_COMINTEROP
1811 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1812 static internal extern IntPtr GetCOMIPFromRCW(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget, out bool pfNeedsRelease);
1814 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1815 static internal extern IntPtr GetCOMIPFromRCW_WinRT(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget);
1817 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1818 static internal extern IntPtr GetCOMIPFromRCW_WinRTSharedGeneric(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget);
1820 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1821 static internal extern IntPtr GetCOMIPFromRCW_WinRTDelegate(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget);
1823 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1824 static internal extern bool ShouldCallWinRTInterface(object objSrc, IntPtr pCPCMD);
1826 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1827 static internal extern Delegate GetTargetForAmbiguousVariantCall(object objSrc, IntPtr pMT, out bool fUseString);
1829 //-------------------------------------------------------
1830 // Helper for the MDA ----OnRCWCleanup
1831 //-------------------------------------------------------
1833 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1834 static internal extern void StubRegisterRCW(object pThis);
1836 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1837 static internal extern void StubUnregisterRCW(object pThis);
1839 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1840 static internal extern IntPtr GetDelegateInvokeMethod(Delegate pThis);
1842 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1843 [System.Security.SecurityCritical]
1844 static internal extern object GetWinRTFactoryObject(IntPtr pCPCMD);
1846 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1847 [System.Security.SecurityCritical]
1848 static internal extern IntPtr GetWinRTFactoryReturnValue(object pThis, IntPtr pCtorEntry);
1850 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1851 [System.Security.SecurityCritical]
1852 static internal extern IntPtr GetOuterInspectable(object pThis, IntPtr pCtorMD);
1854 #if MDA_SUPPORTED
1855 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1856 static internal extern Exception TriggerExceptionSwallowedMDA(Exception ex, IntPtr pManagedTarget);
1857 #endif // MDA_SUPPORTED
1859 #endif // FEATURE_COMINTEROP
1861 #if MDA_SUPPORTED
1862 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1863 static internal extern void CheckCollectedDelegateMDA(IntPtr pEntryThunk);
1864 #endif // MDA_SUPPORTED
1866 //-------------------------------------------------------
1867 // Profiler helpers
1868 //-------------------------------------------------------
1869 #if PROFILING_SUPPORTED
1870 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1871 static internal extern IntPtr ProfilerBeginTransitionCallback(IntPtr pSecretParam, IntPtr pThread, object pThis);
1873 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1874 static internal extern void ProfilerEndTransitionCallback(IntPtr pMD, IntPtr pThread);
1875 #endif // PROFILING_SUPPORTED
1877 //------------------------------------------------------
1878 // misc
1879 //------------------------------------------------------
1880 static internal void CheckStringLength(int length)
1882 CheckStringLength((uint)length);
1885 static internal void CheckStringLength(uint length)
1887 if (length > 0x7ffffff0)
1889 throw new MarshalDirectiveException(Environment.GetResourceString("Marshaler_StringTooLong"));
1893 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1894 static internal unsafe extern int strlen(sbyte* ptr);
1896 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1897 static internal extern void DecimalCanonicalizeInternal(ref Decimal dec);
1899 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1900 static internal unsafe extern void FmtClassUpdateNativeInternal(object obj, byte* pNative, ref CleanupWorkList pCleanupWorkList);
1901 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1902 static internal unsafe extern void FmtClassUpdateCLRInternal(object obj, byte* pNative);
1903 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1904 static internal unsafe extern void LayoutDestroyNativeInternal(byte* pNative, IntPtr pMT);
1905 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1906 static internal extern object AllocateInternal(IntPtr typeHandle);
1908 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1909 static internal extern void MarshalToUnmanagedVaListInternal(IntPtr va_list, uint vaListSize, IntPtr pArgIterator);
1911 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1912 static internal extern void MarshalToManagedVaListInternal(IntPtr va_list, IntPtr pArgIterator);
1914 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1915 static internal extern uint CalcVaListSize(IntPtr va_list);
1917 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1918 static internal extern void ValidateObject(object obj, IntPtr pMD, object pThis);
1920 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1921 static internal extern void LogPinnedArgument(IntPtr localDesc, IntPtr nativeArg);
1923 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1924 static internal extern void ValidateByref(IntPtr byref, IntPtr pMD, object pThis); // the byref is pinned so we can safely "cast" it to IntPtr
1926 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1927 static internal extern IntPtr GetStubContext();
1929 #if WIN64
1930 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1931 static internal extern IntPtr GetStubContextAddr();
1932 #endif // WIN64
1934 #if MDA_SUPPORTED
1935 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1936 static internal extern void TriggerGCForMDA();
1937 #endif // MDA_SUPPORTED
1939 #if FEATURE_ARRAYSTUB_AS_IL
1940 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1941 internal static extern void ArrayTypeCheck(object o, Object[] arr);
1942 #endif
1944 #if FEATURE_STUBS_AS_IL
1945 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1946 internal static extern void MulticastDebuggerTraceHelper(object o, Int32 count);
1947 #endif
1948 } // class StubHelpers