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