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