Merge pull request #487 from mayerwin/patch-1
[mono.git] / mcs / class / corlib / System.Runtime.InteropServices / Marshal.cs
1 // System.Runtime.InteropServices.Marshal.cs
2 //
3 // Sean MacIsaac (macisaac@ximian.com)
4 // Paolo Molaro (lupus@ximian.com)
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Jonathan Chambers (joncham@gmail.com)
7 //
8 // (C) 2001-2002 Ximian, Inc.
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System.Collections;
34 using System.Collections.Generic;
35 using System.Runtime.CompilerServices;
36 using System;
37 using System.Security;
38 using System.Reflection;
39 using System.Threading;
40
41 using System.Runtime.ConstrainedExecution;
42 #if !MOONLIGHT
43 #if !FULL_AOT_RUNTIME
44 using System.Runtime.InteropServices.ComTypes;
45 using Mono.Interop;
46 #endif
47 #endif
48
49 namespace System.Runtime.InteropServices
50 {
51         public static class Marshal
52         {
53                 /* fields */
54                 public static readonly int SystemMaxDBCSCharSize = 2; // don't know what this is
55                 public static readonly int SystemDefaultCharSize = Environment.OSVersion.Platform == PlatformID.Win32NT ? 2 : 1;
56
57 #if !MOBILE
58                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
59                 private extern static int AddRefInternal (IntPtr pUnk);
60 #endif
61
62                 public static int AddRef (IntPtr pUnk)
63                 {
64 #if !MOBILE
65                         if (pUnk == IntPtr.Zero)
66                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
67                         return AddRefInternal (pUnk);
68 #else
69                         throw new NotImplementedException ();
70 #endif
71                 }
72
73                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
74                 public extern static IntPtr AllocCoTaskMem (int cb);
75
76                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
77                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
78                 public extern static IntPtr AllocHGlobal (IntPtr cb);
79
80                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
81                 public static IntPtr AllocHGlobal (int cb)
82                 {
83                         return AllocHGlobal ((IntPtr)cb);
84                 }
85
86                 [MonoTODO]
87                 public static object BindToMoniker (string monikerName)
88                 {
89                         throw new NotImplementedException ();
90                 }
91
92                 [MonoTODO]
93                 public static void ChangeWrapperHandleStrength (object otp, bool fIsWeak)
94                 {
95                         throw new NotImplementedException ();
96                 }
97
98                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
99                 internal extern static void copy_to_unmanaged (Array source, int startIndex,
100                                                                IntPtr destination, int length);
101
102                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
103                 internal extern static void copy_from_unmanaged (IntPtr source, int startIndex,
104                                                                  Array destination, int length);
105
106                 public static void Copy (byte[] source, int startIndex, IntPtr destination, int length)
107                 {
108                         copy_to_unmanaged (source, startIndex, destination, length);
109                 }
110
111                 public static void Copy (char[] source, int startIndex, IntPtr destination, int length)
112                 {
113                         copy_to_unmanaged (source, startIndex, destination, length);
114                 }
115
116                 public static void Copy (short[] source, int startIndex, IntPtr destination, int length)
117                 {
118                         copy_to_unmanaged (source, startIndex, destination, length);
119                 }
120
121                 public static void Copy (int[] source, int startIndex, IntPtr destination, int length)
122                 {
123                         copy_to_unmanaged (source, startIndex, destination, length);
124                 }
125
126                 public static void Copy (long[] source, int startIndex, IntPtr destination, int length)
127                 {
128                         copy_to_unmanaged (source, startIndex, destination, length);
129                 }
130
131                 public static void Copy (float[] source, int startIndex, IntPtr destination, int length)
132                 {
133                         copy_to_unmanaged (source, startIndex, destination, length);
134                 }
135
136                 public static void Copy (double[] source, int startIndex, IntPtr destination, int length)
137                 {
138                         copy_to_unmanaged (source, startIndex, destination, length);
139                 }
140
141                 public static void Copy (IntPtr[] source, int startIndex, IntPtr destination, int length)
142                 {
143                         copy_to_unmanaged (source, startIndex, destination, length);
144                 }
145
146                 public static void Copy (IntPtr source, byte[] destination, int startIndex, int length)
147                 {
148                         copy_from_unmanaged (source, startIndex, destination, length);
149                 }
150
151                 public static void Copy (IntPtr source, char[] destination, int startIndex, int length)
152                 {
153                         copy_from_unmanaged (source, startIndex, destination, length);
154                 }
155
156                 public static void Copy (IntPtr source, short[] destination, int startIndex, int length)
157                 {
158                         copy_from_unmanaged (source, startIndex, destination, length);
159                 }
160
161                 public static void Copy (IntPtr source, int[] destination, int startIndex, int length)
162                 {
163                         copy_from_unmanaged (source, startIndex, destination, length);
164                 }
165
166                 public static void Copy (IntPtr source, long[] destination, int startIndex, int length)
167                 {
168                         copy_from_unmanaged (source, startIndex, destination, length);
169                 }
170
171                 public static void Copy (IntPtr source, float[] destination, int startIndex, int length)
172                 {
173                         copy_from_unmanaged (source, startIndex, destination, length);
174                 }
175
176                 public static void Copy (IntPtr source, double[] destination, int startIndex, int length)
177                 {
178                         copy_from_unmanaged (source, startIndex, destination, length);
179                 }
180
181                 public static void Copy (IntPtr source, IntPtr[] destination, int startIndex, int length)
182                 {
183                         copy_from_unmanaged (source, startIndex, destination, length);
184                 }
185
186                 public static IntPtr CreateAggregatedObject (IntPtr pOuter,
187                                                              object o)
188                 {
189                         throw new NotImplementedException ();
190                 }
191
192 #if !FULL_AOT_RUNTIME && !MOONLIGHT
193                 public static object CreateWrapperOfType (object o, Type t)
194                 {
195                         __ComObject co = o as __ComObject;
196                         if (co == null)
197                                 throw new ArgumentException ("o must derive from __ComObject", "o");
198                         if (t == null)
199                                 throw new ArgumentNullException ("t");
200
201                         Type[] itfs = o.GetType ().GetInterfaces ();
202                         foreach (Type itf in itfs) {
203                                 if (itf.IsImport && co.GetInterface (itf) == IntPtr.Zero)
204                                         throw new InvalidCastException ();
205                         }
206
207                         return ComInteropProxy.GetProxy (co.IUnknown, t).GetTransparentProxy ();
208                 }
209 #endif
210
211                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
212                 [ComVisible (true)]
213                 public extern static void DestroyStructure (IntPtr ptr, Type structuretype);
214
215                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
216                 public extern static void FreeBSTR (IntPtr ptr);
217
218                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
219                 public extern static void FreeCoTaskMem (IntPtr ptr);
220
221                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
222                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
223                 public extern static void FreeHGlobal (IntPtr hglobal);
224
225                 static void ClearBSTR (IntPtr ptr)
226                 {
227                         int len = ReadInt32 (ptr, -4);
228
229                         for (int i = 0; i < len; i++)
230                                 WriteByte (ptr, i, 0);
231                 }
232                 
233                 public static void ZeroFreeBSTR (IntPtr s)
234                 {
235                         ClearBSTR (s);
236                         FreeBSTR (s);
237                 }
238
239                 static void ClearAnsi (IntPtr ptr)
240                 {
241                         for (int i = 0; ReadByte (ptr, i) != 0; i++)
242                                 WriteByte (ptr, i, 0);
243                 }
244
245                 static void ClearUnicode (IntPtr ptr)
246                 {
247                         for (int i = 0; ReadInt16 (ptr, i) != 0; i += 2)
248                                 WriteInt16 (ptr, i, 0);
249                 }
250                 
251                 public static void ZeroFreeCoTaskMemAnsi (IntPtr s)
252                 {
253                         ClearAnsi (s);
254                         FreeCoTaskMem (s);
255                 }
256
257                 public static void ZeroFreeCoTaskMemUnicode (IntPtr s)
258                 {
259                         ClearUnicode (s);
260                         FreeCoTaskMem (s);
261                 }
262
263                 public static void ZeroFreeGlobalAllocAnsi (IntPtr s)
264                 {
265                         ClearAnsi (s);
266                         FreeHGlobal (s);
267                 }
268
269                 public static void ZeroFreeGlobalAllocUnicode (IntPtr s)
270                 {
271                         ClearUnicode (s);
272                         FreeHGlobal (s);
273                 }
274
275 #if !FULL_AOT_RUNTIME && !MOONLIGHT
276                 public static Guid GenerateGuidForType (Type type)
277                 {
278                         return type.GUID;
279                 }
280
281                 public static string GenerateProgIdForType (Type type)
282                 {
283                         IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (type);
284
285                         foreach (var a in attrs)
286                         {
287                                 var dt = a.Constructor.DeclaringType;
288                                 string name = dt.Name;
289                                 if (name == "ProgIdAttribute")
290                                 {
291                                         var args = a.ConstructorArguments;
292                                         string text = a.ConstructorArguments[0].Value as string;
293                                         if (text == null)
294                                         {
295                                                 text = string.Empty;
296                                         }
297                                         return text;
298                                 }
299                         }
300
301                         return type.FullName;
302                 }
303
304                 [MonoTODO]
305                 public static object GetActiveObject (string progID)
306                 {
307                         throw new NotImplementedException ();
308                 }
309
310 #if !MOBILE
311                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
312                 private extern static IntPtr GetCCW (object o, Type T);
313
314                 private static IntPtr GetComInterfaceForObjectInternal (object o, Type T)
315                 {
316                         if (IsComObject (o))
317                                 return ((__ComObject)o).GetInterface (T);
318                         else
319                                 return GetCCW (o, T);
320                 }
321 #endif
322
323                 public static IntPtr GetComInterfaceForObject (object o, Type T)
324                 {
325 #if !MOBILE
326                         IntPtr pItf = GetComInterfaceForObjectInternal (o, T);
327                         AddRef (pItf);
328                         return pItf;
329 #else
330                         throw new NotImplementedException ();
331 #endif
332                 }
333
334                 [MonoTODO]
335                 public static IntPtr GetComInterfaceForObjectInContext (object o, Type t)
336                 {
337                         throw new NotImplementedException ();
338                 }
339
340                 [MonoNotSupportedAttribute ("MSDN states user code should never need to call this method.")]
341                 public static object GetComObjectData (object obj, object key)
342                 {
343                         throw new NotSupportedException ("MSDN states user code should never need to call this method.");
344                 }
345
346 #if !MOBILE
347                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
348                 private extern static int GetComSlotForMethodInfoInternal (MemberInfo m);
349 #endif
350
351                 public static int GetComSlotForMethodInfo (MemberInfo m)
352                 {
353 #if !MOBILE
354                         if (m == null)
355                                 throw new ArgumentNullException ("m");
356                         if (!(m is MethodInfo))
357                                 throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
358                         if (!m.DeclaringType.IsInterface)
359                                 throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
360                         return GetComSlotForMethodInfoInternal (m);
361 #else
362                         throw new NotImplementedException ();
363 #endif
364                 }
365
366                 [MonoTODO]
367                 public static int GetEndComSlot (Type t)
368                 {
369                         throw new NotImplementedException ();
370                 }
371
372                 [MonoTODO]
373                 public static int GetExceptionCode()
374                 {
375                         throw new NotImplementedException ();
376                 }
377
378                 [MonoTODO]
379                 [ComVisible (true)]
380                 public static IntPtr GetExceptionPointers()
381                 {
382                         throw new NotImplementedException ();
383                 }
384
385                 public static IntPtr GetHINSTANCE (Module m)
386                 {
387                         if (m == null)
388                                 throw new ArgumentNullException ("m");
389
390                         return m.GetHINSTANCE ();
391                 }
392 #endif // !MOONLIGHT
393
394 #if !FULL_AOT_RUNTIME
395                 [MonoTODO ("SetErrorInfo")]
396                 public static int GetHRForException (Exception e)
397                 {
398                         return e.hresult;
399                 }
400
401                 [MonoTODO]
402                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
403                 public static int GetHRForLastWin32Error()
404                 {
405                         throw new NotImplementedException ();
406                 }
407 #if !MOONLIGHT
408                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
409                 private extern static IntPtr GetIDispatchForObjectInternal (object o);
410
411                 public static IntPtr GetIDispatchForObject (object o)
412                 {
413                         IntPtr pUnk = GetIDispatchForObjectInternal (o);
414                         // Internal method does not AddRef
415                         AddRef (pUnk);
416                         return pUnk;
417                 }
418
419                 [MonoTODO]
420                 public static IntPtr GetIDispatchForObjectInContext (object o)
421                 {
422                         throw new NotImplementedException ();
423                 }
424
425                 [MonoTODO]
426                 public static IntPtr GetITypeInfoForType (Type t)
427                 {
428                         throw new NotImplementedException ();
429                 }
430
431                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
432                 private extern static IntPtr GetIUnknownForObjectInternal (object o);
433
434                 public static IntPtr GetIUnknownForObject (object o)
435                 {
436                         IntPtr pUnk = GetIUnknownForObjectInternal (o);
437                         // Internal method does not AddRef
438                         AddRef (pUnk);
439                         return pUnk;
440                 }
441
442                 [MonoTODO]
443                 public static IntPtr GetIUnknownForObjectInContext (object o)
444                 {
445                         throw new NotImplementedException ();
446                 }
447
448                 [MonoTODO]
449                 [Obsolete ("This method has been deprecated")]
450                 public static IntPtr GetManagedThunkForUnmanagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
451                 {
452                         throw new NotImplementedException ();
453                 }
454
455                 [MonoTODO]
456                 public static MemberInfo GetMethodInfoForComSlot (Type t, int slot, ref ComMemberType memberType)
457                 {
458                         throw new NotImplementedException ();
459                 }
460
461                 public static void GetNativeVariantForObject (object obj, IntPtr pDstNativeVariant)
462                 {
463                         Variant vt = new Variant();
464                         vt.SetValue(obj);
465                         Marshal.StructureToPtr(vt, pDstNativeVariant, false);
466                 }
467
468 #if !MOBILE
469                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
470                 private static extern object GetObjectForCCW (IntPtr pUnk);
471 #endif
472
473                 public static object GetObjectForIUnknown (IntPtr pUnk)
474                 {
475 #if !MOBILE
476                         object obj = GetObjectForCCW (pUnk);
477                         // was not a CCW
478                         if (obj == null) {
479                                 ComInteropProxy proxy = ComInteropProxy.GetProxy (pUnk, typeof (__ComObject));
480                                 obj = proxy.GetTransparentProxy ();
481                         }
482                         return obj;
483 #else
484                         throw new NotImplementedException ();
485 #endif
486                 }
487
488                 public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant)
489                 {
490                         Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
491                         return vt.GetValue();
492                 }
493
494                 public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars)
495                 {
496                         if (cVars < 0)
497                                 throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
498                         object[] objects = new object[cVars];
499                         for (int i = 0; i < cVars; i++)
500                                 objects[i] = GetObjectForNativeVariant ((IntPtr)(aSrcNativeVariant.ToInt64 () +
501                                         i * SizeOf (typeof(Variant))));
502                         return objects;
503                 }
504
505                 [MonoTODO]
506                 public static int GetStartComSlot (Type t)
507                 {
508                         throw new NotImplementedException ();
509                 }
510
511                 [MonoTODO]
512                 [Obsolete ("This method has been deprecated")]
513                 public static Thread GetThreadFromFiberCookie (int cookie)
514                 {
515                         throw new NotImplementedException ();
516                 }
517
518                 public static object GetTypedObjectForIUnknown (IntPtr pUnk, Type t)
519                 {
520                         ComInteropProxy proxy = new ComInteropProxy (pUnk, t);
521                         __ComObject co = (__ComObject)proxy.GetTransparentProxy ();
522                         foreach (Type itf in t.GetInterfaces ()) {
523                                 if ((itf.Attributes & TypeAttributes.Import) == TypeAttributes.Import) {
524                                         if (co.GetInterface (itf) == IntPtr.Zero)
525                                                 return null;
526                                 }
527                         }
528                         return co;
529                 }
530
531                 [MonoTODO]
532                 public static Type GetTypeForITypeInfo (IntPtr piTypeInfo)
533                 {
534                         throw new NotImplementedException ();
535                 }
536
537 #if !FULL_AOT_RUNTIME
538                 [Obsolete]
539                 [MonoTODO]
540                 public static string GetTypeInfoName (UCOMITypeInfo pTI)
541                 {
542                         throw new NotImplementedException ();
543                 }
544
545                 public static string GetTypeInfoName (ITypeInfo typeInfo)
546                 {
547                         throw new NotImplementedException ();
548                 }
549
550                 [Obsolete]
551                 [MonoTODO]
552                 public static Guid GetTypeLibGuid (UCOMITypeLib pTLB)
553                 {
554                         throw new NotImplementedException ();
555                 }
556
557                 [MonoTODO]
558                 public static Guid GetTypeLibGuid (ITypeLib typelib)
559                 {
560                         throw new NotImplementedException ();
561                 }
562
563                 [MonoTODO]
564                 public static Guid GetTypeLibGuidForAssembly (Assembly asm)
565                 {
566                         throw new NotImplementedException ();
567                 }
568
569                 [Obsolete]
570                 [MonoTODO]
571                 public static int GetTypeLibLcid (UCOMITypeLib pTLB)
572                 {
573                         throw new NotImplementedException ();
574                 }
575
576                 [MonoTODO]
577                 public static int GetTypeLibLcid (ITypeLib typelib)
578                 {
579                         throw new NotImplementedException ();
580                 }
581
582                 [Obsolete]
583                 [MonoTODO]
584                 public static string GetTypeLibName (UCOMITypeLib pTLB)
585                 {
586                         throw new NotImplementedException ();
587                 }
588
589                 [MonoTODO]
590                 public static string GetTypeLibName (ITypeLib typelib)
591                 {
592                         throw new NotImplementedException ();
593                 }
594
595                 [MonoTODO]
596                 public static void GetTypeLibVersionForAssembly (Assembly inputAssembly, out int majorVersion, out int minorVersion)
597                 {
598                         throw new NotImplementedException ();
599                 }
600
601                 public static object GetUniqueObjectForIUnknown (IntPtr unknown)
602                 {
603                         throw new NotImplementedException ();
604                 }
605 #endif
606
607                 [MonoTODO]
608                 [Obsolete ("This method has been deprecated")]
609                 public static IntPtr GetUnmanagedThunkForManagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
610                 {
611                         throw new NotImplementedException ();
612                 }
613
614 #if !MOBILE
615                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
616                 public extern static bool IsComObject (object o);
617 #else
618                 public static bool IsComObject (object o)
619                 {
620                         throw new NotImplementedException ();
621                 }
622 #endif          
623
624                 [MonoTODO]
625                 public static bool IsTypeVisibleFromCom (Type t)
626                 {
627                         throw new NotImplementedException ();
628                 }
629
630                 [MonoTODO]
631                 public static int NumParamBytes (MethodInfo m)
632                 {
633                         throw new NotImplementedException ();
634                 }
635 #endif // !NET_2_1
636 #endif
637
638                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
639                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
640                 public static extern int GetLastWin32Error();
641
642                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
643                 public extern static IntPtr OffsetOf (Type t, string fieldName);
644
645                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
646                 public extern static void Prelink (MethodInfo m);
647
648                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
649                 public extern static void PrelinkAll (Type c);
650
651                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
652                 public extern static string PtrToStringAnsi (IntPtr ptr);
653                 
654                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
655                 public extern static string PtrToStringAnsi (IntPtr ptr, int len);
656
657                 public static string PtrToStringAuto (IntPtr ptr)
658                 {
659                         return SystemDefaultCharSize == 2
660                                 ? PtrToStringUni (ptr) : PtrToStringAnsi (ptr);
661                 }
662                 
663                 public static string PtrToStringAuto (IntPtr ptr, int len)
664                 {
665                         return SystemDefaultCharSize == 2
666                                 ? PtrToStringUni (ptr, len) : PtrToStringAnsi (ptr, len);
667                 }
668
669                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
670                 public extern static string PtrToStringUni (IntPtr ptr);
671
672                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
673                 public extern static string PtrToStringUni (IntPtr ptr, int len);
674
675 #if !MOBILE
676                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
677                 public extern static string PtrToStringBSTR (IntPtr ptr);
678 #else
679                 public static string PtrToStringBSTR (IntPtr ptr)
680                 {
681                         throw new NotImplementedException ();
682                 }
683 #endif
684                 
685                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
686                 [ComVisible (true)]
687                 public extern static void PtrToStructure (IntPtr ptr, object structure);
688
689                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
690                 [ComVisible (true)]
691                 public extern static object PtrToStructure (IntPtr ptr, Type structureType);
692
693 #if !MOBILE
694                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
695                 private extern static int QueryInterfaceInternal (IntPtr pUnk, ref Guid iid, out IntPtr ppv);
696 #endif
697
698                 public static int QueryInterface (IntPtr pUnk, ref Guid iid, out IntPtr ppv)
699                 {
700 #if !MOBILE
701                         if (pUnk == IntPtr.Zero)
702                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
703                         return QueryInterfaceInternal (pUnk, ref iid, out ppv);
704 #else
705                         throw new NotImplementedException ();
706 #endif
707                 }
708
709                 public static byte ReadByte (IntPtr ptr)
710                 {
711                         return ReadByte (ptr, 0);
712                 }
713
714                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
715                 public extern static byte ReadByte (IntPtr ptr, int ofs);
716
717                 [MonoTODO]
718                 [SuppressUnmanagedCodeSecurity]
719                 public static byte ReadByte ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
720                 {
721                         throw new NotImplementedException ();
722                 }
723
724                 public static short ReadInt16 (IntPtr ptr)
725                 {
726                         return ReadInt16 (ptr, 0);
727                 }
728
729                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
730                 public extern static short ReadInt16 (IntPtr ptr, int ofs);
731
732                 [MonoTODO]
733                 [SuppressUnmanagedCodeSecurity]
734                 public static short ReadInt16 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
735                 {
736                         throw new NotImplementedException ();
737                 }
738
739                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
740                 public static int ReadInt32 (IntPtr ptr)
741                 {
742                         return ReadInt32 (ptr, 0);
743                 }
744
745                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
746                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
747                 public extern static int ReadInt32 (IntPtr ptr, int ofs);
748
749                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
750                 [MonoTODO]
751                 [SuppressUnmanagedCodeSecurity]
752                 public static int ReadInt32 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
753                 {
754                         throw new NotImplementedException ();
755                 }
756
757                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
758                 public static long ReadInt64 (IntPtr ptr)
759                 {
760                         return ReadInt64 (ptr, 0);
761                 }
762
763                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
764                 public extern static long ReadInt64 (IntPtr ptr, int ofs);
765
766                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
767                 [MonoTODO]
768                 [SuppressUnmanagedCodeSecurity]
769                 public static long ReadInt64 ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
770                 {
771                         throw new NotImplementedException ();
772                 }
773
774                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
775                 public static IntPtr ReadIntPtr (IntPtr ptr)
776                 {
777                         return ReadIntPtr (ptr, 0);
778                 }
779                 
780                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
781                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
782                 public extern static IntPtr ReadIntPtr (IntPtr ptr, int ofs);
783
784                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
785                 [MonoTODO]
786                 public static IntPtr ReadIntPtr ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
787                 {
788                         throw new NotImplementedException ();
789                 }
790
791                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
792                 public extern static IntPtr ReAllocCoTaskMem (IntPtr pv, int cb);
793
794                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
795                 public extern static IntPtr ReAllocHGlobal (IntPtr pv, IntPtr cb);
796
797 #if !MOBILE
798                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
799                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
800                 private extern static int ReleaseInternal (IntPtr pUnk);
801 #endif
802
803                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
804                 public static int Release (IntPtr pUnk)
805                 {
806 #if !MOBILE
807                         if (pUnk == IntPtr.Zero)
808                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
809
810                         return ReleaseInternal (pUnk);
811 #else
812                         throw new NotImplementedException ();
813 #endif
814                 }
815
816 #if !FULL_AOT_RUNTIME
817 #if !MOONLIGHT
818                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
819                 private extern static int ReleaseComObjectInternal (object co);
820
821                 public static int ReleaseComObject (object o)
822                 {
823                         if (o == null)
824                                 throw new ArgumentException ("Value cannot be null.", "o");
825                         if (!IsComObject (o))
826                                 throw new ArgumentException ("Value must be a Com object.", "o");
827                         return ReleaseComObjectInternal (o);
828                 }
829
830                 [Obsolete]
831                 [MonoTODO]
832                 public static void ReleaseThreadCache()
833                 {
834                         throw new NotImplementedException ();
835                 }
836
837                 [MonoNotSupportedAttribute ("MSDN states user code should never need to call this method.")]
838                 public static bool SetComObjectData (object obj, object key, object data)
839                 {
840                         throw new NotSupportedException ("MSDN states user code should never need to call this method.");
841                 }
842 #endif // !NET_2_1
843 #endif
844
845                 [ComVisible (true)]
846                 public static int SizeOf (object structure)
847                 {
848                         return SizeOf (structure.GetType ());
849                 }
850
851                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
852                 public extern static int SizeOf (Type t);
853
854                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
855                 public extern static IntPtr StringToBSTR (string s);
856
857                 //
858                 // I believe this is wrong, because in Mono and in P/Invoke
859                 // we treat "Ansi" conversions as UTF-8 conversions, while
860                 // this one does not do this
861                 //
862                 public static IntPtr StringToCoTaskMemAnsi (string s)
863                 {
864                         int length = s.Length + 1;
865                         IntPtr ctm = AllocCoTaskMem (length);
866
867                         byte[] asBytes = new byte[length];
868                         for (int i = 0; i < s.Length; i++)
869                                 asBytes[i] = (byte)s[i];
870                         asBytes[s.Length] = 0;
871
872                         copy_to_unmanaged (asBytes, 0, ctm, length);
873                         return ctm;
874                 }
875
876                 public static IntPtr StringToCoTaskMemAuto (string s)
877                 {
878                         return SystemDefaultCharSize == 2
879                                 ? StringToCoTaskMemUni (s) : StringToCoTaskMemAnsi (s);
880                 }
881
882                 public static IntPtr StringToCoTaskMemUni (string s)
883                 {
884                         int length = s.Length + 1;
885                         IntPtr ctm = AllocCoTaskMem (length * 2);
886                         
887                         char[] asChars = new char[length];
888                         s.CopyTo (0, asChars, 0, s.Length);
889                         asChars[s.Length] = '\0';
890
891                         copy_to_unmanaged (asChars, 0, ctm, length);
892                         return ctm;
893                 }
894
895                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
896                 public extern static IntPtr StringToHGlobalAnsi (string s);
897
898                 public static IntPtr StringToHGlobalAuto (string s)
899                 {
900                         return SystemDefaultCharSize == 2
901                                 ? StringToHGlobalUni (s) : StringToHGlobalAnsi (s);
902                 }
903
904                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
905                 public extern static IntPtr StringToHGlobalUni (string s);
906
907 #if !MOONLIGHT
908                 public static IntPtr SecureStringToBSTR (SecureString s)
909                 {
910                         if (s == null)
911                                 throw new ArgumentNullException ("s");
912                         int len = s.Length;
913                         IntPtr ctm = AllocCoTaskMem ((len+1) * 2 + 4);
914                         byte [] buffer = null;
915                         WriteInt32 (ctm, 0, len*2);
916                         try {
917                                 buffer = s.GetBuffer ();
918
919                                 for (int i = 0; i < len; i++)
920                                         WriteInt16 (ctm, 4 + (i * 2), (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
921                                 WriteInt16 (ctm, 4 + buffer.Length, 0);
922                         } finally {
923                                 if (buffer != null)
924                                         for (int i = buffer.Length; i > 0; ){
925                                                 i--;
926                                                 buffer [i] = 0;
927                                         }
928                         }
929                         return (IntPtr) ((long)ctm + 4);
930                 }
931
932                 public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
933                 {
934                         if (s == null)
935                                 throw new ArgumentNullException ("s");
936                         int len = s.Length;
937                         IntPtr ctm = AllocCoTaskMem (len + 1);
938                         byte [] copy = new byte [len+1];
939
940                         try {
941                                 byte [] buffer = s.GetBuffer ();
942                                 int i = 0, j = 0;
943                                 for (; i < len; i++, j += 2){
944                                         copy [i] = buffer [j+1];
945                                         buffer [j] = 0;
946                                         buffer [j+1] = 0;
947                                 }
948                                 copy [i] = 0;
949                                 copy_to_unmanaged (copy, 0, ctm, len+1);
950                         } finally {
951                                 // Ensure that we clear the buffer.
952                                 for (int i = len; i > 0; ){
953                                         i--;
954                                         copy [i] = 0;
955                                 }
956                         }
957                         return ctm;
958                 }
959
960                 public static IntPtr SecureStringToCoTaskMemUnicode (SecureString s)
961                 {
962                         if (s == null)
963                                 throw new ArgumentNullException ("s");
964                         int len = s.Length;
965                         IntPtr ctm = AllocCoTaskMem (len * 2 + 2);
966                         byte [] buffer = null;
967                         try {
968                                 buffer = s.GetBuffer ();
969                                 for (int i = 0; i < len; i++)
970                                         WriteInt16 (ctm, i * 2, (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
971                                 WriteInt16 (ctm, buffer.Length, 0);
972                         } finally {
973                                 if (buffer != null)
974                                         for (int i = buffer.Length; i > 0; ){
975                                                 i--;
976                                                 buffer [i] = 0;
977                                         }
978                         }
979                         return ctm;
980                 }
981
982                 public static IntPtr SecureStringToGlobalAllocAnsi (SecureString s)
983                 {
984                         if (s == null)
985                                 throw new ArgumentNullException ("s");
986                         return SecureStringToCoTaskMemAnsi (s);
987                 }
988
989                 public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)
990                 {
991                         if (s == null)
992                                 throw new ArgumentNullException ("s");
993                         return SecureStringToCoTaskMemUnicode (s);
994                 }
995 #endif
996
997                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
998                 [ComVisible (true)]
999                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1000                 public extern static void StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);
1001
1002                 public static void ThrowExceptionForHR (int errorCode) {
1003                         Exception ex = GetExceptionForHR (errorCode);
1004                         if (ex != null)
1005                                 throw ex;
1006                 }
1007
1008                 public static void ThrowExceptionForHR (int errorCode, IntPtr errorInfo) {
1009                         Exception ex = GetExceptionForHR (errorCode, errorInfo);
1010                         if (ex != null)
1011                                 throw ex;
1012                 }
1013
1014                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1015                 public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
1016
1017                 public static void WriteByte (IntPtr ptr, byte val)
1018                 {
1019                         WriteByte (ptr, 0, val);
1020                 }
1021
1022                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1023                 public extern static void WriteByte (IntPtr ptr, int ofs, byte val);
1024
1025                 [MonoTODO]
1026                 [SuppressUnmanagedCodeSecurity]
1027                 public static void WriteByte ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, byte val)
1028                 {
1029                         throw new NotImplementedException ();
1030                 }
1031
1032                 public static void WriteInt16 (IntPtr ptr, short val)
1033                 {
1034                         WriteInt16 (ptr, 0, val);
1035                 }
1036
1037                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1038                 public extern static void WriteInt16 (IntPtr ptr, int ofs, short val);
1039
1040                 [MonoTODO]
1041                 [SuppressUnmanagedCodeSecurity]
1042                 public static void WriteInt16 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, short val)
1043                 {
1044                         throw new NotImplementedException ();
1045                 }
1046
1047                 public static void WriteInt16 (IntPtr ptr, char val)
1048                 {
1049                         WriteInt16 (ptr, 0, val);
1050                 }
1051
1052                 [MonoTODO]
1053                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1054                 public extern static void WriteInt16 (IntPtr ptr, int ofs, char val);
1055
1056                 [MonoTODO]
1057                 public static void WriteInt16([In, Out] object ptr, int ofs, char val)
1058                 {
1059                         throw new NotImplementedException ();
1060                 }
1061
1062                 public static void WriteInt32 (IntPtr ptr, int val)
1063                 {
1064                         WriteInt32 (ptr, 0, val);
1065                 }
1066
1067                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1068                 public extern static void WriteInt32 (IntPtr ptr, int ofs, int val);
1069
1070                 [MonoTODO]
1071                 [SuppressUnmanagedCodeSecurity]
1072                 public static void WriteInt32([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, int val)
1073                 {
1074                         throw new NotImplementedException ();
1075                 }
1076
1077                 public static void WriteInt64 (IntPtr ptr, long val)
1078                 {
1079                         WriteInt64 (ptr, 0, val);
1080                 }
1081
1082                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1083                 public extern static void WriteInt64 (IntPtr ptr, int ofs, long val);
1084
1085                 [MonoTODO]
1086                 [SuppressUnmanagedCodeSecurity]
1087                 public static void WriteInt64 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, long val)
1088                 {
1089                         throw new NotImplementedException ();
1090                 }
1091
1092                 public static void WriteIntPtr (IntPtr ptr, IntPtr val)
1093                 {
1094                         WriteIntPtr (ptr, 0, val);
1095                 }
1096
1097                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1098                 public extern static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val);
1099
1100                 [MonoTODO]
1101                 public static void WriteIntPtr([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, IntPtr val)
1102                 {
1103                         throw new NotImplementedException ();
1104                 }
1105
1106                 public static Exception GetExceptionForHR (int errorCode) {
1107                         return GetExceptionForHR (errorCode, IntPtr.Zero);
1108                 }
1109
1110                 public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo) {
1111
1112                         const int E_OUTOFMEMORY = unchecked ((int)0x8007000EL);
1113                         const int E_INVALIDARG = unchecked ((int)0X80070057);
1114                         
1115                         switch (errorCode)
1116                         {
1117                         case E_OUTOFMEMORY:
1118                                 return new OutOfMemoryException ();
1119                         case E_INVALIDARG:
1120                                 return new ArgumentException ();
1121                         }
1122                         if (errorCode < 0)
1123                                 return new COMException ("", errorCode);
1124                         return null;
1125                 }
1126
1127 #if !FULL_AOT_RUNTIME
1128 #if !MOONLIGHT
1129                 public static int FinalReleaseComObject (object o)
1130                 {
1131                         while (ReleaseComObject (o) != 0);
1132                         return 0;
1133                 }
1134 #endif
1135 #endif
1136
1137                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1138                 private static extern Delegate GetDelegateForFunctionPointerInternal (IntPtr ptr, Type t);
1139
1140                 public static Delegate GetDelegateForFunctionPointer (IntPtr ptr, Type t)
1141                 {
1142                         if (t == null)
1143                                 throw new ArgumentNullException ("t");
1144                         if (!t.IsSubclassOf (typeof (MulticastDelegate)) || (t == typeof (MulticastDelegate)))
1145                                 throw new ArgumentException ("Type is not a delegate", "t");
1146                         if (t.IsGenericType)
1147                                 throw new ArgumentException ("The specified Type must not be a generic type definition.");
1148                         if (ptr == IntPtr.Zero)
1149                                 throw new ArgumentNullException ("ptr");
1150
1151                         return GetDelegateForFunctionPointerInternal (ptr, t);
1152                 }
1153
1154                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1155                 private static extern IntPtr GetFunctionPointerForDelegateInternal (Delegate d);
1156                 
1157                 public static IntPtr GetFunctionPointerForDelegate (Delegate d)
1158                 {
1159                         if (d == null)
1160                                 throw new ArgumentNullException ("d");
1161                         
1162                         return GetFunctionPointerForDelegateInternal (d);
1163                 }
1164         }
1165 }