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