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