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