909502dc4f11e7d735499051b9b394e771b90244
[mono.git] / mcs / class / referencesource / mscorlib / system / stubhelpers.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6
7 namespace  System.StubHelpers {
8
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;
21
22     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
23     internal static class AnsiCharMarshaler
24     {
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)
29         {
30             byte[] buffer = new byte[(str.Length + 1) * Marshal.SystemMaxDBCSCharSize];
31             fixed (byte *bufferPtr = buffer)
32             {
33                 cbLength = str.ConvertToAnsi(bufferPtr, buffer.Length, fBestFit, fThrowOnUnmappableChar);
34             }
35             return buffer;
36         }
37
38         [System.Security.SecurityCritical]
39         unsafe static internal byte ConvertToNative(char managedChar, bool fBestFit, bool fThrowOnUnmappableChar)
40         {
41             int cbAllocLength = (1 + 1) * Marshal.SystemMaxDBCSCharSize;
42             byte* bufferPtr = stackalloc byte[cbAllocLength];
43
44             int cbLength = managedChar.ToString().ConvertToAnsi(bufferPtr, cbAllocLength, fBestFit, fThrowOnUnmappableChar);
45
46             BCLDebug.Assert(cbLength > 0, "Zero bytes returned from DoAnsiConversion in AnsiCharMarshaler.ConvertToNative");
47             return bufferPtr[0];
48         }
49
50         static internal char ConvertToManaged(byte nativeChar)
51         {
52             byte[] bytes = new byte[1] { nativeChar };
53             string str = Encoding.Default.GetString(bytes);
54             return str[0];
55         }
56     }  // class AnsiCharMarshaler
57
58     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
59     internal static class CSTRMarshaler
60     {
61         [System.Security.SecurityCritical]  // auto-generated
62         static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
63         {
64             if (null == strManaged)
65             {
66                 return IntPtr.Zero;
67             }
68
69             StubHelpers.CheckStringLength(strManaged.Length);
70
71             int nb;
72             byte *pbNativeBuffer = (byte *)pNativeBuffer;
73
74             if (pbNativeBuffer != null || Marshal.SystemMaxDBCSCharSize == 1)
75             {
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.
78
79                 // + 1 for the null character from the user
80                 nb = (strManaged.Length + 1) * Marshal.SystemMaxDBCSCharSize;
81
82                 // Use the pre-allocated buffer (allocated by localloc IL instruction) if not NULL, 
83                 // otherwise fallback to AllocCoTaskMem
84                 if (pbNativeBuffer == null)
85                 {
86                     // + 1 for the null character we put in
87                     pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 1);
88                 }
89
90                 nb = strManaged.ConvertToAnsi(pbNativeBuffer, nb + 1, 0 != (flags & 0xFF), 0 != (flags >> 8));
91             }
92             else
93             {
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.
98
99                 byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb);
100
101                 // + 1 for the null character from the user.  + 1 for the null character we put in.
102                 pbNativeBuffer = (byte*)Marshal.AllocCoTaskMem(nb + 2);
103
104                 Buffer.Memcpy(pbNativeBuffer, 0, bytes, 0, nb);
105             }
106
107             pbNativeBuffer[nb]     = 0x00;
108             pbNativeBuffer[nb + 1] = 0x00;
109
110             return (IntPtr)pbNativeBuffer;
111         }  
112
113         [System.Security.SecurityCritical]  // auto-generated
114         static internal unsafe string ConvertToManaged(IntPtr cstr)
115         {
116             if (IntPtr.Zero == cstr)
117                 return null;
118             else
119                 return new String((sbyte*)cstr);
120         }
121
122         [System.Security.SecurityCritical]  // auto-generated
123         static internal void ClearNative(IntPtr pNative)
124         {
125             Win32Native.CoTaskMemFree(pNative);
126         }
127     }  // class CSTRMarshaler
128
129     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
130     internal static class BSTRMarshaler
131     {
132         [System.Security.SecurityCritical]  // auto-generated
133         static internal unsafe IntPtr ConvertToNative(string strManaged, IntPtr pNativeBuffer)
134         {
135             if (null == strManaged)
136             {
137                 return IntPtr.Zero;
138             }
139             else
140             {
141                 StubHelpers.CheckStringLength(strManaged.Length);
142
143                 byte trailByte;
144                 bool hasTrailByte = strManaged.TryGetTrailByte(out trailByte);
145
146                 uint lengthInBytes = (uint)strManaged.Length * 2;
147
148                 if (hasTrailByte)
149                 {
150                     // this is an odd-sized string with a trailing byte stored in its sync block
151                     lengthInBytes++;
152                 }
153
154                 byte *ptrToFirstChar;
155
156                 if (pNativeBuffer != IntPtr.Zero)
157                 {
158                     // If caller provided a buffer, construct the BSTR manually. The size
159                     // of the buffer must be at least (lengthInBytes + 6) bytes.
160 #if _DEBUG
161                     uint length = *((uint *)pNativeBuffer.ToPointer());
162                     BCLDebug.Assert(length >= lengthInBytes + 6, "BSTR localloc'ed buffer is too small");
163 #endif // _DEBUG
164
165                     // set length
166                     *((uint *)pNativeBuffer.ToPointer()) = lengthInBytes;
167
168                     ptrToFirstChar = (byte *)pNativeBuffer.ToPointer() + 4;
169                 }
170                 else
171                 {
172                     // If not provided, allocate the buffer using SysAllocStringByteLen so
173                     // that odd-sized strings will be handled as well.
174                     ptrToFirstChar = (byte *)Win32Native.SysAllocStringByteLen(null, lengthInBytes).ToPointer();
175                 }
176
177                 // copy characters from the managed string
178                 fixed (char* ch = strManaged)
179                 {
180                     Buffer.Memcpy(
181                         ptrToFirstChar,
182                         (byte *)ch,
183                         (strManaged.Length + 1) * 2);
184                 }
185
186                 // copy the trail byte if present
187                 if (hasTrailByte)
188                 {
189                     ptrToFirstChar[lengthInBytes - 1] = trailByte;
190                 }
191
192                 // return ptr to first character
193                 return (IntPtr)ptrToFirstChar;
194             }
195         }
196
197         [System.Security.SecurityCritical]  // auto-generated
198         static internal unsafe string ConvertToManaged(IntPtr bstr)
199         {
200             if (IntPtr.Zero == bstr)
201             {
202                 return null;
203             }
204             else
205             {
206                 uint length = Win32Native.SysStringByteLen(bstr);
207
208                 // Intentionally checking the number of bytes not characters to match the behavior
209                 // of ML marshalers. This prevents roundtripping of very large strings as the check
210                 // in the managed->native direction is done on String length but considering that
211                 // it's completely moot on 32-bit and not expected to be important on 64-bit either,
212                 // the ability to catch random garbage in the BSTR's length field outweighs this
213                 // restriction. If an ordinary null-terminated string is passed instead of a BSTR,
214                 // chances are that the length field - possibly being unallocated memory - contains
215                 // a heap fill pattern that will have the highest bit set, caught by the check.
216                 StubHelpers.CheckStringLength(length);
217
218                 string ret;
219                 if (length == 1)
220                 {
221                     // In the empty string case, we need to use FastAllocateString rather than the
222                     // String .ctor, since newing up a 0 sized string will always return String.Emtpy.
223                     // When we marshal that out as a bstr, it can wind up getting modified which
224                     // corrupts String.Empty.
225                     ret = String.FastAllocateString(0);
226                 }
227                 else
228                 {
229                     ret = new String((char*)bstr, 0, (int)(length / 2));
230                 }
231
232                 if ((length & 1) == 1)
233                 {
234                     // odd-sized strings need to have the trailing byte saved in their sync block
235                     ret.SetTrailByte(((byte *)bstr.ToPointer())[length - 1]);
236                 }
237
238                 return ret;
239             }
240         }
241
242         [System.Security.SecurityCritical]  // auto-generated
243         static internal void ClearNative(IntPtr pNative)
244         {
245             if (IntPtr.Zero != pNative)
246             {
247                 Win32Native.SysFreeString(pNative);
248             }
249         }
250     }  // class BSTRMarshaler
251
252     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
253     internal static class VBByValStrMarshaler
254     {
255         [System.Security.SecurityCritical]  // auto-generated
256         static internal unsafe IntPtr ConvertToNative(string strManaged, bool fBestFit, bool fThrowOnUnmappableChar, ref int cch)
257         {
258             if (null == strManaged)
259             {
260                 return IntPtr.Zero;
261             }
262
263             byte* pNative;
264             
265             cch = strManaged.Length;
266
267             StubHelpers.CheckStringLength(cch);
268
269             // length field at negative offset + (# of characters incl. the terminator) * max ANSI char size
270             int nbytes = sizeof(uint) + ((cch + 1) * Marshal.SystemMaxDBCSCharSize);
271
272             pNative = (byte*)Marshal.AllocCoTaskMem(nbytes);
273             int* pLength = (int*)pNative;
274             
275             pNative = pNative + sizeof(uint);
276
277             if (0 == cch)
278             {
279                 *pNative = 0;
280                 *pLength = 0;
281             }
282             else
283             {
284                 int nbytesused;
285                 byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, fBestFit, fThrowOnUnmappableChar, out nbytesused);
286
287                 BCLDebug.Assert(nbytesused < nbytes, "Insufficient buffer allocated in VBByValStrMarshaler.ConvertToNative");
288                 Buffer.Memcpy(pNative, 0, bytes, 0, nbytesused);
289
290                 pNative[nbytesused] = 0;
291                 *pLength = nbytesused;
292             }
293
294             return new IntPtr(pNative);
295         }
296
297         [System.Security.SecurityCritical]  // auto-generated
298         static internal unsafe string ConvertToManaged(IntPtr pNative, int cch)
299         {
300             if (IntPtr.Zero == pNative)
301             {
302                 return null;
303             }
304
305             return new String((sbyte*)pNative, 0, cch);
306         }
307         
308         [System.Security.SecurityCritical]  // auto-generated
309         static internal unsafe void ClearNative(IntPtr pNative)
310         {
311             if (IntPtr.Zero != pNative)
312             {
313                 Win32Native.CoTaskMemFree((IntPtr)(((long)pNative) - sizeof(uint)));
314             }
315         }
316     }  // class VBByValStrMarshaler
317
318     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
319     internal static class AnsiBSTRMarshaler
320     {
321         [System.Security.SecurityCritical]  // auto-generated
322         static internal unsafe IntPtr ConvertToNative(int flags, string strManaged)
323         {
324             if (null == strManaged)
325             {
326                 return IntPtr.Zero;
327             }
328
329             int length = strManaged.Length;
330
331             StubHelpers.CheckStringLength(length);
332
333             byte[]  bytes = null;
334             int     nb = 0;
335
336             if (length > 0)
337             {
338                 bytes = AnsiCharMarshaler.DoAnsiConversion(strManaged, 0 != (flags & 0xFF), 0 != (flags >> 8), out nb);
339             }
340
341             return Win32Native.SysAllocStringByteLen(bytes, (uint)nb);
342         }
343
344         [System.Security.SecurityCritical]  // auto-generated
345         static internal unsafe string ConvertToManaged(IntPtr bstr)
346         {
347             if (IntPtr.Zero == bstr)
348             {
349                 return null;
350             }
351             else
352             {
353                 // We intentionally ignore the length field of the BSTR for back compat reasons.
354                 // Unfortunately VB.NET uses Ansi BSTR marshaling when a string is passed ByRef
355                 // and we cannot afford to break this common scenario.
356                 return new String((sbyte*)bstr);
357             }
358         }
359
360         [System.Security.SecurityCritical]  // auto-generated
361         static internal unsafe void ClearNative(IntPtr pNative)
362         {
363             if (IntPtr.Zero != pNative)
364             {
365                 Win32Native.SysFreeString(pNative);
366             }
367         }
368     }  // class AnsiBSTRMarshaler
369
370     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
371     internal static class WSTRBufferMarshaler
372     {
373         static internal IntPtr ConvertToNative(string strManaged)
374         {
375             Contract.Assert(false, "NYI");
376             return IntPtr.Zero;
377         }
378
379         static internal unsafe string ConvertToManaged(IntPtr bstr)
380         {
381             Contract.Assert(false, "NYI");
382             return null;
383         }
384
385         static internal void ClearNative(IntPtr pNative)
386         {
387             Contract.Assert(false, "NYI");
388         }
389     }  // class WSTRBufferMarshaler
390
391
392 #if FEATURE_COMINTEROP
393
394
395     [StructLayout(LayoutKind.Sequential)]
396     internal struct DateTimeNative
397     {
398         public Int64 UniversalTime;
399     };
400
401     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
402     internal static class DateTimeOffsetMarshaler {
403
404         // Numer of ticks counted between 0001-01-01, 00:00:00 and 1601-01-01, 00:00:00.
405         // You can get this through:  (new DateTimeOffset(1601, 1, 1, 0, 0, 1, TimeSpan.Zero)).Ticks;
406         private const Int64 ManagedUtcTicksAtNativeZero = 504911232000000000;
407
408         [SecurityCritical]
409         internal static void ConvertToNative(ref DateTimeOffset managedDTO, out DateTimeNative dateTime) {
410
411             Int64 managedUtcTicks = managedDTO.UtcTicks;
412             dateTime.UniversalTime = managedUtcTicks - ManagedUtcTicksAtNativeZero;
413         }
414
415         [SecurityCritical]
416         internal static void ConvertToManaged(out DateTimeOffset managedLocalDTO, ref DateTimeNative nativeTicks) {
417
418             Int64 managedUtcTicks = ManagedUtcTicksAtNativeZero + nativeTicks.UniversalTime;
419             DateTimeOffset managedUtcDTO = new DateTimeOffset(managedUtcTicks, TimeSpan.Zero);
420             
421             // Some Utc times cannot be represented in local time in certain timezones. E.g. 0001-01-01 12:00:00 AM cannot 
422             // be represented in any timezones with a negative offset from Utc. We throw an ArgumentException in that case.
423             managedLocalDTO = managedUtcDTO.ToLocalTime(true);
424         }
425     }  // class DateTimeOffsetMarshaler
426
427 #endif  // FEATURE_COMINTEROP
428
429
430 #if FEATURE_COMINTEROP
431     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
432     internal static class HStringMarshaler
433     {
434         // Slow-path, which requires making a copy of the managed string into the resulting HSTRING
435         [SecurityCritical]
436         internal static unsafe IntPtr ConvertToNative(string managed)
437         {
438             if (!Environment.IsWinRTSupported)
439                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
440             if (managed == null)
441                 throw new ArgumentNullException(); // We don't have enough information to get the argument name just yet - that support will be coming in M3
442
443             IntPtr hstring;
444             int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString(managed, managed.Length, &hstring);
445             Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
446             return hstring;
447         }
448
449         // Fast-path, which creates a reference over a pinned managed string.  This may only be used if the
450         // pinned string and HSTRING_HEADER will outlive the HSTRING produced (for instance, as an in parameter).
451         //
452         // Note that the managed string input to this method MUST be pinned, and stay pinned for the lifetime of
453         // the returned HSTRING object.  If the string is not pinned, or becomes unpinned before the HSTRING's
454         // lifetime ends, the HSTRING instance will be corrupted.
455         [SecurityCritical]
456         internal static unsafe IntPtr ConvertToNativeReference(string managed,
457                                                                [Out] HSTRING_HEADER *hstringHeader)
458         {
459             if (!Environment.IsWinRTSupported)
460                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
461             if (managed == null)
462                 throw new ArgumentNullException();  // We don't have enough information to get the argument name just yet - that support will be coming in M3
463
464             // The string must also be pinned by the caller to ConvertToNativeReference, which also owns
465             // the HSTRING_HEADER.
466             fixed (char *pManaged = managed)
467             {
468                 IntPtr hstring;
469                 int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateStringReference(pManaged, managed.Length, hstringHeader, &hstring);
470                 Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
471                 return hstring;
472             }
473         }
474
475         [SecurityCritical]
476         internal static string ConvertToManaged(IntPtr hstring)
477         {
478             if (!Environment.IsWinRTSupported)
479             {
480                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
481             }
482
483             return WindowsRuntimeMarshal.HStringToString(hstring);
484         }
485
486         [SecurityCritical]
487         internal static void ClearNative(IntPtr hstring)
488         {
489             Contract.Assert(Environment.IsWinRTSupported);
490
491             if (hstring != IntPtr.Zero)
492             {
493                 System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString(hstring);
494             }
495         }
496     }  // class HStringMarshaler
497
498     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
499     internal static class ObjectMarshaler
500     {
501         [MethodImplAttribute(MethodImplOptions.InternalCall)]
502         static internal extern void ConvertToNative(object objSrc, IntPtr pDstVariant);
503
504         [MethodImplAttribute(MethodImplOptions.InternalCall)]
505         static internal extern object ConvertToManaged(IntPtr pSrcVariant);
506
507         [MethodImplAttribute(MethodImplOptions.InternalCall)]
508         static internal extern void ClearNative(IntPtr pVariant);
509     }  // class ObjectMarshaler
510
511 #endif // FEATURE_COMINTEROP
512
513     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
514     internal static class ValueClassMarshaler
515     {
516         [SecurityCritical]
517         [MethodImplAttribute(MethodImplOptions.InternalCall)]
518         static internal extern void ConvertToNative(IntPtr dst, IntPtr src, IntPtr pMT, ref CleanupWorkList pCleanupWorkList);
519
520         [MethodImplAttribute(MethodImplOptions.InternalCall)]
521         static internal extern void ConvertToManaged(IntPtr dst, IntPtr src, IntPtr pMT);
522
523         [MethodImplAttribute(MethodImplOptions.InternalCall)]
524         static internal extern void ClearNative(IntPtr dst, IntPtr pMT);
525     }  // class ValueClassMarshaler
526
527     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
528     internal static class DateMarshaler
529     {
530         [MethodImplAttribute(MethodImplOptions.InternalCall)]
531         static internal extern double ConvertToNative(DateTime managedDate);
532
533         // The return type is really DateTime but we use long to avoid the pain associated with returning structures.
534         [MethodImplAttribute(MethodImplOptions.InternalCall)]
535         static internal extern long ConvertToManaged(double nativeDate);
536     }  // class DateMarshaler
537
538 #if FEATURE_COMINTEROP
539     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
540     [FriendAccessAllowed]
541     internal static class InterfaceMarshaler
542     {
543         [MethodImplAttribute(MethodImplOptions.InternalCall)]
544         static internal extern IntPtr ConvertToNative(object objSrc, IntPtr itfMT, IntPtr classMT, int flags);
545
546         [MethodImplAttribute(MethodImplOptions.InternalCall)]
547         static internal extern object ConvertToManaged(IntPtr pUnk, IntPtr itfMT, IntPtr classMT, int flags);
548
549         [SecurityCritical]
550         [DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
551         static internal extern void ClearNative(IntPtr pUnk);
552
553         [FriendAccessAllowed]
554         [MethodImplAttribute(MethodImplOptions.InternalCall)]
555         static internal extern object ConvertToManagedWithoutUnboxing(IntPtr pNative);
556     }  // class InterfaceMarshaler
557 #endif // FEATURE_COMINTEROP
558
559 #if FEATURE_COMINTEROP
560     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
561     internal static class UriMarshaler
562     {
563         [MethodImplAttribute(MethodImplOptions.InternalCall)]
564         static internal extern string GetRawUriFromNative(IntPtr pUri);
565
566         [MethodImplAttribute(MethodImplOptions.InternalCall)]
567         [System.Security.SecurityCritical]
568         static unsafe internal extern IntPtr CreateNativeUriInstanceHelper(char* rawUri, int strLen);
569       
570     [System.Security.SecurityCritical]
571         static unsafe internal IntPtr CreateNativeUriInstance(string rawUri)
572         {
573             fixed(char* pManaged = rawUri)
574             {
575                 return CreateNativeUriInstanceHelper(pManaged, rawUri.Length);
576             }
577         }
578
579     }  // class InterfaceMarshaler
580
581     [FriendAccessAllowed]
582     internal static class EventArgsMarshaler
583     {
584         [SecurityCritical]
585         [FriendAccessAllowed]
586         static internal IntPtr CreateNativeNCCEventArgsInstance(int action, object newItems, object oldItems, int newIndex, int oldIndex)
587         {
588             IntPtr newItemsIP = IntPtr.Zero;
589             IntPtr oldItemsIP = IntPtr.Zero;
590
591             RuntimeHelpers.PrepareConstrainedRegions();
592             try
593             {
594                 if (newItems != null)
595                     newItemsIP = Marshal.GetComInterfaceForObject(newItems, typeof(IBindableVector));
596                 if (oldItems != null)
597                     oldItemsIP = Marshal.GetComInterfaceForObject(oldItems, typeof(IBindableVector));
598
599                 return CreateNativeNCCEventArgsInstanceHelper(action, newItemsIP, oldItemsIP, newIndex, oldIndex);
600             }
601             finally
602             {
603                 if (!oldItemsIP.IsNull())
604                     Marshal.Release(oldItemsIP);
605                 if (!newItemsIP.IsNull())
606                     Marshal.Release(newItemsIP);
607             }
608         }
609
610         [SecurityCritical]
611         [FriendAccessAllowed]
612         [DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
613         static extern internal IntPtr CreateNativePCEventArgsInstance([MarshalAs(UnmanagedType.HString)]string name);
614
615         [SecurityCritical]
616         [DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
617         static extern internal IntPtr CreateNativeNCCEventArgsInstanceHelper(int action, IntPtr newItem, IntPtr oldItem, int newIndex, int oldIndex);
618     }
619 #endif // FEATURE_COMINTEROP
620
621     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
622     internal static class MngdNativeArrayMarshaler
623     {
624         [MethodImplAttribute(MethodImplOptions.InternalCall)]
625         static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags);
626         
627         [MethodImplAttribute(MethodImplOptions.InternalCall)]
628         static internal extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
629
630         [MethodImplAttribute(MethodImplOptions.InternalCall)]
631         static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
632
633         [MethodImplAttribute(MethodImplOptions.InternalCall)]
634         static internal extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome,
635                                                           int cElements);
636
637         [MethodImplAttribute(MethodImplOptions.InternalCall)]
638         static internal extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
639
640         [MethodImplAttribute(MethodImplOptions.InternalCall)]
641         static internal extern void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
642         
643         [MethodImplAttribute(MethodImplOptions.InternalCall)]
644         static internal extern void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
645     }  // class MngdNativeArrayMarshaler
646
647 #if FEATURE_COMINTEROP
648     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
649     internal static class MngdSafeArrayMarshaler
650     {
651         [MethodImplAttribute(MethodImplOptions.InternalCall)]
652         static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int iRank, int dwFlags);
653         
654         [MethodImplAttribute(MethodImplOptions.InternalCall)]
655         static internal extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
656
657         [MethodImplAttribute(MethodImplOptions.InternalCall)]
658         static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, object pOriginalManaged);
659
660         [MethodImplAttribute(MethodImplOptions.InternalCall)]
661         static internal extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
662
663         [MethodImplAttribute(MethodImplOptions.InternalCall)]
664         static internal extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
665
666         [MethodImplAttribute(MethodImplOptions.InternalCall)]
667         static internal extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
668     }  // class MngdSafeArrayMarshaler
669
670     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
671     internal static class MngdHiddenLengthArrayMarshaler
672     {
673         [SecurityCritical]
674         [MethodImplAttribute(MethodImplOptions.InternalCall)]
675         static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, IntPtr cbElementSize, ushort vt);
676         
677         [SecurityCritical]
678         [MethodImplAttribute(MethodImplOptions.InternalCall)]
679         internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
680
681         [SecurityCritical]
682         [MethodImplAttribute(MethodImplOptions.InternalCall)]
683         internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
684
685         [SecurityCritical]
686         internal static unsafe void ConvertContentsToNative_DateTime(ref DateTimeOffset[] managedArray, IntPtr pNativeHome)
687         {
688             if (managedArray != null)
689             {
690                 DateTimeNative *nativeBuffer = *(DateTimeNative **)pNativeHome;
691                 for (int i = 0; i < managedArray.Length; i++)
692                 {
693                     DateTimeOffsetMarshaler.ConvertToNative(ref managedArray[i], out nativeBuffer[i]);
694                 }
695             }
696         }
697
698         [SecurityCritical]
699         internal static unsafe void ConvertContentsToNative_Type(ref System.Type[] managedArray, IntPtr pNativeHome)
700         {
701             if (managedArray != null)
702             {
703                 TypeNameNative *nativeBuffer = *(TypeNameNative **)pNativeHome;
704                 for (int i = 0; i < managedArray.Length; i++)
705                 {
706                     SystemTypeMarshaler.ConvertToNative(managedArray[i], &nativeBuffer[i]);
707                 }
708             }
709         }
710
711         [SecurityCritical]
712         internal static unsafe void ConvertContentsToNative_Exception(ref Exception[] managedArray, IntPtr pNativeHome)
713         {
714             if (managedArray != null)
715             {
716                 Int32 *nativeBuffer = *(Int32 **)pNativeHome;
717                 for (int i = 0; i < managedArray.Length; i++)
718                 {
719                     nativeBuffer[i] = HResultExceptionMarshaler.ConvertToNative(managedArray[i]);
720                 }
721             }
722         }
723
724         [SecurityCritical]
725         internal static unsafe void ConvertContentsToNative_Nullable<T>(ref Nullable<T>[] managedArray, IntPtr pNativeHome)
726             where T : struct
727         {
728             if (managedArray != null)
729             {
730                 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
731                 for (int i = 0; i < managedArray.Length; i++)
732                 {
733                     nativeBuffer[i] = NullableMarshaler.ConvertToNative<T>(ref managedArray[i]);
734                 }
735             }
736         }
737
738         [SecurityCritical]
739         internal static unsafe void ConvertContentsToNative_KeyValuePair<K, V>(ref KeyValuePair<K, V>[] managedArray, IntPtr pNativeHome)
740         {
741             if (managedArray != null)
742             {
743                 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
744                 for (int i = 0; i < managedArray.Length; i++)
745                 {
746                     nativeBuffer[i] = KeyValuePairMarshaler.ConvertToNative<K, V>(ref managedArray[i]);
747                 }
748             }
749         }
750
751         [SecurityCritical]
752         [MethodImplAttribute(MethodImplOptions.InternalCall)]
753         internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, int elementCount);
754
755         [SecurityCritical]
756         [MethodImplAttribute(MethodImplOptions.InternalCall)]
757         internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
758
759         [SecurityCritical]
760         internal static unsafe void ConvertContentsToManaged_DateTime(ref DateTimeOffset[] managedArray, IntPtr pNativeHome)
761         {
762             if (managedArray != null)
763             {
764                 DateTimeNative *nativeBuffer = *(DateTimeNative **)pNativeHome;
765                 for (int i = 0; i < managedArray.Length; i++)
766                 {
767                     DateTimeOffsetMarshaler.ConvertToManaged(out managedArray[i], ref nativeBuffer[i]);
768                 }
769             }
770         }
771
772         [SecurityCritical]
773         internal static unsafe void ConvertContentsToManaged_Type(ref System.Type[] managedArray, IntPtr pNativeHome)
774         {
775             if (managedArray != null)
776             {
777                 TypeNameNative *nativeBuffer = *(TypeNameNative **)pNativeHome;
778                 for (int i = 0; i < managedArray.Length; i++)
779                 {
780                     SystemTypeMarshaler.ConvertToManaged(&nativeBuffer[i], ref managedArray[i]);
781                 }
782             }
783         }
784
785         [SecurityCritical]
786         internal static unsafe void ConvertContentsToManaged_Exception(ref Exception[] managedArray, IntPtr pNativeHome)
787         {
788             if (managedArray != null)
789             {
790                 Int32 *nativeBuffer = *(Int32 **)pNativeHome;
791                 for (int i = 0; i < managedArray.Length; i++)
792                 {
793                     managedArray[i] = HResultExceptionMarshaler.ConvertToManaged(nativeBuffer[i]);
794                 }
795             }
796         }
797
798         [SecurityCritical]
799         internal static unsafe void ConvertContentsToManaged_Nullable<T>(ref Nullable<T>[] managedArray, IntPtr pNativeHome)
800             where T : struct
801         {
802             if (managedArray != null)
803             {
804                 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
805                 for (int i = 0; i < managedArray.Length; i++)
806                 {
807                     managedArray[i] = NullableMarshaler.ConvertToManaged<T>(nativeBuffer[i]);
808                 }
809             }
810         }
811
812         [SecurityCritical]
813         internal static unsafe void ConvertContentsToManaged_KeyValuePair<K, V>(ref KeyValuePair<K, V>[] managedArray, IntPtr pNativeHome)
814         {
815             if (managedArray != null)
816             {
817                 IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
818                 for (int i = 0; i < managedArray.Length; i++)
819                 {
820                     managedArray[i] = KeyValuePairMarshaler.ConvertToManaged<K, V>(nativeBuffer[i]);
821                 }
822             }
823         }
824
825         [SecurityCritical]
826         [MethodImplAttribute(MethodImplOptions.InternalCall)]
827         internal static extern void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
828
829         [SecurityCritical]
830         internal static unsafe void ClearNativeContents_Type(IntPtr pNativeHome, int cElements)
831         {
832             Contract.Assert(Environment.IsWinRTSupported);
833
834             TypeNameNative *pNativeTypeArray = *(TypeNameNative **)pNativeHome;
835             if (pNativeTypeArray != null)
836             {
837                 for (int i = 0; i < cElements; ++i)
838                 {
839                     SystemTypeMarshaler.ClearNative(pNativeTypeArray);
840                     pNativeTypeArray++;
841                 }
842             }
843         }
844     }  // class MngdHiddenLengthArrayMarshaler
845
846 #endif // FEATURE_COMINTEROP
847
848     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
849     internal static class MngdRefCustomMarshaler
850     {
851         [MethodImplAttribute(MethodImplOptions.InternalCall)]
852         static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pCMHelper);
853         
854         [MethodImplAttribute(MethodImplOptions.InternalCall)]
855         static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
856
857         [MethodImplAttribute(MethodImplOptions.InternalCall)]
858         static internal extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
859
860         [MethodImplAttribute(MethodImplOptions.InternalCall)]
861         static internal extern void ClearNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
862
863         [MethodImplAttribute(MethodImplOptions.InternalCall)]
864         static internal extern void ClearManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
865     }  // class MngdRefCustomMarshaler
866
867     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
868     [System.Security.SecurityCritical]
869     internal struct AsAnyMarshaler
870     {
871         private const ushort VTHACK_ANSICHAR = 253;
872         private const ushort VTHACK_WINBOOL  = 254;
873
874         private enum BackPropAction
875         {
876             None,
877             Array,
878             Layout,
879             StringBuilderAnsi,
880             StringBuilderUnicode
881         }
882
883         // Pointer to MngdNativeArrayMarshaler, ownership not assumed.
884         private IntPtr pvArrayMarshaler;
885
886         // Type of action to perform after the CLR-to-unmanaged call.
887         private BackPropAction backPropAction;
888
889         // The managed layout type for BackPropAction.Layout.
890         private Type layoutType;
891
892         // Cleanup list to be destroyed when clearing the native view (for layouts with SafeHandles).
893         private CleanupWorkList cleanupWorkList;
894
895         private static bool IsIn(int dwFlags)      { return ((dwFlags & 0x10000000) != 0); }
896         private static bool IsOut(int dwFlags)     { return ((dwFlags & 0x20000000) != 0); }
897         private static bool IsAnsi(int dwFlags)    { return ((dwFlags & 0x00FF0000) != 0); }
898         private static bool IsThrowOn(int dwFlags) { return ((dwFlags & 0x0000FF00) != 0); }
899         private static bool IsBestFit(int dwFlags) { return ((dwFlags & 0x000000FF) != 0); }
900
901         internal AsAnyMarshaler(IntPtr pvArrayMarshaler)
902         {
903             // we need this in case the value being marshaled turns out to be array
904             BCLDebug.Assert(pvArrayMarshaler != IntPtr.Zero, "pvArrayMarshaler must not be null");
905
906             this.pvArrayMarshaler = pvArrayMarshaler;
907             this.backPropAction = BackPropAction.None;
908             this.layoutType = null;
909             this.cleanupWorkList = null;
910         }
911
912         #region ConvertToNative helpers
913
914         [System.Security.SecurityCritical]
915         private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags)
916         {
917             Type elementType = pManagedHome.GetType().GetElementType();
918             VarEnum vt = VarEnum.VT_EMPTY;
919
920             switch (Type.GetTypeCode(elementType))
921             {
922                 case TypeCode.SByte:   vt = VarEnum.VT_I1;  break;
923                 case TypeCode.Byte:    vt = VarEnum.VT_UI1; break;
924                 case TypeCode.Int16:   vt = VarEnum.VT_I2;  break;
925                 case TypeCode.UInt16:  vt = VarEnum.VT_UI2; break;
926                 case TypeCode.Int32:   vt = VarEnum.VT_I4;  break;
927                 case TypeCode.UInt32:  vt = VarEnum.VT_UI4; break;
928                 case TypeCode.Int64:   vt = VarEnum.VT_I8;  break;
929                 case TypeCode.UInt64:  vt = VarEnum.VT_UI8; break;
930                 case TypeCode.Single:  vt = VarEnum.VT_R4;  break;
931                 case TypeCode.Double:  vt = VarEnum.VT_R8;  break;
932                 case TypeCode.Char:    vt = (IsAnsi(dwFlags) ? (VarEnum)VTHACK_ANSICHAR : VarEnum.VT_UI2); break;
933                 case TypeCode.Boolean: vt = (VarEnum)VTHACK_WINBOOL; break;
934
935                 case TypeCode.Object:
936                 {
937                     if (elementType == typeof(IntPtr))
938                     {
939                         vt = (IntPtr.Size == 4 ? VarEnum.VT_I4 : VarEnum.VT_I8);
940                     }
941                     else if (elementType == typeof(UIntPtr))
942                     {
943                         vt = (IntPtr.Size == 4 ? VarEnum.VT_UI4 : VarEnum.VT_UI8);
944                     }
945                     else goto default;
946                     break;
947                 }
948
949                 default:
950                     throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject"));
951             }
952
953             // marshal the object as C-style array (UnmanagedType.LPArray)
954             int dwArrayMarshalerFlags = (int)vt;
955             if (IsBestFit(dwFlags)) dwArrayMarshalerFlags |= (1 << 16);
956             if (IsThrowOn(dwFlags)) dwArrayMarshalerFlags |= (1 << 24);
957
958             MngdNativeArrayMarshaler.CreateMarshaler(
959                 pvArrayMarshaler,
960                 IntPtr.Zero,      // not needed as we marshal primitive VTs only
961                 dwArrayMarshalerFlags);
962
963             IntPtr pNativeHome;
964             IntPtr pNativeHomeAddr = new IntPtr(&pNativeHome);
965
966             MngdNativeArrayMarshaler.ConvertSpaceToNative(
967                 pvArrayMarshaler,
968                 ref pManagedHome,
969                 pNativeHomeAddr);
970
971             if (IsIn(dwFlags))
972             {
973                 MngdNativeArrayMarshaler.ConvertContentsToNative(
974                     pvArrayMarshaler,
975                     ref pManagedHome,
976                     pNativeHomeAddr);
977             }
978             if (IsOut(dwFlags))
979             {
980                 backPropAction = BackPropAction.Array;
981             }
982
983             return pNativeHome;
984         }
985
986         [System.Security.SecurityCritical]
987         private static IntPtr ConvertStringToNative(string pManagedHome, int dwFlags)
988         {
989             IntPtr pNativeHome;
990
991             // IsIn, IsOut are ignored for strings - they're always in-only
992             if (IsAnsi(dwFlags))
993             {
994                 // marshal the object as Ansi string (UnmanagedType.LPStr)
995                 pNativeHome = CSTRMarshaler.ConvertToNative(
996                     dwFlags & 0xFFFF, // (throw on unmappable char << 8 | best fit)
997                     pManagedHome,     //
998                     IntPtr.Zero);     // unmanaged buffer will be allocated
999             }
1000             else
1001             {
1002                 // marshal the object as Unicode string (UnmanagedType.LPWStr)
1003                 StubHelpers.CheckStringLength(pManagedHome.Length);
1004
1005                 int allocSize = (pManagedHome.Length + 1) * 2;
1006                 pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1007
1008                 String.InternalCopy(pManagedHome, pNativeHome, allocSize);
1009             }
1010
1011             return pNativeHome;
1012         }
1013
1014         [System.Security.SecurityCritical]
1015         private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags)
1016         {
1017             IntPtr pNativeHome;
1018
1019             // P/Invoke can be used to call Win32 apis that don't strictly follow CLR in/out semantics and thus may
1020             // leave garbage in the buffer in circumstances that we can't detect. To prevent us from crashing when
1021             // converting the contents back to managed, put a hidden NULL terminator past the end of the official buffer.
1022
1023             // Unmanaged layout:
1024             // +====================================+
1025             // | Extra hidden NULL                  |
1026             // +====================================+ \
1027             // |                                    | |
1028             // | [Converted] NULL-terminated string | |- buffer that the target may change
1029             // |                                    | |
1030             // +====================================+ / <-- native home
1031
1032             // Note that StringBuilder.Capacity is the number of characters NOT including any terminators.
1033
1034             if (IsAnsi(dwFlags))
1035             {
1036                 StubHelpers.CheckStringLength(pManagedHome.Capacity);
1037
1038                 // marshal the object as Ansi string (UnmanagedType.LPStr)
1039                 int allocSize = (pManagedHome.Capacity * Marshal.SystemMaxDBCSCharSize) + 4;
1040                 pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1041
1042                 byte* ptr = (byte*)pNativeHome;
1043                 *(ptr + allocSize - 3) = 0;
1044                 *(ptr + allocSize - 2) = 0;
1045                 *(ptr + allocSize - 1) = 0;
1046
1047                 if (IsIn(dwFlags))
1048                 {
1049                     int length;
1050
1051                     byte[] bytes = AnsiCharMarshaler.DoAnsiConversion(
1052                         pManagedHome.ToString(),
1053                         IsBestFit(dwFlags),
1054                         IsThrowOn(dwFlags),
1055                         out length);
1056
1057                     Buffer.Memcpy(
1058                         ptr,           // dst buffer
1059                         0,             // dts index
1060                         bytes,         // src array
1061                         0,             // src index
1062                         length);       // len
1063
1064                     // null-terminate the native string
1065                     *(ptr + length) = 0;
1066                 }
1067                 if (IsOut(dwFlags))
1068                 {
1069                     backPropAction = BackPropAction.StringBuilderAnsi;
1070                 }
1071             }
1072             else
1073             {
1074                 // marshal the object as Unicode string (UnmanagedType.LPWStr)
1075                 int allocSize = (pManagedHome.Capacity * 2) + 4;
1076                 pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1077
1078                 byte* ptr = (byte*)pNativeHome;
1079                 *(ptr + allocSize - 1) = 0;
1080                 *(ptr + allocSize - 2) = 0;
1081
1082                 if (IsIn(dwFlags))
1083                 {
1084                     int length = pManagedHome.Length * 2;
1085                     pManagedHome.InternalCopy(pNativeHome, length);
1086
1087                     // null-terminate the native string
1088                     *(ptr + length + 0) = 0;
1089                     *(ptr + length + 1) = 0;
1090                 }
1091                 if (IsOut(dwFlags))
1092                 {
1093                     backPropAction = BackPropAction.StringBuilderUnicode;
1094                 }
1095             }
1096
1097             return pNativeHome;
1098         }
1099
1100         [System.Security.SecurityCritical]
1101         private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags)
1102         {
1103             // Note that the following call will not throw exception if the type
1104             // of pManagedHome is not marshalable. That's intentional because we
1105             // want to maintain the original behavior where this was indicated
1106             // by TypeLoadException during the actual field marshaling.
1107             int allocSize = Marshal.SizeOfHelper(pManagedHome.GetType(), false);
1108             IntPtr pNativeHome = Marshal.AllocCoTaskMem(allocSize);
1109
1110             // marshal the object as class with layout (UnmanagedType.LPStruct)
1111             if (IsIn(dwFlags))
1112             {
1113                 StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte *)pNativeHome.ToPointer(), ref cleanupWorkList);
1114             }
1115             if (IsOut(dwFlags))
1116             {
1117                 backPropAction = BackPropAction.Layout;
1118             }
1119             layoutType = pManagedHome.GetType();
1120
1121             return pNativeHome;
1122         }
1123
1124         #endregion
1125
1126         [System.Security.SecurityCritical]
1127         internal IntPtr ConvertToNative(object pManagedHome, int dwFlags)
1128         {
1129             if (pManagedHome == null)
1130                 return IntPtr.Zero;
1131
1132             if (pManagedHome is ArrayWithOffset)
1133                 throw new ArgumentException(Environment.GetResourceString("Arg_MarshalAsAnyRestriction"));
1134
1135             IntPtr pNativeHome;
1136
1137             if (pManagedHome.GetType().IsArray)
1138             {
1139                 // array (LPArray)
1140                 pNativeHome = ConvertArrayToNative(pManagedHome, dwFlags);
1141             }
1142             else
1143             {
1144                 string strValue;
1145                 StringBuilder sbValue;
1146
1147                 if ((strValue = pManagedHome as string) != null)
1148                 {
1149                     // string (LPStr or LPWStr)
1150                     pNativeHome = ConvertStringToNative(strValue, dwFlags);
1151                 }
1152                 else if ((sbValue = pManagedHome as StringBuilder) != null)
1153                 {
1154                     // StringBuilder (LPStr or LPWStr)
1155                     pNativeHome = ConvertStringBuilderToNative(sbValue, dwFlags);
1156                 }
1157                 else if (pManagedHome.GetType().IsLayoutSequential || pManagedHome.GetType().IsExplicitLayout)
1158                 {
1159                     // layout (LPStruct)
1160                     pNativeHome = ConvertLayoutToNative(pManagedHome, dwFlags);
1161                 }
1162                 else
1163                 {
1164                     // this type is not supported for AsAny marshaling
1165                     throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject"));
1166                 }
1167             }
1168
1169             return pNativeHome;
1170         }
1171
1172         [System.Security.SecurityCritical]
1173         internal unsafe void ConvertToManaged(object pManagedHome, IntPtr pNativeHome)
1174         {
1175             switch (backPropAction)
1176             {
1177                 case BackPropAction.Array:
1178                 {
1179                     MngdNativeArrayMarshaler.ConvertContentsToManaged(
1180                         pvArrayMarshaler,
1181                         ref pManagedHome,
1182                         new IntPtr(&pNativeHome));
1183                     break;
1184                 }
1185
1186                 case BackPropAction.Layout:
1187                 {
1188                     StubHelpers.FmtClassUpdateCLRInternal(pManagedHome, (byte *)pNativeHome.ToPointer());
1189                     break;
1190                 }
1191
1192                 case BackPropAction.StringBuilderAnsi:
1193                 {
1194                     sbyte* ptr = (sbyte*)pNativeHome.ToPointer();
1195                     ((StringBuilder)pManagedHome).ReplaceBufferAnsiInternal(ptr, Win32Native.lstrlenA(pNativeHome));
1196                     break;
1197                 }
1198
1199                 case BackPropAction.StringBuilderUnicode:
1200                 {
1201                     char* ptr = (char*)pNativeHome.ToPointer();
1202                     ((StringBuilder)pManagedHome).ReplaceBufferInternal(ptr, Win32Native.lstrlenW(pNativeHome));
1203                     break;
1204                 }
1205
1206                 // nothing to do for BackPropAction.None
1207             }
1208         }
1209
1210         [System.Security.SecurityCritical]
1211         internal void ClearNative(IntPtr pNativeHome)
1212         {
1213             if (pNativeHome != IntPtr.Zero)
1214             {
1215                 if (layoutType != null)
1216                 {
1217                     // this must happen regardless of BackPropAction
1218                     Marshal.DestroyStructure(pNativeHome, layoutType);
1219                 }
1220                 Win32Native.CoTaskMemFree(pNativeHome);
1221             }
1222             StubHelpers.DestroyCleanupList(ref cleanupWorkList);
1223         }
1224     }  // struct AsAnyMarshaler
1225
1226 #if FEATURE_COMINTEROP
1227     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1228     internal static class NullableMarshaler
1229     {    
1230         [SecurityCritical]
1231         static internal IntPtr ConvertToNative<T>(ref Nullable<T> pManaged) where T : struct
1232         {
1233             if (pManaged.HasValue)
1234             {
1235                 object impl = IReferenceFactory.CreateIReference(pManaged);
1236                 return Marshal.GetComInterfaceForObject(impl, typeof(IReference<T>));
1237             }
1238             else
1239             {
1240                 return IntPtr.Zero;
1241             }
1242         }
1243         
1244         [SecurityCritical]
1245         static internal void ConvertToManagedRetVoid<T>(IntPtr pNative, ref Nullable<T> retObj) where T : struct
1246         {
1247             retObj = ConvertToManaged<T>(pNative);
1248         }
1249
1250
1251         [SecurityCritical]
1252         static internal Nullable<T> ConvertToManaged<T>(IntPtr pNative) where T : struct
1253         {
1254             if (pNative != IntPtr.Zero)
1255             {
1256                 object wrapper = InterfaceMarshaler.ConvertToManagedWithoutUnboxing(pNative);
1257                 return (Nullable<T>)CLRIReferenceImpl<T>.UnboxHelper(wrapper);
1258             }
1259             else
1260             {
1261                 return new Nullable<T>();
1262             }
1263         }
1264     }  // class NullableMarshaler
1265
1266     // Corresponds to Windows.UI.Xaml.Interop.TypeName
1267     [StructLayout(LayoutKind.Sequential)]
1268     internal struct TypeNameNative
1269     {
1270
1271         internal IntPtr     typeName;           // HSTRING
1272         internal TypeKind   typeKind;           // TypeKind enum
1273     }
1274
1275     // Corresponds to Windows.UI.Xaml.TypeSource
1276     internal enum TypeKind
1277     {
1278         Primitive,
1279         Metadata,
1280         Projection
1281     };
1282
1283     internal static class WinRTTypeNameConverter
1284     {
1285         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1286         internal static extern string ConvertToWinRTTypeName(System.Type managedType, out bool isPrimitive);
1287         
1288         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1289         internal static extern System.Type GetTypeFromWinRTTypeName(string typeName, out bool isPrimitive);
1290     }
1291     
1292     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1293     internal static class SystemTypeMarshaler
1294     {   
1295         [SecurityCritical]
1296         internal static unsafe void ConvertToNative(System.Type managedType, TypeNameNative *pNativeType)
1297         {
1298             if (!Environment.IsWinRTSupported)
1299             {
1300                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1301             }
1302             
1303             string typeName;
1304             if (managedType != null)
1305             {
1306                 if (managedType.GetType() != typeof(System.RuntimeType))
1307                 {   // The type should be exactly System.RuntimeType (and not its child System.ReflectionOnlyType, or other System.Type children)
1308                     throw new ArgumentException(Environment.GetResourceString("Argument_WinRTSystemRuntimeType", managedType.GetType().ToString()));
1309                 }
1310
1311                 bool isPrimitive;
1312                 string winrtTypeName = WinRTTypeNameConverter.ConvertToWinRTTypeName(managedType, out isPrimitive);
1313                 if (winrtTypeName != null)
1314                 {
1315                     // Must be a WinRT type, either in a WinMD or a Primitive
1316                     typeName = winrtTypeName;
1317                     if (isPrimitive)
1318                         pNativeType->typeKind = TypeKind.Primitive;
1319                     else
1320                         pNativeType->typeKind = TypeKind.Metadata;
1321                 }
1322                 else
1323                 {
1324                     // Custom .NET type
1325                     typeName = managedType.AssemblyQualifiedName;
1326                     pNativeType->typeKind = TypeKind.Projection;
1327                 }
1328             }
1329             else
1330             {   // Marshal null as empty string + Projection
1331                 typeName = "";
1332                 pNativeType->typeKind = TypeKind.Projection;
1333             }
1334
1335             int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString(typeName, typeName.Length, &pNativeType->typeName);
1336             Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
1337         }
1338         
1339         [SecurityCritical]
1340         internal static unsafe void ConvertToManaged(TypeNameNative *pNativeType, ref System.Type managedType)
1341         {
1342             if (!Environment.IsWinRTSupported)
1343             {
1344                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1345             }
1346             
1347             string typeName = WindowsRuntimeMarshal.HStringToString(pNativeType->typeName);
1348             if (String.IsNullOrEmpty(typeName))
1349             {
1350                 managedType = null;
1351                 return;
1352             }
1353
1354             if (pNativeType->typeKind == TypeKind.Projection)
1355             {
1356                 managedType = Type.GetType(typeName, /* throwOnError = */ true);
1357             }
1358             else
1359             {
1360                 bool isPrimitive;
1361                 managedType = WinRTTypeNameConverter.GetTypeFromWinRTTypeName(typeName, out isPrimitive);
1362
1363                 // TypeSource must match
1364                 if (isPrimitive != (pNativeType->typeKind == TypeKind.Primitive))
1365                     throw new ArgumentException(Environment.GetResourceString("Argument_Unexpected_TypeSource"));
1366             }
1367         }
1368         
1369         [SecurityCritical]
1370         internal static unsafe void ClearNative(TypeNameNative *pNativeType)
1371         {
1372             Contract.Assert(Environment.IsWinRTSupported);
1373
1374             if (pNativeType->typeName != null)
1375             {
1376                 System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString(pNativeType->typeName);
1377             }
1378         }
1379     }  // class SystemTypeMarshaler
1380
1381     // For converting WinRT's Windows.Foundation.HResult into System.Exception and vice versa.
1382     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1383     internal static class HResultExceptionMarshaler
1384     {
1385         static internal unsafe int ConvertToNative(Exception ex)
1386         {
1387             if (!Environment.IsWinRTSupported)
1388             {
1389                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1390             }
1391
1392             if (ex == null)
1393                 return 0;  // S_OK;
1394
1395             return ex._HResult;
1396         }
1397
1398         [SecuritySafeCritical]
1399         static internal unsafe Exception ConvertToManaged(int hr)
1400         {
1401             Contract.Ensures(Contract.Result<Exception>() != null || hr >= 0);
1402
1403             if (!Environment.IsWinRTSupported)
1404             {
1405                 throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
1406             }
1407
1408             Exception e = null;
1409             if (hr < 0)
1410             {
1411                 e = StubHelpers.InternalGetCOMHRExceptionObject(hr, IntPtr.Zero, null, /* fForWinRT */ true);
1412             }
1413
1414             // S_OK should be marshaled as null.  WinRT API's should not return S_FALSE by convention.
1415             // We've chosen to treat S_FALSE as success and return null.
1416             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.");
1417             return e;
1418         }
1419     }  // class HResultExceptionMarshaler
1420
1421     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1422     internal static class KeyValuePairMarshaler
1423     {    
1424         [SecurityCritical]
1425         internal static IntPtr ConvertToNative<K, V>([In] ref KeyValuePair<K, V> pair)
1426         {
1427             IKeyValuePair<K, V> impl = new CLRIKeyValuePairImpl<K, V>(ref pair);
1428             return Marshal.GetComInterfaceForObject(impl, typeof(IKeyValuePair<K, V>));
1429         }
1430         
1431         [SecurityCritical]
1432         internal static KeyValuePair<K, V> ConvertToManaged<K, V>(IntPtr pInsp)
1433         {
1434             object obj = InterfaceMarshaler.ConvertToManagedWithoutUnboxing(pInsp);
1435
1436             IKeyValuePair<K, V> pair = (IKeyValuePair<K, V>)obj;
1437             return new KeyValuePair<K, V>(pair.Key, pair.Value);
1438         }
1439
1440         // Called from COMInterfaceMarshaler
1441         [SecurityCritical]
1442         internal static object ConvertToManagedBox<K, V>(IntPtr pInsp)
1443         {
1444             return (object)ConvertToManaged<K, V>(pInsp);
1445         }
1446     }  // class KeyValuePairMarshaler
1447
1448 #endif // FEATURE_COMINTEROP
1449
1450     [StructLayout(LayoutKind.Sequential)]
1451     internal struct NativeVariant
1452     {
1453         ushort vt;
1454         ushort wReserved1;
1455         ushort wReserved2;
1456         ushort wReserved3;
1457
1458         // The union portion of the structure contains at least one 64-bit type that on some 32-bit platforms
1459         // (notably  ARM) requires 64-bit alignment. So on 32-bit platforms we'll actually size the variant
1460         // portion of the struct with an Int64 so the type loader notices this requirement (a no-op on x86,
1461         // but on ARM it will allow us to correctly determine the layout of native argument lists containing
1462         // VARIANTs). Note that the field names here don't matter: none of the code refers to these fields,
1463         // the structure just exists to provide size information to the IL marshaler.
1464 #if WIN64
1465         IntPtr data1;
1466         IntPtr data2;
1467 #else
1468         Int64  data1;
1469 #endif
1470     }  // struct NativeVariant
1471
1472 #if !WIN64 && !FEATURE_CORECLR
1473     // Structure filled by IL stubs if copy constructor(s) and destructor(s) need to be called
1474     // on value types pushed on the stack. The structure is stored in s_copyCtorStubDesc by
1475     // SetCopyCtorCookieChain and fetched by CopyCtorCallStubWorker. Must be stack-allocated.
1476     [StructLayout(LayoutKind.Sequential)]
1477     unsafe internal struct CopyCtorStubCookie
1478     {
1479         public void SetData(IntPtr srcInstancePtr, uint dstStackOffset, IntPtr ctorPtr, IntPtr dtorPtr)
1480         {
1481             m_srcInstancePtr = srcInstancePtr;
1482             m_dstStackOffset = dstStackOffset;
1483             m_ctorPtr = ctorPtr;
1484             m_dtorPtr = dtorPtr;
1485         }
1486
1487         public void SetNext(IntPtr pNext)
1488         {
1489             m_pNext = pNext;
1490         }
1491
1492         public IntPtr m_srcInstancePtr; // pointer to the source instance
1493         public uint   m_dstStackOffset; // offset from the start of stack arguments of the pushed 'this' instance
1494
1495         public IntPtr m_ctorPtr;        // fnptr to the managed copy constructor, result of ldftn
1496         public IntPtr m_dtorPtr;        // fnptr to the managed destructor, result of ldftn
1497
1498         public IntPtr m_pNext;          // pointer to next cookie in the chain or IntPtr.Zero
1499     }  // struct CopyCtorStubCookie
1500
1501     // Aggregates pointer to CopyCtorStubCookie and the target of the interop call.
1502     [StructLayout(LayoutKind.Sequential)]
1503     unsafe internal struct CopyCtorStubDesc
1504     {
1505         public IntPtr m_pCookie;
1506         public IntPtr m_pTarget;
1507     }  // struct CopyCtorStubDes
1508 #endif // !WIN64 && !FEATURE_CORECLR
1509
1510     // Aggregates SafeHandle and the "owned" bit which indicates whether the SafeHandle
1511     // has been successfully AddRef'ed. This allows us to do realiable cleanup (Release)
1512     // if and only if it is needed.
1513     [System.Security.SecurityCritical]
1514     internal sealed class CleanupWorkListElement
1515     {
1516         public CleanupWorkListElement(SafeHandle handle)
1517         {
1518             m_handle = handle;
1519         }
1520
1521         public SafeHandle m_handle;
1522
1523         // This field is passed by-ref to SafeHandle.DangerousAddRef.
1524         // CleanupWorkList.Destroy ignores this element if m_owned is not set to true.
1525         public bool m_owned;
1526     }  // class CleanupWorkListElement
1527
1528     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1529     [System.Security.SecurityCritical]
1530     internal sealed class CleanupWorkList
1531     {
1532         private List<CleanupWorkListElement> m_list = new List<CleanupWorkListElement>();
1533         
1534         public void Add(CleanupWorkListElement elem)
1535         {
1536             BCLDebug.Assert(elem.m_owned == false, "m_owned is supposed to be false and set later by DangerousAddRef");
1537             m_list.Add(elem);
1538         }
1539
1540         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1541         public void Destroy()
1542         {
1543             for (int i = m_list.Count - 1; i >= 0; i--)
1544             {
1545                 if (m_list[i].m_owned)
1546                     StubHelpers.SafeHandleRelease(m_list[i].m_handle);
1547             }
1548         }
1549     }  // class CleanupWorkList
1550
1551     [System.Security.SecurityCritical]  // auto-generated
1552     [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1553     [SuppressUnmanagedCodeSecurityAttribute()]
1554     internal static class StubHelpers
1555     {
1556         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1557         static internal extern bool IsQCall(IntPtr pMD);
1558
1559         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1560         static internal extern void InitDeclaringType(IntPtr pMD);
1561
1562         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1563         static internal extern IntPtr GetNDirectTarget(IntPtr pMD);
1564
1565         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1566         static internal extern IntPtr GetDelegateTarget(Delegate pThis, ref IntPtr pStubArg);
1567
1568 #if !WIN64 && !FEATURE_CORECLR
1569         // Written to by a managed stub helper, read by CopyCtorCallStubWorker in VM.
1570         [ThreadStatic]
1571         static CopyCtorStubDesc s_copyCtorStubDesc;
1572
1573         static internal void SetCopyCtorCookieChain(IntPtr pStubArg, IntPtr pUnmngThis, int dwStubFlags, IntPtr pCookie)
1574         {
1575             // we store both the cookie chain head and the target of the copy ctor stub to a thread
1576             // static field to be accessed by the copy ctor (see code:CopyCtorCallStubWorker)
1577             s_copyCtorStubDesc.m_pCookie = pCookie;
1578             s_copyCtorStubDesc.m_pTarget = GetFinalStubTarget(pStubArg, pUnmngThis, dwStubFlags);
1579         }
1580
1581         // Returns the final unmanaged stub target, ignores interceptors.
1582         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1583         static internal extern IntPtr GetFinalStubTarget(IntPtr pStubArg, IntPtr pUnmngThis, int dwStubFlags);
1584 #endif // !FEATURE_CORECLR && !WIN64
1585
1586 #if !FEATURE_CORECLR
1587         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1588         static internal extern void DemandPermission(IntPtr pNMD);
1589 #endif // !FEATURE_CORECLR
1590
1591         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1592         static internal extern void SetLastError();
1593
1594         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1595         static internal extern void ThrowInteropParamException(int resID, int paramIdx);
1596
1597         [System.Security.SecurityCritical]
1598         static internal IntPtr AddToCleanupList(ref CleanupWorkList pCleanupWorkList, SafeHandle handle)
1599         {
1600             if (pCleanupWorkList == null)
1601                 pCleanupWorkList = new CleanupWorkList();
1602
1603             CleanupWorkListElement element = new CleanupWorkListElement(handle);
1604             pCleanupWorkList.Add(element);
1605
1606             // element.m_owned will be true iff the AddRef succeeded
1607             return SafeHandleAddRef(handle, ref element.m_owned);
1608         }
1609
1610         [System.Security.SecurityCritical]
1611         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1612         static internal void DestroyCleanupList(ref CleanupWorkList pCleanupWorkList)
1613         {
1614             if (pCleanupWorkList != null)
1615             {
1616                 pCleanupWorkList.Destroy();
1617                 pCleanupWorkList = null;
1618             }
1619         }
1620
1621         static internal Exception GetHRExceptionObject(int hr)
1622         {
1623             Exception ex = InternalGetHRExceptionObject(hr);
1624             ex.InternalPreserveStackTrace();
1625             return ex;
1626         }
1627
1628         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1629         static internal extern Exception InternalGetHRExceptionObject(int hr);
1630
1631 #if FEATURE_COMINTEROP
1632         static internal Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis)
1633         {
1634             Exception ex = InternalGetCOMHRExceptionObject(hr, pCPCMD, pThis, false);
1635             ex.InternalPreserveStackTrace();
1636             return ex;
1637         }
1638
1639         static internal Exception GetCOMHRExceptionObject_WinRT(int hr, IntPtr pCPCMD, object pThis)
1640         {
1641             Exception ex = InternalGetCOMHRExceptionObject(hr, pCPCMD, pThis, true);
1642             ex.InternalPreserveStackTrace();
1643             return ex;
1644         }
1645
1646         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1647         static internal extern Exception InternalGetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis, bool fForWinRT);
1648
1649 #endif // FEATURE_COMINTEROP
1650
1651         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1652         static internal extern IntPtr CreateCustomMarshalerHelper(IntPtr pMD, int paramToken, IntPtr hndManagedType);
1653
1654         //-------------------------------------------------------
1655         // SafeHandle Helpers
1656         //-------------------------------------------------------
1657         
1658         // AddRefs the SH and returns the underlying unmanaged handle.
1659         [System.Security.SecurityCritical]  // auto-generated
1660         static internal IntPtr SafeHandleAddRef(SafeHandle pHandle, ref bool success)
1661         {
1662             if (pHandle == null)
1663             {
1664                 throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_SafeHandle"));
1665             }
1666             Contract.EndContractBlock();
1667
1668             pHandle.DangerousAddRef(ref success);
1669
1670             return (success ? pHandle.DangerousGetHandle() : IntPtr.Zero);
1671         }
1672
1673         // Releases the SH (to be called from finally block).
1674         [System.Security.SecurityCritical]  // auto-generated
1675         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1676         static internal void SafeHandleRelease(SafeHandle pHandle)
1677         {
1678             if (pHandle == null)
1679             {
1680                 throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_SafeHandle"));
1681             }
1682             Contract.EndContractBlock();
1683
1684             try
1685             {
1686                 pHandle.DangerousRelease();
1687             }
1688 #if MDA_SUPPORTED
1689             catch (Exception ex)
1690             {
1691                 Mda.ReportErrorSafeHandleRelease(ex);
1692             }
1693 #else // MDA_SUPPORTED
1694             catch (Exception)
1695             { }
1696 #endif // MDA_SUPPORTED
1697         }
1698
1699 #if FEATURE_COMINTEROP
1700         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1701         static internal extern IntPtr GetCOMIPFromRCW(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget, out bool pfNeedsRelease);
1702
1703         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1704         static internal extern IntPtr GetCOMIPFromRCW_WinRT(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget);
1705
1706         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1707         static internal extern IntPtr GetCOMIPFromRCW_WinRTSharedGeneric(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget);
1708
1709         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1710         static internal extern IntPtr GetCOMIPFromRCW_WinRTDelegate(object objSrc, IntPtr pCPCMD, out IntPtr ppTarget);
1711
1712         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1713         static internal extern bool ShouldCallWinRTInterface(object objSrc, IntPtr pCPCMD);
1714
1715         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1716         static internal extern Delegate GetTargetForAmbiguousVariantCall(object objSrc, IntPtr pMT, out bool fUseString);
1717
1718         //-------------------------------------------------------
1719         // Helper for the MDA ----OnRCWCleanup
1720         //-------------------------------------------------------
1721         
1722         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1723         static internal extern void StubRegisterRCW(object pThis);
1724
1725         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1726         static internal extern void StubUnregisterRCW(object pThis);
1727
1728         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1729         static internal extern IntPtr GetDelegateInvokeMethod(Delegate pThis);
1730
1731         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1732         [System.Security.SecurityCritical]
1733         static internal extern object GetWinRTFactoryObject(IntPtr pCPCMD);
1734
1735         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1736         [System.Security.SecurityCritical]
1737         static internal extern IntPtr GetWinRTFactoryReturnValue(object pThis, IntPtr pCtorEntry);
1738
1739         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1740         [System.Security.SecurityCritical]
1741         static internal extern IntPtr GetOuterInspectable(object pThis, IntPtr pCtorMD);
1742
1743 #if MDA_SUPPORTED
1744         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1745         static internal extern Exception TriggerExceptionSwallowedMDA(Exception ex, IntPtr pManagedTarget);
1746 #endif // MDA_SUPPORTED
1747
1748 #endif // FEATURE_COMINTEROP
1749
1750 #if MDA_SUPPORTED
1751         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1752         static internal extern void CheckCollectedDelegateMDA(IntPtr pEntryThunk);
1753 #endif // MDA_SUPPORTED
1754
1755         //-------------------------------------------------------
1756         // Profiler helpers
1757         //-------------------------------------------------------
1758 #if PROFILING_SUPPORTED
1759         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1760         static internal extern IntPtr ProfilerBeginTransitionCallback(IntPtr pSecretParam, IntPtr pThread, object pThis);
1761
1762         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1763         static internal extern void ProfilerEndTransitionCallback(IntPtr pMD, IntPtr pThread);
1764 #endif // PROFILING_SUPPORTED
1765
1766         //------------------------------------------------------
1767         // misc
1768         //------------------------------------------------------
1769         static internal void CheckStringLength(int length)
1770         {
1771             CheckStringLength((uint)length);
1772         }
1773
1774         static internal void CheckStringLength(uint length)
1775         {
1776             if (length > 0x7ffffff0)
1777             {
1778                 throw new MarshalDirectiveException(Environment.GetResourceString("Marshaler_StringTooLong"));
1779             }
1780         }
1781
1782         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1783         static internal unsafe extern int strlen(sbyte* ptr);
1784
1785         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1786         static internal extern void DecimalCanonicalizeInternal(ref Decimal dec);
1787         
1788         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1789         static internal unsafe extern void FmtClassUpdateNativeInternal(object obj, byte* pNative, ref CleanupWorkList pCleanupWorkList);
1790         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1791         static internal unsafe extern void FmtClassUpdateCLRInternal(object obj, byte* pNative);
1792         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1793         static internal unsafe extern void LayoutDestroyNativeInternal(byte* pNative, IntPtr pMT);
1794         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1795         static internal extern object AllocateInternal(IntPtr typeHandle);
1796
1797         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1798         static internal extern void MarshalToUnmanagedVaListInternal(IntPtr va_list, uint vaListSize, IntPtr pArgIterator);
1799
1800         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1801         static internal extern void MarshalToManagedVaListInternal(IntPtr va_list, IntPtr pArgIterator);
1802         
1803         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1804         static internal extern uint CalcVaListSize(IntPtr va_list);
1805         
1806         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1807         static internal extern void ValidateObject(object obj, IntPtr pMD, object pThis);
1808
1809         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1810         static internal extern void LogPinnedArgument(IntPtr localDesc, IntPtr nativeArg);
1811
1812         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1813         static internal extern void ValidateByref(IntPtr byref, IntPtr pMD, object pThis); // the byref is pinned so we can safely "cast" it to IntPtr
1814
1815         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1816         static internal extern IntPtr GetStubContext();
1817
1818 #if WIN64
1819         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1820         static internal extern IntPtr GetStubContextAddr();
1821 #endif // WIN64
1822
1823 #if MDA_SUPPORTED
1824         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1825         static internal extern void TriggerGCForMDA();        
1826 #endif // MDA_SUPPORTED
1827
1828 #if FEATURE_ARRAYSTUB_AS_IL
1829         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1830         internal static extern void ArrayTypeCheck(object o, Object[] arr);
1831 #endif
1832
1833 #if FEATURE_STUBS_AS_IL
1834         [MethodImplAttribute(MethodImplOptions.InternalCall)]
1835         internal static extern void MulticastDebuggerTraceHelper(object o, Int32 count);
1836 #endif
1837     }  // class StubHelpers
1838 }