some tests comment out for target_jvm
[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-2006 Novell, Inc (http://www.novell.com)
9 //
10 #if !TARGET_JVM
11 using NUnit.Framework;
12 using System;
13 using System.Runtime.InteropServices;
14 using System.Security;
15
16 namespace MonoTests.System.Runtime.InteropServices
17 {
18         [TestFixture]
19         public class MarshalTest
20         {
21                 [StructLayout (LayoutKind.Sequential)]
22                 class ClsSequential {
23                         public int field;
24                 }
25
26                 class ClsNoLayout {
27                         public int field;
28                 }
29
30                 [StructLayout (LayoutKind.Explicit)]
31                 class ClsExplicit {
32                         [FieldOffset (0)] public int field;
33                 }
34
35                 [StructLayout (LayoutKind.Sequential)]
36                 struct StrSequential {
37                         public int field;
38                 }
39
40                 struct StrNoLayout {
41                         public int field;
42                 }
43
44                 [StructLayout (LayoutKind.Explicit)]
45                 struct StrExplicit {
46                         [FieldOffset (0)] public int field;
47                 }
48
49                 [Test]
50                 public void ClassSequential ()
51                 {
52                         Marshal.SizeOf (typeof (ClsSequential));
53                 }
54
55                 [Test]
56                 [ExpectedException (typeof (ArgumentException))]
57                 public void ClassNoLayout ()
58                 {
59                         Marshal.SizeOf (typeof (ClsNoLayout));
60                 }
61
62                 [Test]
63                 public void ClassExplicit ()
64                 {
65                         Marshal.SizeOf (typeof (ClsExplicit));
66                 }
67
68                 [Test]
69                 public void StructSequential ()
70                 {
71                         Marshal.SizeOf (typeof (StrSequential));
72                 }
73
74                 [Test]
75                 public void StructNoLayout ()
76                 {
77                         Marshal.SizeOf (typeof (StrNoLayout));
78                 }
79
80                 [Test]
81                 public void StructExplicit ()
82                 {
83                         Marshal.SizeOf (typeof (StrExplicit));
84                 }
85
86                 [Test]
87                 [ExpectedException (typeof (ArgumentException))]
88                 public void ArrayType ()
89                 {
90                         Marshal.SizeOf (typeof (string[]));
91                 }
92
93                 [Test]
94                 public void PtrToStringWithNull ()
95                 {
96                         Assert.IsNull (Marshal.PtrToStringAnsi (IntPtr.Zero), "A");
97                         Assert.IsNull (Marshal.PtrToStringUni (IntPtr.Zero), "C");
98                 }
99
100                 [Test]
101                 [ExpectedException (typeof (ArgumentNullException))]
102                 public void PtrToStringWithNullThrow ()
103                 {
104                         Assert.IsNull (Marshal.PtrToStringAnsi (IntPtr.Zero, 0), "B");
105                 }
106
107                 [Test]
108                 [ExpectedException (typeof (ArgumentNullException))]
109                 public void PtrToStringWithNullThrow2 ()
110                 {
111                         Assert.IsNull (Marshal.PtrToStringUni (IntPtr.Zero, 0), "D");
112                 }
113
114                 [Test]
115                 public unsafe void UnsafeAddrOfPinnedArrayElement () {
116                         short[] sarr = new short [5];
117                         sarr [2] = 3;
118
119                         IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement (sarr, 2);
120                         Assert.AreEqual (3, *(short*)ptr.ToPointer ());
121                 }
122
123                 [Test]
124                 public void AllocHGlobalZeroSize () {
125                         IntPtr ptr = Marshal.AllocHGlobal (0);
126                         Assert.IsTrue (ptr != IntPtr.Zero);
127                         Marshal.FreeHGlobal (ptr);
128                 }
129
130                 struct Foo {
131                         int a;
132                         static int b;
133                         long c;
134                         static char d;
135                         int e;
136                 }
137
138                 [Test]
139                 [ExpectedException (typeof (ArgumentException))]
140                 public void OffsetOfStatic () {
141                         Marshal.OffsetOf (typeof (Foo), "b");
142                 }
143
144                 // bug #76123
145                 [Test]
146                 public void StringToHGlobalUni () {
147                         IntPtr handle = Marshal.StringToHGlobalUni ("unicode data");
148                         string s = Marshal.PtrToStringUni (handle);
149                         Assert.AreEqual (12, s.Length, "#1");
150
151                         handle = Marshal.StringToHGlobalUni ("unicode data string");
152                         s = Marshal.PtrToStringUni (handle);
153                         Assert.AreEqual (19, s.Length, "#2");
154                 }
155
156                 [Test]
157                 public void ReadInt32_Endian ()
158                 {
159                         IntPtr ptr = Marshal.AllocHGlobal (4);
160                         try {
161                                 Marshal.WriteByte (ptr, 0, 0x01);
162                                 Marshal.WriteByte (ptr, 1, 0x02);
163                                 Marshal.WriteByte (ptr, 2, 0x03);
164                                 Marshal.WriteByte (ptr, 3, 0x04);
165                                 // Marshal MUST use the native CPU data
166                                 if (BitConverter.IsLittleEndian){
167                                         Assert.AreEqual (0x04030201, Marshal.ReadInt32 (ptr), "ReadInt32");
168                                 } else {
169                                         Assert.AreEqual (0x01020304, Marshal.ReadInt32 (ptr), "ReadInt32");
170                                 }
171                         }
172                         finally {
173                                 Marshal.FreeHGlobal (ptr);
174                         }
175                 }
176
177 #if NET_2_0
178                 private const string NotSupported = "Not supported before Windows 2000 Service Pack 3";
179                 private static char[] PlainText = new char[] { 'a', 'b', 'c' };
180                 private static byte[] AsciiPlainText = new byte[] { (byte) 'a', (byte) 'b', (byte) 'c' };
181
182                 private unsafe SecureString GetSecureString ()
183                 {
184                         fixed (char* p = &PlainText[0]) {
185                                 return new SecureString (p, PlainText.Length);
186                         }
187                 }
188
189                 [Test]
190                 [ExpectedException (typeof (ArgumentNullException))]
191                 public void SecureStringToBSTR_Null ()
192                 {
193                         Marshal.SecureStringToBSTR (null);
194                 }
195
196                 [Test]
197                 public void SecureStringToBSTR ()
198                 {
199                         try {
200                                 SecureString ss = GetSecureString ();
201                                 IntPtr p = Marshal.SecureStringToBSTR (ss);
202
203                                 char[] decrypted = new char[ss.Length];
204                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
205                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
206
207                                 Marshal.ZeroFreeBSTR (p);
208                         }
209                         catch (NotSupportedException) {
210                                 Assert.Ignore (NotSupported);
211                         }
212                 }
213
214                 [Test]
215                 [ExpectedException (typeof (ArgumentNullException))]
216                 public void SecureStringToCoTaskMemAnsi_Null ()
217                 {
218                         Marshal.SecureStringToCoTaskMemAnsi (null);
219                 }
220
221                 [Test]
222                 public void SecureStringToCoTaskMemAnsi ()
223                 {
224                         try {
225                                 SecureString ss = GetSecureString ();
226                                 IntPtr p = Marshal.SecureStringToCoTaskMemAnsi (ss);
227
228                                 byte[] decrypted = new byte[ss.Length];
229                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
230                                 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
231
232                                 Marshal.ZeroFreeCoTaskMemAnsi (p);
233                         }
234                         catch (NotSupportedException) {
235                                 Assert.Ignore (NotSupported);
236                         }
237                 }
238
239                 [Test]
240                 [ExpectedException (typeof (ArgumentNullException))]
241                 public void SecureStringToCoTaskMemUnicode_Null ()
242                 {
243                         Marshal.SecureStringToCoTaskMemUnicode (null);
244                 }
245
246                 [Test]
247                 public void SecureStringToCoTaskMemUnicode ()
248                 {
249                         try {
250                                 SecureString ss = GetSecureString ();
251                                 IntPtr p = Marshal.SecureStringToCoTaskMemUnicode (ss);
252
253                                 char[] decrypted = new char[ss.Length];
254                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
255                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
256
257                                 Marshal.ZeroFreeCoTaskMemUnicode (p);
258                         }
259                         catch (NotSupportedException) {
260                                 Assert.Ignore (NotSupported);
261                         }
262                 }
263
264                 [Test]
265                 [ExpectedException (typeof (ArgumentNullException))]
266                 public void SecureStringToGlobalAllocAnsi_Null ()
267                 {
268                         Marshal.SecureStringToGlobalAllocAnsi (null);
269                 }
270
271                 [Test]
272                 public void SecureStringToGlobalAllocAnsi ()
273                 {
274                         try {
275                                 SecureString ss = GetSecureString ();
276                                 IntPtr p = Marshal.SecureStringToGlobalAllocAnsi (ss);
277
278                                 byte[] decrypted = new byte[ss.Length];
279                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
280                                 Assert.AreEqual (AsciiPlainText, decrypted, "Decrypted");
281
282                                 Marshal.ZeroFreeGlobalAllocAnsi (p);
283                         }
284                         catch (NotSupportedException) {
285                                 Assert.Ignore (NotSupported);
286                         }
287                 }
288
289                 [Test]
290                 [ExpectedException (typeof (ArgumentNullException))]
291                 public void SecureStringToGlobalAllocUnicode_Null ()
292                 {
293                         Marshal.SecureStringToGlobalAllocUnicode (null);
294                 }
295
296                 [Test]
297                 public void SecureStringToGlobalAllocUnicode ()
298                 {
299                         try {
300                                 SecureString ss = GetSecureString ();
301                                 IntPtr p = Marshal.SecureStringToGlobalAllocUnicode (ss);
302
303                                 char[] decrypted = new char[ss.Length];
304                                 Marshal.Copy (p, decrypted, 0, decrypted.Length);
305                                 Assert.AreEqual (PlainText, decrypted, "Decrypted");
306
307                                 Marshal.ZeroFreeGlobalAllocUnicode (p);
308                         }
309                         catch (NotSupportedException) {
310                                 Assert.Ignore (NotSupported);
311                         }
312                 }
313 #endif
314
315                 [Test]
316                 public void TestGetComSlotForMethodInfo ()
317                 {
318                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDefault).GetMethod("DoNothing")));
319                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo(typeof(ITestDual).GetMethod("DoNothing")));
320                         Assert.AreEqual (7, Marshal.GetComSlotForMethodInfo (typeof(ITestDefault).GetMethod ("DoNothing")));
321                         Assert.AreEqual (3, Marshal.GetComSlotForMethodInfo (typeof(ITestUnknown).GetMethod ("DoNothing")));
322
323                         for (int i = 0; i < 10; i++)
324                                 Assert.AreEqual (7+i, Marshal.GetComSlotForMethodInfo(typeof(ITestInterface).GetMethod ("Method"+i.ToString())));
325                 }
326
327                 [Test]
328                 [ExpectedException(typeof(ArgumentNullException))]
329                 public void TestGetComSlotForMethodInfoNullException()
330                 {
331                         Marshal.GetComSlotForMethodInfo (null);
332                 }
333
334                 [Test]
335                 [ExpectedException(typeof(ArgumentException))]
336                 public void TestGetComSlotForMethodInfoArgumentException2 ()
337                 {
338                         Marshal.GetComSlotForMethodInfo (typeof(TestCoClass).GetMethod ("DoNothing"));
339                 }
340
341                 [Test]
342                 public void TestPtrToStringAuto ()
343                 {
344                         string input = Guid.NewGuid ().ToString ();
345                         string output;
346                         string output2;
347                         int len = 4;
348                         IntPtr ptr;
349
350                         if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
351                                 // Auto -> Uni
352                                 ptr = Marshal.StringToHGlobalAuto (input);
353                                 output = Marshal.PtrToStringUni (ptr);
354                                 output2 = Marshal.PtrToStringUni (ptr, len);
355                         } else {
356                                 // Auto -> Ansi
357                                 ptr = Marshal.StringToHGlobalAuto (input);
358                                 output = Marshal.PtrToStringAnsi (ptr);
359                                 output2 = Marshal.PtrToStringAnsi (ptr, len);
360                         }
361
362                         try {
363                                 Assert.AreEqual (input, output, "#1");
364                                 Assert.AreEqual (input.Substring (0, len), output2, "#2");
365                         } finally {
366                                 Marshal.FreeHGlobal (ptr);
367                         }
368                 }
369         }
370
371         [ComImport()]
372         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
373         interface ITestDefault
374         {
375                 void DoNothing ();
376         }
377
378         [ComImport()]
379         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
380         [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
381         interface ITestDispatch
382         {
383                 void DoNothing ();
384         }
385
386         [ComImport()]
387         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
388         [InterfaceType(ComInterfaceType.InterfaceIsDual)]
389         interface ITestDual
390         {
391                 void DoNothing ();
392         }
393
394         [ComImport()]
395         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
396         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
397         interface ITestUnknown
398         {
399                 void DoNothing ();
400         }
401
402         [ComImport()]
403         [Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
404         interface ITestInterface
405         {
406                 void Method0 ();
407                 void Method1 ();
408                 void Method2 ();
409                 void Method3 ();
410                 void Method4 ();
411                 void Method5 ();
412                 void Method6 ();
413                 void Method7 ();
414                 void Method8 ();
415                 void Method9 ();
416         }
417
418         public class TestCoClass : ITestDispatch
419         {
420                 public void DoNothing ()
421                 {
422                 }
423         }
424 }
425 #endif