[corlib] Fixed StringBuilder construction bugs in marshalling caused by changes to...
[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                 public 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                 public struct Foo {
177                         public int a;
178                         public static int b;
179                         public long c;
180                         public static char d;
181                         public 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                 private const string NotSupported = "Not supported before Windows 2000 Service Pack 3";
501                 private static char[] PlainText = new char[] { 'a', 'b', 'c' };
502                 private static byte[] AsciiPlainText = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c' };
503
504                 private unsafe SecureString GetSecureString ()
505                 {
506                         fixed (char* p = &PlainText[0]) {
507                                 return new SecureString (p, PlainText.Length);
508                         }
509                 }
510
511                 [Test]
512                 public void SecureStringToBSTR_Null ()
513                 {
514                         try {
515                                 Marshal.SecureStringToBSTR (null);
516                                 Assert.Fail ("#1");
517                         } catch (ArgumentNullException ex) {
518                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
519                                 Assert.IsNull (ex.InnerException, "#3");
520                                 Assert.IsNotNull (ex.Message, "#4");
521                                 Assert.AreEqual ("s", ex.ParamName, "#5");
522                         }
523                 }
524
525                 [Test]
526                 public void SecureStringToBSTR ()
527                 {
528                         try {
529                                 SecureString ss = GetSecureString ();
530                                 IntPtr p = Marshal.SecureStringToBSTR (ss);
531
532                                 char[] decrypted = new char[ss.Length];
533                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
534                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
535
536                                 Marshal.ZeroFreeBSTR (p);
537                         } catch (NotSupportedException) {
538                                 Assert.Ignore (NotSupported);
539                         }
540                 }
541
542                 [Test]
543                 public void SecureStringToCoTaskMemAnsi_Null ()
544                 {
545                         try {
546                                 Marshal.SecureStringToCoTaskMemAnsi (null);
547                                 Assert.Fail ("#1");
548                         } catch (ArgumentNullException ex) {
549                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
550                                 Assert.IsNull (ex.InnerException, "#3");
551                                 Assert.IsNotNull (ex.Message, "#4");
552                                 Assert.AreEqual ("s", ex.ParamName, "#5");
553                         }
554                 }
555
556                 [Test]
557                 public void SecureStringToCoTaskMemAnsi ()
558                 {
559                         try {
560                                 SecureString ss = GetSecureString ();
561                                 IntPtr p = Marshal.SecureStringToCoTaskMemAnsi (ss);
562
563                                 byte[] decrypted = new byte[ss.Length];
564                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
565                                 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
566
567                                 Marshal.ZeroFreeCoTaskMemAnsi (p);
568                         } catch (NotSupportedException) {
569                                 Assert.Ignore (NotSupported);
570                         }
571                 }
572
573                 [Test]
574                 public void SecureStringToCoTaskMemUnicode_Null ()
575                 {
576                         try {
577                                 Marshal.SecureStringToCoTaskMemUnicode (null);
578                                 Assert.Fail ("#1");
579                         } catch (ArgumentNullException ex) {
580                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
581                                 Assert.IsNull (ex.InnerException, "#3");
582                                 Assert.IsNotNull (ex.Message, "#4");
583                                 Assert.AreEqual ("s", ex.ParamName, "#5");
584                         }
585                 }
586
587                 [Test]
588                 public void SecureStringToCoTaskMemUnicode ()
589                 {
590                         try {
591                                 SecureString ss = GetSecureString ();
592                                 IntPtr p = Marshal.SecureStringToCoTaskMemUnicode (ss);
593
594                                 char[] decrypted = new char[ss.Length];
595                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
596                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
597
598                                 Marshal.ZeroFreeCoTaskMemUnicode (p);
599                         } catch (NotSupportedException) {
600                                 Assert.Ignore (NotSupported);
601                         }
602                 }
603
604                 [Test]
605                 public void SecureStringToGlobalAllocAnsi_Null ()
606                 {
607                         try {
608                                 Marshal.SecureStringToGlobalAllocAnsi (null);
609                                 Assert.Fail ("#1");
610                         } catch (ArgumentNullException ex) {
611                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
612                                 Assert.IsNull (ex.InnerException, "#3");
613                                 Assert.IsNotNull (ex.Message, "#4");
614                                 Assert.AreEqual ("s", ex.ParamName, "#5");
615                         }
616                 }
617
618                 [Test]
619                 public void SecureStringToGlobalAllocAnsi ()
620                 {
621                         try {
622                                 SecureString ss = GetSecureString ();
623                                 IntPtr p = Marshal.SecureStringToGlobalAllocAnsi (ss);
624
625                                 byte[] decrypted = new byte[ss.Length];
626                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
627                                 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
628
629                                 Marshal.ZeroFreeGlobalAllocAnsi (p);
630                         } catch (NotSupportedException) {
631                                 Assert.Ignore (NotSupported);
632                         }
633                 }
634
635                 [Test]
636                 public void SecureStringToGlobalAllocUnicode_Null ()
637                 {
638                         try {
639                                 Marshal.SecureStringToGlobalAllocUnicode (null);
640                                 Assert.Fail ("#1");
641                         } catch (ArgumentNullException ex) {
642                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
643                                 Assert.IsNull (ex.InnerException, "#3");
644                                 Assert.IsNotNull (ex.Message, "#4");
645                                 Assert.AreEqual ("s", ex.ParamName, "#5");
646                         }
647                 }
648
649                 [Test]
650                 public void SecureStringToGlobalAllocUnicode ()
651                 {
652                         try {
653                                 SecureString ss = GetSecureString ();
654                                 IntPtr p = Marshal.SecureStringToGlobalAllocUnicode (ss);
655
656                                 char[] decrypted = new char[ss.Length];
657                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
658                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
659
660                                 Marshal.ZeroFreeGlobalAllocUnicode (p);
661                         } catch (NotSupportedException) {
662                                 Assert.Ignore (NotSupported);
663                         }
664                 }
665
666 #if !NET_2_1
667                 [Test]
668                 public void TestGetComSlotForMethodInfo ()
669                 {
670                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing")));
671                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing")));
672                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo (typeof(ITestDefault).GetMethod ("DoNothing")));
673                         Assert.AreEqual (3, Marshal.GetComSlotForMethodInfo (typeof(ITestUnknown).GetMethod ("DoNothing")));
674
675                         for (int i = 0; i < 10; i++)
676                                 Assert.AreEqual (7+i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod ("Method"+i.ToString())));
677                 }
678
679                 [Test]
680                 public void TestGetComSlotForMethod_Method_Null ()
681                 {
682                         try {
683                                 Marshal.GetComSlotForMethodInfo (null);
684                                 Assert.Fail ("#1");
685                         } catch (ArgumentNullException ex) {
686                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
687                                 Assert.IsNull (ex.InnerException, "#3");
688                                 Assert.IsNotNull (ex.Message, "#4");
689                                 Assert.AreEqual ("m", ex.ParamName, "#5");
690                         }
691                 }
692
693                 [Test]
694                 public void TestGetComSlotForMethodInfo_Method_NotOnInterface ()
695                 {
696                         MethodInfo m = typeof(TestCoClass).GetMethod ("DoNothing");
697                         try {
698                                 Marshal.GetComSlotForMethodInfo (m);
699                                 Assert.Fail ("#1");
700                         } catch (ArgumentException ex) {
701                                 // The MemberInfo must be an interface method
702                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
703                                 Assert.IsNull (ex.InnerException, "#3");
704                                 Assert.IsNotNull (ex.Message, "#4");
705                                 Assert.AreEqual ("m", ex.ParamName, "#5");
706                         }
707                 }
708 #endif
709                 [Test]
710                 public void TestPtrToStringAuto ()
711                 {
712                         string input = Guid.NewGuid ().ToString ();
713                         string output;
714                         string output2;
715                         int len = 4;
716                         IntPtr ptr;
717
718                         if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
719                                 // Auto -> Uni
720                                 ptr = Marshal.StringToHGlobalAuto (input);
721                                 output = Marshal.PtrToStringUni (ptr);
722                                 output2 = Marshal.PtrToStringUni (ptr, len);
723                         } else {
724                                 // Auto -> Ansi
725                                 ptr = Marshal.StringToHGlobalAuto (input);
726                                 output = Marshal.PtrToStringAnsi (ptr);
727                                 output2 = Marshal.PtrToStringAnsi (ptr, len);
728                         }
729
730                         try {
731                                 Assert.AreEqual (input, output, "#1");
732                                 Assert.AreEqual (input.Substring (0, len), output2, "#2");
733                         } finally {
734                                 Marshal.FreeHGlobal (ptr);
735                         }
736                 }
737 #if !MOBILE
738                 [Test]
739                 public void TestGenerateProgIdForType()
740                 {
741                         string output;
742                         
743                         output = Marshal.GenerateProgIdForType(typeof(TestCoClass));
744                         Assert.AreEqual ("MonoTests.System.Runtime.InteropServices.TestCoClass", output, "#1");
745                         
746                         output = Marshal.GenerateProgIdForType(typeof(TestCoClassWithProgId));
747                         Assert.AreEqual ("CoClassWithProgId", output, "#2");
748                 }
749 #endif
750                 [Test]
751                 public void TestGlobalAlloc ()
752                 {
753                         IntPtr mem = Marshal.AllocHGlobal (100);
754                         mem = Marshal.ReAllocHGlobal (mem, (IntPtr) 1000000);
755                         Marshal.FreeHGlobal (mem);
756                 }
757                 
758                 [Test]
759                 public void FreeHGlobal ()
760                 {
761                         // clear user doubts on assistly #6749
762                         for (int i = 0; i < 1024; i++) {
763                                 IntPtr p = Marshal.AllocHGlobal (1024 * 1024);
764                                 Assert.AreNotEqual (IntPtr.Zero, p, i.ToString ());
765                                 Marshal.FreeHGlobal (p);
766                         }
767                 }
768
769                 [StructLayout (LayoutKind.Sequential)]
770                 public struct SimpleStruct2 {
771                         public int a;
772                         public int b;
773                 }
774
775                 [Test]
776                 public void PtrToStructureNull ()
777                 {
778                         Assert.IsNull (Marshal.PtrToStructure (IntPtr.Zero, typeof (SimpleStruct2)));
779                 }
780                 
781                 [Test]
782                 public void TestGetExceptionForHR ()
783                 {
784                         const int E_OUTOFMEMORY = unchecked ((int) 0x8007000E);
785                         const int E_INVALIDARG = unchecked ((int) 0X80070057);
786                         
787                         Exception ex = Marshal.GetExceptionForHR (E_OUTOFMEMORY);
788                         Assert.AreEqual (typeof (OutOfMemoryException), ex.GetType (), "E_OUTOFMEMORY");
789                         
790                         ex = Marshal.GetExceptionForHR (E_INVALIDARG);
791                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "E_INVALIDARG");
792                 }
793                 bool RunningOnUnix {
794                         get {
795                                 int p = (int) Environment.OSVersion.Platform;
796                                 return ((p == 4) || (p == 128) || (p == 6));
797                         }
798                 }
799
800                 [DllImport ("kernel32.dll", SetLastError = true)]
801                 [PreserveSig]
802                 static extern uint GetModuleFileName (
803                         [In]
804                         IntPtr hModule,
805                         [Out]
806                         StringBuilder lpFilename,
807                         [In]
808                         [MarshalAs (UnmanagedType.U4)]
809                         int nSize
810                 );
811         }
812 #if !NET_2_1
813         [ComImport()]
814         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
815         interface ITestDefault
816         {
817                 void DoNothing ();
818         }
819
820         [ComImport()]
821         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
822         [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
823         interface ITestDispatch
824         {
825                 void DoNothing ();
826         }
827
828         [ComImport()]
829         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
830         [InterfaceType(ComInterfaceType.InterfaceIsDual)]
831         interface ITestDual
832         {
833                 void DoNothing ();
834         }
835
836         [ComImport()]
837         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
838         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
839         interface ITestUnknown
840         {
841                 void DoNothing ();
842         }
843
844         [ComImport()]
845         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
846         interface ITestInterface
847         {
848                 void Method0 ();
849                 void Method1 ();
850                 void Method2 ();
851                 void Method3 ();
852                 void Method4 ();
853                 void Method5 ();
854                 void Method6 ();
855                 void Method7 ();
856                 void Method8 ();
857                 void Method9 ();
858         }
859
860         public class TestCoClass : ITestDispatch
861         {
862                 public void DoNothing ()
863                 {
864                 }
865         }
866
867         [ProgId("CoClassWithProgId")]
868         public class TestCoClassWithProgId : ITestDispatch
869         {
870                 public void DoNothing ()
871                 {
872                 }
873         }
874 #endif
875 }