d6f2a49bf38d774f3ee0f8be8c7a3f1f2f37c685
[mono.git] / mcs / class / corlib / Test / System.Runtime.InteropServices / MarshalTest.cs
1 //
2 // System.Runtime.InteropServices.Marshal Test Cases
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
9 //
10 using NUnit.Framework;
11 using System;
12 using System.IO;
13 using System.Reflection;
14 #if !MOBILE
15 using System.Reflection.Emit;
16 #endif
17 using System.Runtime.InteropServices;
18 using System.Security;
19 using System.Text;
20
21 namespace MonoTests.System.Runtime.InteropServices
22 {
23         [TestFixture]
24         public class MarshalTest
25         {
26                 [StructLayout (LayoutKind.Sequential)]
27                 class ClsSequential {
28                         public int field;
29                 }
30
31                 class ClsNoLayout {
32                         public int field;
33                 }
34
35                 [StructLayout (LayoutKind.Explicit)]
36                 class ClsExplicit {
37                         [FieldOffset (0)] public int field;
38                 }
39
40                 [StructLayout (LayoutKind.Sequential)]
41                 struct StrSequential {
42                         public int field;
43                 }
44
45                 struct StrNoLayout {
46                         public int field;
47                 }
48
49                 [StructLayout (LayoutKind.Explicit)]
50                 struct StrExplicit {
51                         [FieldOffset (0)] public int field;
52                 }
53
54                 [Test]
55                 public void SizeOf_Class_LayoutSequential ()
56                 {
57                         Marshal.SizeOf (typeof (ClsSequential));
58                 }
59
60                 [Test]
61                 public void SizeOf_Class_LayoutNotSet ()
62                 {
63                         try {
64                                 Marshal.SizeOf (typeof (ClsNoLayout));
65                                 Assert.Fail ("#1");
66                         } catch (ArgumentException ex) {
67                                 // Type '...MarshalTest+ClsNoLayout' cannot be
68                                 // marshaled as an unmanaged structure; no
69                                 // meaningful size or offset can be computed
70                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
71                                 Assert.IsNull (ex.InnerException, "#3");
72                                 Assert.IsNotNull (ex.Message, "#4");
73                         }
74                 }
75
76                 [Test]
77                 public void SizeOf_Class_LayoutExplicit ()
78                 {
79                         Marshal.SizeOf (typeof (ClsExplicit));
80                 }
81
82                 [Test]
83                 public void SizeOf_Struct_LayoutSequential ()
84                 {
85                         Marshal.SizeOf (typeof (StrSequential));
86                 }
87
88                 [Test]
89                 public void SizeOf_Struct_LayoutNotSet ()
90                 {
91                         Marshal.SizeOf (typeof (StrNoLayout));
92                 }
93
94                 [Test]
95                 public void SizeOf_Struct_LayoutExplicit ()
96                 {
97                         Marshal.SizeOf (typeof (StrExplicit));
98                 }
99
100                 [Test]
101                 public void SizeOf_Array ()
102                 {
103                         try {
104                                 Marshal.SizeOf (typeof (string []));
105                                 Assert.Fail ("#1");
106                         } catch (ArgumentException ex) {
107                                 // Type 'System.String[]' cannot be marshaled
108                                 // as an unmanaged structure; no meaningful
109                                 // size or offset can be computed
110                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
111                                 Assert.IsNull (ex.InnerException, "#3");
112                                 Assert.IsNotNull (ex.Message, "#4");
113                         }
114                 }
115
116                 [Test]
117                 public unsafe void Sizeof_Pointer ()
118                 {
119                         int size = Marshal.SizeOf (typeof (char*));
120                         Assert.IsTrue (size == 4 || size == 8);
121                 }
122
123                 [Test]
124                 public void PtrToStringWithNull ()
125                 {
126                         Assert.IsNull (Marshal.PtrToStringAnsi (IntPtr.Zero), "A");
127                         Assert.IsNull (Marshal.PtrToStringUni (IntPtr.Zero), "C");
128                 }
129
130                 [Test]
131                 public void PtrToStringAnsi_Ptr_Zero ()
132                 {
133                         try {
134                                 Marshal.PtrToStringAnsi (IntPtr.Zero, 0);
135                                 Assert.Fail ("#1");
136                         } catch (ArgumentNullException ex) {
137                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
138                                 Assert.IsNull (ex.InnerException, "#3");
139                                 Assert.IsNotNull (ex.Message, "#4");
140                                 Assert.AreEqual ("ptr", ex.ParamName, "#5");
141                         }
142                 }
143
144                 [Test]
145                 public void PtrToStringWithUni_Ptr_Zero ()
146                 {
147                         try {
148                                 Marshal.PtrToStringUni (IntPtr.Zero, 0);
149                                 Assert.Fail ("#1");
150                         } catch (ArgumentNullException ex) {
151                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
152                                 Assert.IsNull (ex.InnerException, "#3");
153                                 Assert.IsNotNull (ex.Message, "#4");
154                                 Assert.AreEqual ("ptr", ex.ParamName, "#5");
155                         }
156                 }
157
158                 [Test]
159                 public unsafe void UnsafeAddrOfPinnedArrayElement ()
160                 {
161                         short[] sarr = new short [5];
162                         sarr [2] = 3;
163
164                         IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement (sarr, 2);
165                         Assert.AreEqual (3, *(short*) ptr.ToPointer ());
166                 }
167
168                 [Test]
169                 public void AllocHGlobalZeroSize ()
170                 {
171                         IntPtr ptr = Marshal.AllocHGlobal (0);
172                         Assert.IsTrue (ptr != IntPtr.Zero);
173                         Marshal.FreeHGlobal (ptr);
174                 }
175
176                 struct Foo {
177                         int a;
178                         static int b;
179                         long c;
180                         static char d;
181                         int e;
182                 }
183
184                 [Test]
185                 public void OffsetOf_FieldName_Static ()
186                 {
187                         try {
188                                 Marshal.OffsetOf (typeof (Foo), "b");
189                                 Assert.Fail ("#1");
190                         } catch (ArgumentException ex) {
191                                 // Field passed in is not a marshaled member of
192                                 // the type '...MarshalTest+Foo'
193                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
194                                 Assert.IsNull (ex.InnerException, "#3");
195                                 Assert.IsNotNull (ex.Message, "#4");
196                                 Assert.AreEqual ("fieldName", ex.ParamName, "#5");
197                         }
198                 }
199 #if !MOBILE
200                 [Test]
201                 public void GetHINSTANCE ()
202                 {
203                         if (RunningOnUnix)
204                                 Assert.Ignore ("GetHINSTANCE only applies to Windows.");
205
206                         Assembly a;
207                         IntPtr hinstance;
208                         StringBuilder fileName;
209
210                         fileName = new StringBuilder (255);
211                         a = Assembly.GetExecutingAssembly ();
212                         hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
213                         Assert.IsTrue (GetModuleFileName (hinstance, fileName,
214                                 fileName.Capacity) > 0, "#A1");
215                         Assert.AreEqual (a.Location, fileName.ToString (), "#A2");
216
217                         fileName.Length = 0;
218                         a = typeof (int).Assembly;
219                         hinstance = Marshal.GetHINSTANCE (a.GetModules () [0]);
220                         Assert.IsTrue (GetModuleFileName (hinstance, fileName,
221                                 fileName.Capacity) > 0, "#B1");
222                         Assert.IsTrue (File.Exists (fileName.ToString ()), "#B3");
223                         Assert.AreEqual ("mscorlib.dll", Path.GetFileName (fileName.ToString ()), "#B4");
224                 }
225
226                 [Test]
227                 public void GetHINSTANCE_Module_Dynamic ()
228                 {
229                         AssemblyName aname = new AssemblyName ();
230                         aname.Name = "foo";
231
232                         AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (
233                                 aname, AssemblyBuilderAccess.Save,
234                                 Path.GetTempPath ());
235                         ModuleBuilder mb = ab.DefineDynamicModule ("foo.dll", false);
236
237                         IntPtr hinstance = Marshal.GetHINSTANCE (mb);
238                         Assert.AreEqual (-1, hinstance.ToInt32 ());
239                 }
240
241                 [Test]
242                 public void GetHINSTANCE_Module_Null ()
243                 {
244                         try {
245                                 Marshal.GetHINSTANCE ((Module) null);
246                                 Assert.Fail ("#1");
247                         } catch (ArgumentNullException ex) {
248                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
249                                 Assert.IsNull (ex.InnerException, "#3");
250                                 Assert.IsNotNull (ex.Message, "#4");
251                                 Assert.AreEqual ("m", ex.ParamName, "#5");
252                         }
253                 }
254 #endif
255                 [Test] // bug #319009
256                 public void StringToHGlobalUni ()
257                 {
258                         IntPtr handle = Marshal.StringToHGlobalUni ("unicode data");
259                         string s = Marshal.PtrToStringUni (handle);
260                         Assert.AreEqual (12, s.Length, "#1");
261
262                         handle = Marshal.StringToHGlobalUni ("unicode data string");
263                         s = Marshal.PtrToStringUni (handle);
264                         Assert.AreEqual (19, s.Length, "#2");
265                 }
266
267                 [Test]
268                 public void ReadIntByte ()
269                 {
270                         IntPtr ptr = Marshal.AllocHGlobal (4);
271                         try {
272                                 Marshal.WriteByte (ptr, 0, 0x1);
273                                 Marshal.WriteByte (ptr, 1, 0x2);
274                                 Assert.AreEqual (0x1, Marshal.ReadByte (ptr));
275                                 Assert.AreEqual (0x1, Marshal.ReadByte (ptr, 0));
276                                 Assert.AreEqual (0x2, Marshal.ReadByte (ptr, 1));
277                         } finally {
278                                 Marshal.FreeHGlobal (ptr);
279                         }
280                 }
281
282                 [Test]
283                 public void ReadInt16 ()
284                 {
285                         IntPtr ptr = Marshal.AllocHGlobal (64);
286                         try {
287                                 Marshal.WriteInt16 (ptr, 0, 0x1234);
288                                 Marshal.WriteInt16 (ptr, 2, 0x4567);
289                                 Marshal.WriteInt16 (ptr, 5, 0x4567);
290                                 Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr));
291                                 Assert.AreEqual (0x1234, Marshal.ReadInt16 (ptr, 0));
292                                 Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 2));
293 #if NET_4_5
294                                 Assert.AreEqual (0x4567, Marshal.ReadInt16 ((ptr + 5)));
295 #endif
296                                 Assert.AreEqual (0x4567, Marshal.ReadInt16 (ptr, 5));
297                         } finally {
298                                 Marshal.FreeHGlobal (ptr);
299                         }
300                 }
301
302                 [Test]
303                 public void ReadInt32 ()
304                 {
305                         IntPtr ptr = Marshal.AllocHGlobal (64);
306                         try {
307                                 Marshal.WriteInt32 (ptr, 0, 0x12345678);
308                                 Marshal.WriteInt32 (ptr, 4, 0x77654321);
309                                 Marshal.WriteInt32 (ptr, 10, 0x77654321);
310                                 Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr));
311                                 Assert.AreEqual (0x12345678, Marshal.ReadInt32 (ptr, 0));
312                                 Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 4));
313 #if NET_4_5
314                                 Assert.AreEqual (0x77654321, Marshal.ReadInt32 ((ptr + 10)));
315 #endif
316                                 Assert.AreEqual (0x77654321, Marshal.ReadInt32 (ptr, 10));
317                         } finally {
318                                 Marshal.FreeHGlobal (ptr);
319                         }
320                 }
321
322                 [Test]
323                 public void ReadInt32_Endian ()
324                 {
325                         IntPtr ptr = Marshal.AllocHGlobal (4);
326                         try {
327                                 Marshal.WriteByte (ptr, 0, 0x01);
328                                 Marshal.WriteByte (ptr, 1, 0x02);
329                                 Marshal.WriteByte (ptr, 2, 0x03);
330                                 Marshal.WriteByte (ptr, 3, 0x04);
331                                 // Marshal MUST use the native CPU data
332                                 if (BitConverter.IsLittleEndian){
333                                         Assert.AreEqual (0x04030201, Marshal.ReadInt32 (ptr), "ReadInt32");
334                                 } else {
335                                         Assert.AreEqual (0x01020304, Marshal.ReadInt32 (ptr), "ReadInt32");
336                                 }
337                         } finally {
338                                 Marshal.FreeHGlobal (ptr);
339                         }
340                 }
341
342                 [Test]
343                 public void ReadInt64 ()
344                 {
345                         IntPtr ptr = Marshal.AllocHGlobal (16);
346                         try {
347                                 Marshal.WriteInt64 (ptr, 0, 0x12345678ABCDEFL);
348                                 Marshal.WriteInt64 (ptr, 8, 0x87654321ABCDEFL);
349                                 Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr));
350                                 Assert.AreEqual (0x12345678ABCDEFL, Marshal.ReadInt64 (ptr, 0));
351                                 Assert.AreEqual (0x87654321ABCDEFL, Marshal.ReadInt64 (ptr, 8));
352                         } finally {
353                                 Marshal.FreeHGlobal (ptr);
354                         }
355                 }
356
357                 [Test]
358                 [Category ("MobileNotWorking")]
359                 public void BSTR_Roundtrip ()
360                 {
361                         string s = "mono";
362                         IntPtr ptr = Marshal.StringToBSTR (s);
363                         string s2 = Marshal.PtrToStringBSTR (ptr);
364                         Assert.AreEqual (s, s2, "string");
365                 }
366
367                 [Test]
368                 [Category ("MobileNotWorking")]
369                 public void StringToBSTRWithNullValues ()
370                 {
371                         int size = 128;
372                         string s = String.Empty.PadLeft (size, '\0');
373                         Assert.AreEqual (size, s.Length, "Length-1");
374
375                         IntPtr ptr = Marshal.StringToBSTR (s);
376                         try {
377                                 for (int i = 0; i < size; i += 4)
378                                         Marshal.WriteInt32 (ptr, i, 0);
379
380                                 string s2 = Marshal.PtrToStringBSTR (ptr);
381                                 Assert.AreEqual (128, s2.Length, "Length-2");
382                         } finally {
383                                 Marshal.FreeBSTR (ptr);
384                         }
385                 }
386
387                 [Test]
388                 public void StringToHGlobalAnsiWithNullValues ()
389                 {
390                         int size = 128;
391                         string s = String.Empty.PadLeft (size, '\0');
392                         Assert.AreEqual (size, s.Length, "Length-1");
393
394                         IntPtr ptr = Marshal.StringToHGlobalAnsi (s);
395                         try {
396                                 for (int i = 0; i < size; i += 4)
397                                         Marshal.WriteInt32 (ptr, i, 0);
398
399                                 string s2 = Marshal.PtrToStringAnsi (ptr);
400                                 Assert.AreEqual (0, s2.Length, "Length-2");
401                         } finally {
402                                 Marshal.FreeHGlobal (ptr);
403                         }
404                 }
405
406                 [Test]
407                 public void StringToHGlobalAutoWithNullValues ()
408                 {
409                         int size = 128;
410                         string s = String.Empty.PadLeft (size, '\0');
411                         Assert.AreEqual (size, s.Length, "Length-1");
412
413                         IntPtr ptr = Marshal.StringToHGlobalAuto (s);
414                         try {
415                                 for (int i = 0; i < size; i += 4)
416                                         Marshal.WriteInt32 (ptr, i, 0);
417
418                                 string s2 = Marshal.PtrToStringAuto (ptr);
419                                 Assert.AreEqual (0, s2.Length, "Length-2");
420                         } finally {
421                                 Marshal.FreeHGlobal (ptr);
422                         }
423                 }
424
425                 [Test]
426                 public void StringToHGlobalUniWithNullValues ()
427                 {
428                         int size = 128;
429                         string s = String.Empty.PadLeft (size, '\0');
430                         Assert.AreEqual (size, s.Length, "Length-1");
431
432                         IntPtr ptr = Marshal.StringToHGlobalUni (s);
433                         try {
434                                 for (int i = 0; i < size; i += 4)
435                                         Marshal.WriteInt32 (ptr, i, 0);
436
437                                 string s2 = Marshal.PtrToStringUni (ptr);
438                                 Assert.AreEqual (0, s2.Length, "Length-2");
439                         } finally {
440                                 Marshal.FreeHGlobal (ptr);
441                         }
442                 }
443
444                 [Test]
445                 public void StringToCoTaskMemAnsiWithNullValues ()
446                 {
447                         int size = 128;
448                         string s = String.Empty.PadLeft (size, '\0');
449                         Assert.AreEqual (size, s.Length, "Length-1");
450
451                         IntPtr ptr = Marshal.StringToCoTaskMemAnsi (s);
452                         try {
453                                 for (int i = 0; i < size; i += 4)
454                                         Marshal.WriteInt32 (ptr, i, 0);
455
456                                 string s2 = Marshal.PtrToStringAnsi (ptr);
457                                 Assert.AreEqual (0, s2.Length, "Length-2");
458                         } finally {
459                                 Marshal.FreeCoTaskMem (ptr);
460                         }
461                 }
462
463                 [Test]
464                 public void StringToCoTaskMemAutoWithNullValues ()
465                 {
466                         int size = 128;
467                         string s = String.Empty.PadLeft (size, '\0');
468                         Assert.AreEqual (size, s.Length, "Length-1");
469
470                         IntPtr ptr = Marshal.StringToCoTaskMemAuto (s);
471                         try {
472                                 for (int i = 0; i < size; i += 4)
473                                         Marshal.WriteInt32 (ptr, i, 0);
474
475                                 string s2 = Marshal.PtrToStringAuto (ptr);
476                                 Assert.AreEqual (0, s2.Length, "Length-2");
477                         } finally {
478                                 Marshal.FreeCoTaskMem (ptr);
479                         }
480                 }
481
482                 [Test]
483                 public void StringToCoTaskMemUniWithNullValues ()
484                 {
485                         int size = 128;
486                         string s = String.Empty.PadLeft (size, '\0');
487                         Assert.AreEqual (size, s.Length, "Length-1");
488
489                         IntPtr ptr = Marshal.StringToCoTaskMemUni (s);
490                         try {
491                                 for (int i = 0; i < size; i += 4)
492                                         Marshal.WriteInt32 (ptr, i, 0);
493
494                                 string s2 = Marshal.PtrToStringUni (ptr);
495                                 Assert.AreEqual (0, s2.Length, "Length-2");
496                         } finally {
497                                 Marshal.FreeCoTaskMem (ptr);
498                         }
499                 }
500 #if NET_2_0
501                 private const string NotSupported = "Not supported before Windows 2000 Service Pack 3";
502                 private static char[] PlainText = new char[] { 'a', 'b', 'c' };
503                 private static byte[] AsciiPlainText = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c' };
504
505                 private unsafe SecureString GetSecureString ()
506                 {
507                         fixed (char* p = &PlainText[0]) {
508                                 return new SecureString (p, PlainText.Length);
509                         }
510                 }
511
512                 [Test]
513                 public void SecureStringToBSTR_Null ()
514                 {
515                         try {
516                                 Marshal.SecureStringToBSTR (null);
517                                 Assert.Fail ("#1");
518                         } catch (ArgumentNullException ex) {
519                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
520                                 Assert.IsNull (ex.InnerException, "#3");
521                                 Assert.IsNotNull (ex.Message, "#4");
522                                 Assert.AreEqual ("s", ex.ParamName, "#5");
523                         }
524                 }
525
526                 [Test]
527                 public void SecureStringToBSTR ()
528                 {
529                         try {
530                                 SecureString ss = GetSecureString ();
531                                 IntPtr p = Marshal.SecureStringToBSTR (ss);
532
533                                 char[] decrypted = new char[ss.Length];
534                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
535                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
536
537                                 Marshal.ZeroFreeBSTR (p);
538                         } catch (NotSupportedException) {
539                                 Assert.Ignore (NotSupported);
540                         }
541                 }
542
543                 [Test]
544                 public void SecureStringToCoTaskMemAnsi_Null ()
545                 {
546                         try {
547                                 Marshal.SecureStringToCoTaskMemAnsi (null);
548                                 Assert.Fail ("#1");
549                         } catch (ArgumentNullException ex) {
550                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
551                                 Assert.IsNull (ex.InnerException, "#3");
552                                 Assert.IsNotNull (ex.Message, "#4");
553                                 Assert.AreEqual ("s", ex.ParamName, "#5");
554                         }
555                 }
556
557                 [Test]
558                 public void SecureStringToCoTaskMemAnsi ()
559                 {
560                         try {
561                                 SecureString ss = GetSecureString ();
562                                 IntPtr p = Marshal.SecureStringToCoTaskMemAnsi (ss);
563
564                                 byte[] decrypted = new byte[ss.Length];
565                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
566                                 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
567
568                                 Marshal.ZeroFreeCoTaskMemAnsi (p);
569                         } catch (NotSupportedException) {
570                                 Assert.Ignore (NotSupported);
571                         }
572                 }
573
574                 [Test]
575                 public void SecureStringToCoTaskMemUnicode_Null ()
576                 {
577                         try {
578                                 Marshal.SecureStringToCoTaskMemUnicode (null);
579                                 Assert.Fail ("#1");
580                         } catch (ArgumentNullException ex) {
581                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
582                                 Assert.IsNull (ex.InnerException, "#3");
583                                 Assert.IsNotNull (ex.Message, "#4");
584                                 Assert.AreEqual ("s", ex.ParamName, "#5");
585                         }
586                 }
587
588                 [Test]
589                 public void SecureStringToCoTaskMemUnicode ()
590                 {
591                         try {
592                                 SecureString ss = GetSecureString ();
593                                 IntPtr p = Marshal.SecureStringToCoTaskMemUnicode (ss);
594
595                                 char[] decrypted = new char[ss.Length];
596                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
597                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
598
599                                 Marshal.ZeroFreeCoTaskMemUnicode (p);
600                         } catch (NotSupportedException) {
601                                 Assert.Ignore (NotSupported);
602                         }
603                 }
604
605                 [Test]
606                 public void SecureStringToGlobalAllocAnsi_Null ()
607                 {
608                         try {
609                                 Marshal.SecureStringToGlobalAllocAnsi (null);
610                                 Assert.Fail ("#1");
611                         } catch (ArgumentNullException ex) {
612                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
613                                 Assert.IsNull (ex.InnerException, "#3");
614                                 Assert.IsNotNull (ex.Message, "#4");
615                                 Assert.AreEqual ("s", ex.ParamName, "#5");
616                         }
617                 }
618
619                 [Test]
620                 public void SecureStringToGlobalAllocAnsi ()
621                 {
622                         try {
623                                 SecureString ss = GetSecureString ();
624                                 IntPtr p = Marshal.SecureStringToGlobalAllocAnsi (ss);
625
626                                 byte[] decrypted = new byte[ss.Length];
627                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
628                                 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
629
630                                 Marshal.ZeroFreeGlobalAllocAnsi (p);
631                         } catch (NotSupportedException) {
632                                 Assert.Ignore (NotSupported);
633                         }
634                 }
635
636                 [Test]
637                 public void SecureStringToGlobalAllocUnicode_Null ()
638                 {
639                         try {
640                                 Marshal.SecureStringToGlobalAllocUnicode (null);
641                                 Assert.Fail ("#1");
642                         } catch (ArgumentNullException ex) {
643                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
644                                 Assert.IsNull (ex.InnerException, "#3");
645                                 Assert.IsNotNull (ex.Message, "#4");
646                                 Assert.AreEqual ("s", ex.ParamName, "#5");
647                         }
648                 }
649
650                 [Test]
651                 public void SecureStringToGlobalAllocUnicode ()
652                 {
653                         try {
654                                 SecureString ss = GetSecureString ();
655                                 IntPtr p = Marshal.SecureStringToGlobalAllocUnicode (ss);
656
657                                 char[] decrypted = new char[ss.Length];
658                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
659                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
660
661                                 Marshal.ZeroFreeGlobalAllocUnicode (p);
662                         } catch (NotSupportedException) {
663                                 Assert.Ignore (NotSupported);
664                         }
665                 }
666 #endif
667
668 #if !NET_2_1
669                 [Test]
670                 public void TestGetComSlotForMethodInfo ()
671                 {
672                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing")));
673                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing")));
674                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo (typeof(ITestDefault).GetMethod ("DoNothing")));
675                         Assert.AreEqual (3, Marshal.GetComSlotForMethodInfo (typeof(ITestUnknown).GetMethod ("DoNothing")));
676
677                         for (int i = 0; i < 10; i++)
678                                 Assert.AreEqual (7+i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod ("Method"+i.ToString())));
679                 }
680
681                 [Test]
682                 public void TestGetComSlotForMethod_Method_Null ()
683                 {
684                         try {
685                                 Marshal.GetComSlotForMethodInfo (null);
686                                 Assert.Fail ("#1");
687                         } catch (ArgumentNullException ex) {
688                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
689                                 Assert.IsNull (ex.InnerException, "#3");
690                                 Assert.IsNotNull (ex.Message, "#4");
691                                 Assert.AreEqual ("m", ex.ParamName, "#5");
692                         }
693                 }
694
695                 [Test]
696                 public void TestGetComSlotForMethodInfo_Method_NotOnInterface ()
697                 {
698                         MethodInfo m = typeof(TestCoClass).GetMethod ("DoNothing");
699                         try {
700                                 Marshal.GetComSlotForMethodInfo (m);
701                                 Assert.Fail ("#1");
702                         } catch (ArgumentException ex) {
703                                 // The MemberInfo must be an interface method
704                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
705                                 Assert.IsNull (ex.InnerException, "#3");
706                                 Assert.IsNotNull (ex.Message, "#4");
707                                 Assert.AreEqual ("m", ex.ParamName, "#5");
708                         }
709                 }
710 #endif
711                 [Test]
712                 public void TestPtrToStringAuto ()
713                 {
714                         string input = Guid.NewGuid ().ToString ();
715                         string output;
716                         string output2;
717                         int len = 4;
718                         IntPtr ptr;
719
720                         if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
721                                 // Auto -> Uni
722                                 ptr = Marshal.StringToHGlobalAuto (input);
723                                 output = Marshal.PtrToStringUni (ptr);
724                                 output2 = Marshal.PtrToStringUni (ptr, len);
725                         } else {
726                                 // Auto -> Ansi
727                                 ptr = Marshal.StringToHGlobalAuto (input);
728                                 output = Marshal.PtrToStringAnsi (ptr);
729                                 output2 = Marshal.PtrToStringAnsi (ptr, len);
730                         }
731
732                         try {
733                                 Assert.AreEqual (input, output, "#1");
734                                 Assert.AreEqual (input.Substring (0, len), output2, "#2");
735                         } finally {
736                                 Marshal.FreeHGlobal (ptr);
737                         }
738                 }
739 #if !MOBILE
740                 [Test]
741                 public void TestGenerateProgIdForType()
742                 {
743                         string output;
744                         
745                         output = Marshal.GenerateProgIdForType(typeof(TestCoClass));
746                         Assert.AreEqual ("MonoTests.System.Runtime.InteropServices.TestCoClass", output, "#1");
747                         
748                         output = Marshal.GenerateProgIdForType(typeof(TestCoClassWithProgId));
749                         Assert.AreEqual ("CoClassWithProgId", output, "#2");
750                 }
751 #endif
752                 [Test]
753                 public void TestGlobalAlloc ()
754                 {
755                         IntPtr mem = Marshal.AllocHGlobal (100);
756                         mem = Marshal.ReAllocHGlobal (mem, (IntPtr) 1000000);
757                         Marshal.FreeHGlobal (mem);
758                 }
759                 
760                 [Test]
761                 public void FreeHGlobal ()
762                 {
763                         // clear user doubts on assistly #6749
764                         for (int i = 0; i < 1024; i++) {
765                                 IntPtr p = Marshal.AllocHGlobal (1024 * 1024);
766                                 Assert.AreNotEqual (IntPtr.Zero, p, i.ToString ());
767                                 Marshal.FreeHGlobal (p);
768                         }
769                 }
770
771                 [StructLayout (LayoutKind.Sequential)]
772                 public struct SimpleStruct2 {
773                         public int a;
774                         public int b;
775                 }
776
777                 [Test]
778                 public void PtrToStructureNull ()
779                 {
780                         Assert.IsNull (Marshal.PtrToStructure (IntPtr.Zero, typeof (SimpleStruct2)));
781                 }
782                 
783 #if NET_2_0
784                 [Test]
785                 public void TestGetExceptionForHR ()
786                 {
787                         const int E_OUTOFMEMORY = unchecked ((int) 0x8007000E);
788                         const int E_INVALIDARG = unchecked ((int) 0X80070057);
789                         
790                         Exception ex = Marshal.GetExceptionForHR (E_OUTOFMEMORY);
791                         Assert.AreEqual (typeof (OutOfMemoryException), ex.GetType (), "E_OUTOFMEMORY");
792                         
793                         ex = Marshal.GetExceptionForHR (E_INVALIDARG);
794                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "E_INVALIDARG");
795                 }
796 #endif
797                 bool RunningOnUnix {
798                         get {
799                                 int p = (int) Environment.OSVersion.Platform;
800                                 return ((p == 4) || (p == 128) || (p == 6));
801                         }
802                 }
803
804                 [DllImport ("kernel32.dll", SetLastError = true)]
805                 [PreserveSig]
806                 static extern uint GetModuleFileName (
807                         [In]
808                         IntPtr hModule,
809                         [Out]
810                         StringBuilder lpFilename,
811                         [In]
812                         [MarshalAs (UnmanagedType.U4)]
813                         int nSize
814                 );
815         }
816 #if !NET_2_1
817         [ComImport()]
818         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
819         interface ITestDefault
820         {
821                 void DoNothing ();
822         }
823
824         [ComImport()]
825         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
826         [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
827         interface ITestDispatch
828         {
829                 void DoNothing ();
830         }
831
832         [ComImport()]
833         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
834         [InterfaceType(ComInterfaceType.InterfaceIsDual)]
835         interface ITestDual
836         {
837                 void DoNothing ();
838         }
839
840         [ComImport()]
841         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
842         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
843         interface ITestUnknown
844         {
845                 void DoNothing ();
846         }
847
848         [ComImport()]
849         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
850         interface ITestInterface
851         {
852                 void Method0 ();
853                 void Method1 ();
854                 void Method2 ();
855                 void Method3 ();
856                 void Method4 ();
857                 void Method5 ();
858                 void Method6 ();
859                 void Method7 ();
860                 void Method8 ();
861                 void Method9 ();
862         }
863
864         public class TestCoClass : ITestDispatch
865         {
866                 public void DoNothing ()
867                 {
868                 }
869         }
870
871         [ProgId("CoClassWithProgId")]
872         public class TestCoClassWithProgId : ITestDispatch
873         {
874                 public void DoNothing ()
875                 {
876                 }
877         }
878 #endif
879 }