2010-03-12 Jb Evain <jbevain@novell.com>
[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.Runtime.CompilerServices;
35 using System;
36 using System.Security;
37 using System.Reflection;
38 using System.Threading;
39
40 using System.Runtime.ConstrainedExecution;
41 #if !NET_2_1 || MONOTOUCH
42 using System.Runtime.InteropServices.ComTypes;
43 #endif
44
45 #if !NET_2_1 || MONOTOUCH
46 using Mono.Interop;
47 #endif
48
49 namespace System.Runtime.InteropServices
50 {
51         [SuppressUnmanagedCodeSecurity ()]
52         public static class Marshal
53         {
54                 /* fields */
55                 public static readonly int SystemMaxDBCSCharSize = 2; // don't know what this is
56                 public static readonly int SystemDefaultCharSize;
57
58                 static Marshal ()
59                 {
60                         SystemDefaultCharSize = Environment.OSVersion.Platform == PlatformID.Win32NT ? 2 : 1;
61                 }
62
63                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
64                 private extern static int AddRefInternal (IntPtr pUnk);
65
66                 public static int AddRef (IntPtr pUnk)
67                 {
68                         if (pUnk == IntPtr.Zero)
69                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
70                         return AddRefInternal (pUnk);
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 !NET_2_1 || MONOTOUCH
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 !NET_2_1 || MONOTOUCH
276                 public static Guid GenerateGuidForType (Type type)
277                 {
278                         return type.GUID;
279                 }
280
281                 [MonoTODO]
282                 public static string GenerateProgIdForType (Type type)
283                 {
284                         throw new NotImplementedException ();
285                 }
286
287                 [MonoTODO]
288                 public static object GetActiveObject (string progID)
289                 {
290                         throw new NotImplementedException ();
291                 }
292
293                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
294                 private extern static IntPtr GetCCW (object o, Type T);
295
296                 private static IntPtr GetComInterfaceForObjectInternal (object o, Type T)
297                 {
298                         if (IsComObject (o))
299                                 return ((__ComObject)o).GetInterface (T);
300                         else
301                                 return GetCCW (o, T);
302                 }
303
304                 public static IntPtr GetComInterfaceForObject (object o, Type T)
305                 {
306                         IntPtr pItf = GetComInterfaceForObjectInternal (o, T);
307                         AddRef (pItf);
308                         return pItf;
309                 }
310
311                 [MonoTODO]
312                 public static IntPtr GetComInterfaceForObjectInContext (object o, Type t)
313                 {
314                         throw new NotImplementedException ();
315                 }
316
317                 [MonoNotSupportedAttribute ("MSDN states user code should never need to call this method.")]
318                 public static object GetComObjectData (object obj, object key)
319                 {
320                         throw new NotSupportedException ("MSDN states user code should never need to call this method.");
321                 }
322
323                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
324                 private extern static int GetComSlotForMethodInfoInternal (MemberInfo m);
325
326                 public static int GetComSlotForMethodInfo (MemberInfo m)
327                 {
328                         if (m == null)
329                                 throw new ArgumentNullException ("m");
330                         if (!(m is MethodInfo))
331                                 throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
332                         if (!m.DeclaringType.IsInterface)
333                                 throw new ArgumentException ("The MemberInfo must be an interface method.", "m");
334                         return GetComSlotForMethodInfoInternal (m);
335                 }
336
337                 [MonoTODO]
338                 public static int GetEndComSlot (Type t)
339                 {
340                         throw new NotImplementedException ();
341                 }
342
343                 [MonoTODO]
344                 public static int GetExceptionCode()
345                 {
346                         throw new NotImplementedException ();
347                 }
348
349                 [MonoTODO]
350                 [ComVisible (true)]
351                 public static IntPtr GetExceptionPointers()
352                 {
353                         throw new NotImplementedException ();
354                 }
355
356                 public static IntPtr GetHINSTANCE (Module m)
357                 {
358                         if (m == null)
359                                 throw new ArgumentNullException ("m");
360
361                         return m.GetHINSTANCE ();
362                 }
363 #endif // !NET_2_1
364
365                 [MonoTODO ("SetErrorInfo")]
366                 public static int GetHRForException (Exception e)
367                 {
368                         return e.hresult;
369                 }
370
371                 [MonoTODO]
372                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
373                 public static int GetHRForLastWin32Error()
374                 {
375                         throw new NotImplementedException ();
376                 }
377 #if !NET_2_1 || MONOTOUCH
378                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
379                 private extern static IntPtr GetIDispatchForObjectInternal (object o);
380
381                 public static IntPtr GetIDispatchForObject (object o)
382                 {
383                         IntPtr pUnk = GetIDispatchForObjectInternal (o);
384                         // Internal method does not AddRef
385                         AddRef (pUnk);
386                         return pUnk;
387                 }
388
389                 [MonoTODO]
390                 public static IntPtr GetIDispatchForObjectInContext (object o)
391                 {
392                         throw new NotImplementedException ();
393                 }
394
395                 [MonoTODO]
396                 public static IntPtr GetITypeInfoForType (Type t)
397                 {
398                         throw new NotImplementedException ();
399                 }
400
401                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
402                 private extern static IntPtr GetIUnknownForObjectInternal (object o);
403
404                 public static IntPtr GetIUnknownForObject (object o)
405                 {
406                         IntPtr pUnk = GetIUnknownForObjectInternal (o);
407                         // Internal method does not AddRef
408                         AddRef (pUnk);
409                         return pUnk;
410                 }
411
412                 [MonoTODO]
413                 public static IntPtr GetIUnknownForObjectInContext (object o)
414                 {
415                         throw new NotImplementedException ();
416                 }
417
418                 [MonoTODO]
419                 [Obsolete ("This method has been deprecated")]
420                 public static IntPtr GetManagedThunkForUnmanagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
421                 {
422                         throw new NotImplementedException ();
423                 }
424
425                 [MonoTODO]
426                 public static MemberInfo GetMethodInfoForComSlot (Type t, int slot, ref ComMemberType memberType)
427                 {
428                         throw new NotImplementedException ();
429                 }
430
431                 public static void GetNativeVariantForObject (object obj, IntPtr pDstNativeVariant)
432                 {
433                         Variant vt = new Variant();
434                         vt.SetValue(obj);
435                         Marshal.StructureToPtr(vt, pDstNativeVariant, false);
436                 }
437
438                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
439                 private static extern object GetObjectForCCW (IntPtr pUnk);
440
441                 public static object GetObjectForIUnknown (IntPtr pUnk)
442                 {
443                         object obj = GetObjectForCCW (pUnk);
444                         // was not a CCW
445                         if (obj == null) {
446                                 ComInteropProxy proxy = ComInteropProxy.GetProxy (pUnk, typeof (__ComObject));
447                                 obj = proxy.GetTransparentProxy ();
448                         }
449                         return obj;
450                 }
451
452                 public static object GetObjectForNativeVariant (IntPtr pSrcNativeVariant)
453                 {
454                         Variant vt = (Variant)Marshal.PtrToStructure(pSrcNativeVariant, typeof(Variant));
455                         return vt.GetValue();
456                 }
457
458                 public static object[] GetObjectsForNativeVariants (IntPtr aSrcNativeVariant, int cVars)
459                 {
460                         if (cVars < 0)
461                                 throw new ArgumentOutOfRangeException ("cVars", "cVars cannot be a negative number.");
462                         object[] objects = new object[cVars];
463                         for (int i = 0; i < cVars; i++)
464                                 objects[i] = GetObjectForNativeVariant ((IntPtr)(aSrcNativeVariant.ToInt64 () +
465                                         i * SizeOf (typeof(Variant))));
466                         return objects;
467                 }
468
469                 [MonoTODO]
470                 public static int GetStartComSlot (Type t)
471                 {
472                         throw new NotImplementedException ();
473                 }
474
475                 [MonoTODO]
476                 [Obsolete ("This method has been deprecated")]
477                 public static Thread GetThreadFromFiberCookie (int cookie)
478                 {
479                         throw new NotImplementedException ();
480                 }
481
482                 public static object GetTypedObjectForIUnknown (IntPtr pUnk, Type t)
483                 {
484                         ComInteropProxy proxy = new ComInteropProxy (pUnk, t);
485                         __ComObject co = (__ComObject)proxy.GetTransparentProxy ();
486                         foreach (Type itf in t.GetInterfaces ()) {
487                                 if ((itf.Attributes & TypeAttributes.Import) == TypeAttributes.Import) {
488                                         if (co.GetInterface (itf) == IntPtr.Zero)
489                                                 return null;
490                                 }
491                         }
492                         return co;
493                 }
494
495                 [MonoTODO]
496                 public static Type GetTypeForITypeInfo (IntPtr piTypeInfo)
497                 {
498                         throw new NotImplementedException ();
499                 }
500
501                 [Obsolete]
502                 [MonoTODO]
503                 public static string GetTypeInfoName (UCOMITypeInfo pTI)
504                 {
505                         throw new NotImplementedException ();
506                 }
507
508                 public static string GetTypeInfoName (ITypeInfo typeInfo)
509                 {
510                         throw new NotImplementedException ();
511                 }
512
513                 [Obsolete]
514                 [MonoTODO]
515                 public static Guid GetTypeLibGuid (UCOMITypeLib pTLB)
516                 {
517                         throw new NotImplementedException ();
518                 }
519
520                 [MonoTODO]
521                 public static Guid GetTypeLibGuid (ITypeLib typelib)
522                 {
523                         throw new NotImplementedException ();
524                 }
525
526                 [MonoTODO]
527                 public static Guid GetTypeLibGuidForAssembly (Assembly asm)
528                 {
529                         throw new NotImplementedException ();
530                 }
531
532                 [Obsolete]
533                 [MonoTODO]
534                 public static int GetTypeLibLcid (UCOMITypeLib pTLB)
535                 {
536                         throw new NotImplementedException ();
537                 }
538
539                 [MonoTODO]
540                 public static int GetTypeLibLcid (ITypeLib typelib)
541                 {
542                         throw new NotImplementedException ();
543                 }
544
545                 [Obsolete]
546                 [MonoTODO]
547                 public static string GetTypeLibName (UCOMITypeLib pTLB)
548                 {
549                         throw new NotImplementedException ();
550                 }
551
552                 [MonoTODO]
553                 public static string GetTypeLibName (ITypeLib typelib)
554                 {
555                         throw new NotImplementedException ();
556                 }
557
558                 [MonoTODO]
559                 public static void GetTypeLibVersionForAssembly (Assembly inputAssembly, out int majorVersion, out int minorVersion)
560                 {
561                         throw new NotImplementedException ();
562                 }
563
564                 public static object GetUniqueObjectForIUnknown (IntPtr unknown)
565                 {
566                         throw new NotImplementedException ();
567                 }
568
569                 [MonoTODO]
570                 [Obsolete ("This method has been deprecated")]
571                 public static IntPtr GetUnmanagedThunkForManagedMethodPtr (IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature)
572                 {
573                         throw new NotImplementedException ();
574                 }
575
576                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
577                 public extern static bool IsComObject (object o);
578
579                 [MonoTODO]
580                 public static bool IsTypeVisibleFromCom (Type t)
581                 {
582                         throw new NotImplementedException ();
583                 }
584
585                 [MonoTODO]
586                 public static int NumParamBytes (MethodInfo m)
587                 {
588                         throw new NotImplementedException ();
589                 }
590 #endif // !NET_2_1
591
592                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
593                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
594                 public static extern int GetLastWin32Error();
595
596                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
597                 public extern static IntPtr OffsetOf (Type t, string fieldName);
598
599                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
600                 public extern static void Prelink (MethodInfo m);
601
602                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
603                 public extern static void PrelinkAll (Type c);
604
605                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
606                 public extern static string PtrToStringAnsi (IntPtr ptr);
607                 
608                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
609                 public extern static string PtrToStringAnsi (IntPtr ptr, int len);
610
611                 public static string PtrToStringAuto (IntPtr ptr)
612                 {
613                         return SystemDefaultCharSize == 2
614                                 ? PtrToStringUni (ptr) : PtrToStringAnsi (ptr);
615                 }
616                 
617                 public static string PtrToStringAuto (IntPtr ptr, int len)
618                 {
619                         return SystemDefaultCharSize == 2
620                                 ? PtrToStringUni (ptr, len) : PtrToStringAnsi (ptr, len);
621                 }
622
623                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
624                 public extern static string PtrToStringUni (IntPtr ptr);
625
626                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
627                 public extern static string PtrToStringUni (IntPtr ptr, int len);
628
629                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
630                 public extern static string PtrToStringBSTR (IntPtr ptr);
631                 
632                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
633                 [ComVisible (true)]
634                 public extern static void PtrToStructure (IntPtr ptr, object structure);
635
636                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
637                 [ComVisible (true)]
638                 public extern static object PtrToStructure (IntPtr ptr, Type structureType);
639
640                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
641                 private extern static int QueryInterfaceInternal (IntPtr pUnk, ref Guid iid, out IntPtr ppv);
642
643                 public static int QueryInterface (IntPtr pUnk, ref Guid iid, out IntPtr ppv)
644                 {
645                         if (pUnk == IntPtr.Zero)
646                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
647                         return QueryInterfaceInternal (pUnk, ref iid, out ppv);
648                 }
649
650                 public static byte ReadByte (IntPtr ptr)
651                 {
652                         return ReadByte (ptr, 0);
653                 }
654
655                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
656                 public extern static byte ReadByte (IntPtr ptr, int ofs);
657
658                 [MonoTODO]
659                 public static byte ReadByte ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
660                 {
661                         throw new NotImplementedException ();
662                 }
663
664                 public static short ReadInt16 (IntPtr ptr)
665                 {
666                         return ReadInt16 (ptr, 0);
667                 }
668
669                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
670                 public extern static short ReadInt16 (IntPtr ptr, int ofs);
671
672                 [MonoTODO]
673                 public static short ReadInt16 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
674                 {
675                         throw new NotImplementedException ();
676                 }
677
678                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
679                 public static int ReadInt32 (IntPtr ptr)
680                 {
681                         return ReadInt32 (ptr, 0);
682                 }
683
684                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
685                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
686                 public extern static int ReadInt32 (IntPtr ptr, int ofs);
687
688                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
689                 [MonoTODO]
690                 public static int ReadInt32 ([In, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs)
691                 {
692                         throw new NotImplementedException ();
693                 }
694
695                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
696                 public static long ReadInt64 (IntPtr ptr)
697                 {
698                         return ReadInt64 (ptr, 0);
699                 }
700
701                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
702                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
703                 public extern static long ReadInt64 (IntPtr ptr, int ofs);
704
705                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
706                 [MonoTODO]
707                 public static long ReadInt64 ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
708                 {
709                         throw new NotImplementedException ();
710                 }
711
712                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
713                 public static IntPtr ReadIntPtr (IntPtr ptr)
714                 {
715                         return ReadIntPtr (ptr, 0);
716                 }
717                 
718                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
719                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
720                 public extern static IntPtr ReadIntPtr (IntPtr ptr, int ofs);
721
722                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
723                 [MonoTODO]
724                 public static IntPtr ReadIntPtr ([In, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs)
725                 {
726                         throw new NotImplementedException ();
727                 }
728
729                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
730                 public extern static IntPtr ReAllocCoTaskMem (IntPtr pv, int cb);
731
732                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
733                 public extern static IntPtr ReAllocHGlobal (IntPtr pv, IntPtr cb);
734
735                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
736                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
737                 private extern static int ReleaseInternal (IntPtr pUnk);
738
739                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
740                 public static int Release (IntPtr pUnk)
741                 {
742                         if (pUnk == IntPtr.Zero)
743                                 throw new ArgumentException ("Value cannot be null.", "pUnk");
744                         return ReleaseInternal (pUnk);
745                 }
746
747 #if !NET_2_1 || MONOTOUCH
748                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
749                 private extern static int ReleaseComObjectInternal (object co);
750
751                 public static int ReleaseComObject (object o)
752                 {
753                         if (o == null)
754                                 throw new ArgumentException ("Value cannot be null.", "o");
755                         if (!IsComObject (o))
756                                 throw new ArgumentException ("Value must be a Com object.", "o");
757                         return ReleaseComObjectInternal (o);
758                 }
759
760                 [Obsolete]
761                 [MonoTODO]
762                 public static void ReleaseThreadCache()
763                 {
764                         throw new NotImplementedException ();
765                 }
766
767                 [MonoNotSupportedAttribute ("MSDN states user code should never need to call this method.")]
768                 public static bool SetComObjectData (object obj, object key, object data)
769                 {
770                         throw new NotSupportedException ("MSDN states user code should never need to call this method.");
771                 }
772 #endif // !NET_2_1
773
774                 [ComVisible (true)]
775                 public static int SizeOf (object structure)
776                 {
777                         return SizeOf (structure.GetType ());
778                 }
779
780                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
781                 public extern static int SizeOf (Type t);
782
783                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
784                 public extern static IntPtr StringToBSTR (string s);
785
786                 //
787                 // I believe this is wrong, because in Mono and in P/Invoke
788                 // we treat "Ansi" conversions as UTF-8 conversions, while
789                 // this one does not do this
790                 //
791                 public static IntPtr StringToCoTaskMemAnsi (string s)
792                 {
793                         int length = s.Length + 1;
794                         IntPtr ctm = AllocCoTaskMem (length);
795
796                         byte[] asBytes = new byte[length];
797                         for (int i = 0; i < s.Length; i++)
798                                 asBytes[i] = (byte)s[i];
799                         asBytes[s.Length] = 0;
800
801                         copy_to_unmanaged (asBytes, 0, ctm, length);
802                         return ctm;
803                 }
804
805                 public static IntPtr StringToCoTaskMemAuto (string s)
806                 {
807                         return SystemDefaultCharSize == 2
808                                 ? StringToCoTaskMemUni (s) : StringToCoTaskMemAnsi (s);
809                 }
810
811                 public static IntPtr StringToCoTaskMemUni (string s)
812                 {
813                         int length = s.Length + 1;
814                         IntPtr ctm = AllocCoTaskMem (length * 2);
815                         
816                         char[] asChars = new char[length];
817                         s.CopyTo (0, asChars, 0, s.Length);
818                         asChars[s.Length] = '\0';
819
820                         copy_to_unmanaged (asChars, 0, ctm, length);
821                         return ctm;
822                 }
823
824                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
825                 public extern static IntPtr StringToHGlobalAnsi (string s);
826
827                 public static IntPtr StringToHGlobalAuto (string s)
828                 {
829                         return SystemDefaultCharSize == 2
830                                 ? StringToHGlobalUni (s) : StringToHGlobalAnsi (s);
831                 }
832
833                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
834                 public extern static IntPtr StringToHGlobalUni (string s);
835
836 #if !NET_2_1 || MONOTOUCH
837                 public static IntPtr SecureStringToBSTR (SecureString s)
838                 {
839                         if (s == null)
840                                 throw new ArgumentNullException ("s");
841                         int len = s.Length;
842                         IntPtr ctm = AllocCoTaskMem ((len+1) * 2 + 4);
843                         byte [] buffer = null;
844                         WriteInt32 (ctm, 0, len*2);
845                         try {
846                                 buffer = s.GetBuffer ();
847
848                                 for (int i = 0; i < len; i++)
849                                         WriteInt16 (ctm, 4 + (i * 2), (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
850                                 WriteInt16 (ctm, 4 + buffer.Length, 0);
851                         } finally {
852                                 if (buffer != null)
853                                         for (int i = buffer.Length; i > 0; ){
854                                                 i--;
855                                                 buffer [i] = 0;
856                                         }
857                         }
858                         return (IntPtr) ((long)ctm + 4);
859                 }
860
861                 public static IntPtr SecureStringToCoTaskMemAnsi (SecureString s)
862                 {
863                         if (s == null)
864                                 throw new ArgumentNullException ("s");
865                         int len = s.Length;
866                         IntPtr ctm = AllocCoTaskMem (len + 1);
867                         byte [] copy = new byte [len+1];
868
869                         try {
870                                 byte [] buffer = s.GetBuffer ();
871                                 int i = 0, j = 0;
872                                 for (; i < len; i++, j += 2){
873                                         copy [i] = buffer [j+1];
874                                         buffer [j] = 0;
875                                         buffer [j+1] = 0;
876                                 }
877                                 copy [i] = 0;
878                                 copy_to_unmanaged (copy, 0, ctm, len+1);
879                         } finally {
880                                 // Ensure that we clear the buffer.
881                                 for (int i = len; i > 0; ){
882                                         i--;
883                                         copy [i] = 0;
884                                 }
885                         }
886                         return ctm;
887                 }
888
889                 public static IntPtr SecureStringToCoTaskMemUnicode (SecureString s)
890                 {
891                         if (s == null)
892                                 throw new ArgumentNullException ("s");
893                         int len = s.Length;
894                         IntPtr ctm = AllocCoTaskMem (len * 2 + 2);
895                         byte [] buffer = null;
896                         try {
897                                 buffer = s.GetBuffer ();
898                                 for (int i = 0; i < len; i++)
899                                         WriteInt16 (ctm, i * 2, (short) ((buffer [(i*2)] << 8) | (buffer [i*2+1])));
900                                 WriteInt16 (ctm, buffer.Length, 0);
901                         } finally {
902                                 if (buffer != null)
903                                         for (int i = buffer.Length; i > 0; ){
904                                                 i--;
905                                                 buffer [i] = 0;
906                                         }
907                         }
908                         return ctm;
909                 }
910
911                 public static IntPtr SecureStringToGlobalAllocAnsi (SecureString s)
912                 {
913                         if (s == null)
914                                 throw new ArgumentNullException ("s");
915                         return SecureStringToCoTaskMemAnsi (s);
916                 }
917
918                 public static IntPtr SecureStringToGlobalAllocUnicode (SecureString s)
919                 {
920                         if (s == null)
921                                 throw new ArgumentNullException ("s");
922                         return SecureStringToCoTaskMemUnicode (s);
923                 }
924 #endif
925
926                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
927                 [ComVisible (true)]
928                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
929                 public extern static void StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);
930
931                 public static void ThrowExceptionForHR (int errorCode) {
932                         Exception ex = GetExceptionForHR (errorCode);
933                         if (ex != null)
934                                 throw ex;
935                 }
936
937                 public static void ThrowExceptionForHR (int errorCode, IntPtr errorInfo) {
938                         Exception ex = GetExceptionForHR (errorCode, errorInfo);
939                         if (ex != null)
940                                 throw ex;
941                 }
942
943                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
944                 public extern static IntPtr UnsafeAddrOfPinnedArrayElement (Array arr, int index);
945
946                 public static void WriteByte (IntPtr ptr, byte val)
947                 {
948                         WriteByte (ptr, 0, val);
949                 }
950
951                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
952                 public extern static void WriteByte (IntPtr ptr, int ofs, byte val);
953
954                 [MonoTODO]
955                 public static void WriteByte ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, byte val)
956                 {
957                         throw new NotImplementedException ();
958                 }
959
960                 public static void WriteInt16 (IntPtr ptr, short val)
961                 {
962                         WriteInt16 (ptr, 0, val);
963                 }
964
965                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
966                 public extern static void WriteInt16 (IntPtr ptr, int ofs, short val);
967
968                 [MonoTODO]
969                 public static void WriteInt16 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, short val)
970                 {
971                         throw new NotImplementedException ();
972                 }
973
974                 public static void WriteInt16 (IntPtr ptr, char val)
975                 {
976                         WriteInt16 (ptr, 0, val);
977                 }
978
979                 [MonoTODO]
980                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
981                 public extern static void WriteInt16 (IntPtr ptr, int ofs, char val);
982
983                 [MonoTODO]
984                 public static void WriteInt16([In, Out] object ptr, int ofs, char val)
985                 {
986                         throw new NotImplementedException ();
987                 }
988
989                 public static void WriteInt32 (IntPtr ptr, int val)
990                 {
991                         WriteInt32 (ptr, 0, val);
992                 }
993
994                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
995                 public extern static void WriteInt32 (IntPtr ptr, int ofs, int val);
996
997                 [MonoTODO]
998                 public static void WriteInt32([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, int val)
999                 {
1000                         throw new NotImplementedException ();
1001                 }
1002
1003                 public static void WriteInt64 (IntPtr ptr, long val)
1004                 {
1005                         WriteInt64 (ptr, 0, val);
1006                 }
1007
1008                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1009                 public extern static void WriteInt64 (IntPtr ptr, int ofs, long val);
1010
1011                 [MonoTODO]
1012                 public static void WriteInt64 ([In, Out, MarshalAs (UnmanagedType.AsAny)] object ptr, int ofs, long val)
1013                 {
1014                         throw new NotImplementedException ();
1015                 }
1016
1017                 public static void WriteIntPtr (IntPtr ptr, IntPtr val)
1018                 {
1019                         WriteIntPtr (ptr, 0, val);
1020                 }
1021
1022                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1023                 public extern static void WriteIntPtr (IntPtr ptr, int ofs, IntPtr val);
1024
1025                 [MonoTODO]
1026                 public static void WriteIntPtr([In, Out, MarshalAs(UnmanagedType.AsAny)] object ptr, int ofs, IntPtr val)
1027                 {
1028                         throw new NotImplementedException ();
1029                 }
1030
1031                 public static Exception GetExceptionForHR (int errorCode) {
1032                         return GetExceptionForHR (errorCode, IntPtr.Zero);
1033                 }
1034
1035                 public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo) {
1036
1037                         const int E_OUTOFMEMORY = unchecked ((int)0x8007000EL);
1038                         const int E_INVALIDARG = unchecked ((int)0X80070057);
1039                         
1040                         switch (errorCode)
1041                         {
1042                         case E_OUTOFMEMORY:
1043                                 return new OutOfMemoryException ();
1044                         case E_INVALIDARG:
1045                                 return new ArgumentException ();
1046                         }
1047                         if (errorCode < 0)
1048                                 return new COMException ("", errorCode);
1049                         return null;
1050                 }
1051
1052 #if !NET_2_1 || MONOTOUCH
1053                 public static int FinalReleaseComObject (object o)
1054                 {
1055                         while (ReleaseComObject (o) != 0);
1056                         return 0;
1057                 }
1058 #endif
1059
1060                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1061                 private static extern Delegate GetDelegateForFunctionPointerInternal (IntPtr ptr, Type t);
1062
1063                 public static Delegate GetDelegateForFunctionPointer (IntPtr ptr, Type t)
1064                 {
1065                         if (t == null)
1066                                 throw new ArgumentNullException ("t");
1067                         if (!t.IsSubclassOf (typeof (MulticastDelegate)) || (t == typeof (MulticastDelegate)))
1068                                 throw new ArgumentException ("Type is not a delegate", "t");
1069                         if (ptr == IntPtr.Zero)
1070                                 throw new ArgumentNullException ("ptr");
1071
1072                         return GetDelegateForFunctionPointerInternal (ptr, t);
1073                 }
1074
1075                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1076                 private static extern IntPtr GetFunctionPointerForDelegateInternal (Delegate d);
1077                 
1078                 public static IntPtr GetFunctionPointerForDelegate (Delegate d)
1079                 {
1080                         if (d == null)
1081                                 throw new ArgumentNullException ("d");
1082                         
1083                         return GetFunctionPointerForDelegateInternal (d);
1084                 }
1085         }
1086 }