Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mono / tests / libtest.c
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <glib.h>
6 #include <gmodule.h>
7 #include <errno.h>
8 #include <time.h>
9 #include <math.h>
10
11 #ifdef WIN32
12 #include <windows.h>
13 #include "initguid.h"
14 #else
15 #include <pthread.h>
16 #endif
17
18 #ifdef WIN32
19 #define STDCALL __stdcall
20 #else
21 #define STDCALL
22 #endif
23
24 #ifdef __GNUC__
25 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
26 #endif
27
28 #ifdef WIN32
29 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
30 #endif
31
32 typedef int (STDCALL *SimpleDelegate) (int a);
33
34 #if defined(WIN32) && defined (_MSC_VER)
35 #define LIBTEST_API __declspec(dllexport)
36 #else 
37 #define LIBTEST_API
38 #endif
39
40 static void marshal_free (void *ptr)
41 {
42 #ifdef WIN32
43         CoTaskMemFree (ptr);
44 #else
45         g_free (ptr);
46 #endif
47 }
48
49 static void* marshal_alloc (gsize size)
50 {
51 #ifdef WIN32
52         return CoTaskMemAlloc (size);
53 #else
54         return g_malloc (size);
55 #endif
56 }
57
58 static void* marshal_alloc0 (gsize size)
59 {
60 #ifdef WIN32
61         void* ptr = CoTaskMemAlloc (size);
62         memset(ptr, 0, size);
63         return ptr;
64 #else
65         return g_malloc0 (size);
66 #endif
67 }
68
69 static char* marshal_strdup (const char *str)
70 {
71 #ifdef WIN32
72         int len;
73         char *buf;
74
75         if (!str)
76                 return NULL;
77
78         len = strlen (str);
79         buf = (char *) CoTaskMemAlloc (len + 1);
80         return strcpy (buf, str);
81 #else
82         return g_strdup (str);
83 #endif
84 }
85
86 static gunichar2* marshal_bstr_alloc(const gchar* str)
87 {
88 #ifdef WIN32
89         gunichar2* ret = NULL;
90         gunichar2* temp = NULL;
91         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
92         ret = SysAllocString (temp);
93         g_free (temp);
94         return ret;
95 #else
96         gchar* ret = NULL;
97         int slen = strlen (str);
98         gunichar2* temp;
99         /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
100         ret = g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
101         if (ret == NULL)
102                 return NULL;
103         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
104         memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
105         * ((guint32 *) ret) = slen * sizeof(gunichar2);
106         ret [4 + slen * sizeof(gunichar2)] = 0;
107         ret [5 + slen * sizeof(gunichar2)] = 0;
108
109         return (gunichar2*)(ret + 4);
110 #endif
111 }
112
113 #define marshal_new0(type,size)       ((type *) marshal_alloc0 (sizeof (type)* (size)))
114
115 LIBTEST_API int STDCALL
116 mono_cominterop_is_supported (void)
117 {
118 #if defined(TARGET_X86) || defined(TARGET_AMD64)
119         return 1;
120 #endif
121         return 0;
122 }
123
124 LIBTEST_API unsigned short* STDCALL
125 test_lpwstr_marshal (unsigned short* chars, long length)
126 {
127         int i = 0;
128         unsigned short *res;
129
130         res = marshal_alloc (2 * (length + 1));
131
132         // printf("test_lpwstr_marshal()\n");
133         
134         while ( i < length ) {
135                 // printf("X|%u|\n", chars[i]);
136                 res [i] = chars[i];
137                 i++;
138         }
139
140         res [i] = 0;
141
142         return res;
143 }
144
145
146 LIBTEST_API void STDCALL
147 test_lpwstr_marshal_out (unsigned short** chars)
148 {
149         int i = 0;
150         const char abc[] = "ABC";
151         glong len = strlen(abc);
152
153         *chars = marshal_alloc (2 * (len + 1));
154         
155         while ( i < len ) {
156                 (*chars) [i] = abc[i];
157                 i++;
158         }
159
160         (*chars) [i] = 0;
161 }
162
163 typedef struct {
164         int b;
165         int a;
166         int c;
167 } union_test_1_type;
168
169 LIBTEST_API int STDCALL  
170 mono_union_test_1 (union_test_1_type u1) {
171         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
172         return u1.a + u1.b + u1.c;
173 }
174
175 LIBTEST_API int STDCALL  
176 mono_return_int (int a) {
177         // printf ("Got value %d\n", a);
178         return a;
179 }
180
181 LIBTEST_API float STDCALL  
182 mono_test_marshal_pass_return_float (float f) {
183         return f + 1.0;
184 }
185
186 struct ss
187 {
188         int i;
189 };
190
191 LIBTEST_API int STDCALL 
192 mono_return_int_ss (struct ss a) {
193         // printf ("Got value %d\n", a.i);
194         return a.i;
195 }
196
197 LIBTEST_API struct ss STDCALL
198 mono_return_ss (struct ss a) {
199         // printf ("Got value %d\n", a.i);
200         a.i++;
201         return a;
202 }
203
204 struct sc1
205 {
206         char c[1];
207 };
208
209 LIBTEST_API struct sc1 STDCALL
210 mono_return_sc1 (struct sc1 a) {
211         // printf ("Got value %d\n", a.c[0]);
212         a.c[0]++;
213         return a;
214 }
215
216
217 struct sc3
218 {
219         char c[3];
220 };
221
222 LIBTEST_API struct sc3 STDCALL 
223 mono_return_sc3 (struct sc3 a) {
224         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
225         a.c[0]++;
226         a.c[1] += 2;
227         a.c[2] += 3;
228         return a;
229 }
230
231 struct sc5
232 {
233         char c[5];
234 };
235
236 LIBTEST_API struct sc5 STDCALL 
237 mono_return_sc5 (struct sc5 a) {
238         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
239         a.c[0]++;
240         a.c[1] += 2;
241         a.c[2] += 3;
242         a.c[3] += 4;
243         a.c[4] += 5;
244         return a;
245 }
246
247 union su
248 {
249         int i1;
250         int i2;
251 };
252
253 LIBTEST_API int STDCALL  
254 mono_return_int_su (union su a) {
255         // printf ("Got value %d\n", a.i1);
256         return a.i1;
257 }
258
259 LIBTEST_API int STDCALL  
260 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
261                                                           int f, int g, int h, int i, int j);
262 LIBTEST_API short STDCALL 
263 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
264                                                                 short f, short g, short h, short i, short j);
265 LIBTEST_API char STDCALL 
266 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
267                                                            char f, char g, char h, char i, char j);
268
269 LIBTEST_API int STDCALL 
270 mono_test_many_int_arguments (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
271 {
272         return a + b + c + d + e + f + g + h + i + j;
273 }
274
275 LIBTEST_API short STDCALL 
276 mono_test_many_short_arguments (short a, short b, short c, short d, short e, short f, short g, short h, short i, short j)
277 {
278         return a + b + c + d + e + f + g + h + i + j;
279 }
280
281 LIBTEST_API char STDCALL 
282 mono_test_many_byte_arguments (char a, char b, char c, char d, char e, char f, char g, char h, char i, char j)
283 {
284         return a + b + c + d + e + f + g + h + i + j;
285 }
286
287 LIBTEST_API float STDCALL 
288 mono_test_many_float_arguments (float a, float b, float c, float d, float e, float f, float g, float h, float i, float j)
289 {
290         return a + b + c + d + e + f + g + h + i + j;
291 }
292
293 LIBTEST_API double STDCALL 
294 mono_test_many_double_arguments (double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
295 {
296         return a + b + c + d + e + f + g + h + i + j;
297 }
298
299 LIBTEST_API double STDCALL 
300 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
301 {
302         return a + b + c + d + e;
303 }
304
305 LIBTEST_API int STDCALL 
306 mono_test_puts_static (char *s)
307 {
308         // printf ("TEST %s\n", s);
309         return 1;
310 }
311
312 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
313
314 LIBTEST_API int STDCALL 
315 mono_invoke_delegate (SimpleDelegate3 delegate)
316 {
317         int res;
318
319         // printf ("start invoke %p\n", delegate);
320
321         res = delegate (2, 3);
322
323         // printf ("end invoke\n");
324
325         return res;
326 }
327
328 LIBTEST_API int STDCALL
329 mono_invoke_simple_delegate (SimpleDelegate d)
330 {
331         return d (4);
332 }
333
334 LIBTEST_API int STDCALL  
335 mono_test_marshal_char (short a1)
336 {
337         if (a1 == 'a')
338                 return 0;
339         
340         return 1;
341 }
342
343 LIBTEST_API void STDCALL
344 mono_test_marshal_char_array (gunichar2 *s)
345 {
346         const char m[] = "abcdef";
347         gunichar2* s2;
348         glong len;
349
350         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
351         
352         len = (len * 2) + 2;
353         memcpy (s, s2, len);
354
355         g_free (s2);
356 }
357
358 LIBTEST_API int STDCALL
359 mono_test_marshal_ansi_char_array (char *s)
360 {
361         const char m[] = "abcdef";
362
363         if (strncmp ("qwer", s, 4))
364                 return 1;
365
366         memcpy (s, m, sizeof (m));
367         return 0;
368 }
369
370 LIBTEST_API int STDCALL
371 mono_test_marshal_unicode_char_array (gunichar2 *s)
372 {
373         const char m[] = "abcdef";
374         const char expected[] = "qwer";
375         gunichar2 *s1, *s2;
376         glong len1, len2;
377
378         s1 = g_utf8_to_utf16 (m, -1, NULL, &len1, NULL);
379         s2 = g_utf8_to_utf16 (expected, -1, NULL, &len2, NULL);
380         len1 = (len1 * 2);
381         len2 = (len2 * 2);
382
383         if (memcmp (s, s2, len2))
384                 return 1;
385
386         memcpy (s, s1, len1);
387         return 0;
388 }
389
390
391 LIBTEST_API int STDCALL 
392 mono_test_empty_pinvoke (int i)
393 {
394         return i;
395 }
396
397 LIBTEST_API int STDCALL  
398 mono_test_marshal_bool_byref (int a, int *b, int c)
399 {
400     int res = *b;
401
402         *b = 1;
403
404         return res;
405 }
406
407 LIBTEST_API int STDCALL 
408 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
409 {
410         if (!bTrue)
411                 return 1;
412         if (bFalse)
413                 return 2;
414         return 0;
415 }
416
417 LIBTEST_API int STDCALL 
418 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
419 {
420         if (!bTrue || !bFalse)
421                 return 3;
422
423         *bTrue = 1;
424         *bFalse = 0;
425
426         return 0;
427 }
428
429 LIBTEST_API int STDCALL 
430 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
431 {
432         if (!bTrue || !bFalse)
433                 return 4;
434
435         if (!(*bTrue))
436                 return 5;
437         if (*bFalse)
438                 return 6;
439
440         *bFalse = 1;
441         *bTrue = 0;
442
443         return 0;
444 }
445
446 LIBTEST_API int STDCALL  
447 mono_test_marshal_array (int *a1)
448 {
449         int i, sum = 0;
450
451         for (i = 0; i < 50; i++)
452                 sum += a1 [i];
453         
454         return sum;
455 }
456
457 LIBTEST_API int STDCALL  
458 mono_test_marshal_inout_array (int *a1)
459 {
460         int i, sum = 0;
461
462         for (i = 0; i < 50; i++) {
463                 sum += a1 [i];
464                 a1 [i] = 50 - a1 [i];
465         }
466         
467         return sum;
468 }
469
470 LIBTEST_API int /* cdecl */
471 mono_test_marshal_inout_array_cdecl (int *a1)
472 {
473         return mono_test_marshal_inout_array (a1);
474 }
475
476 LIBTEST_API int STDCALL  
477 mono_test_marshal_out_array (int *a1)
478 {
479         int i;
480
481         for (i = 0; i < 50; i++) {
482                 a1 [i] = i;
483         }
484         
485         return 0;
486 }
487
488 LIBTEST_API int STDCALL  
489 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
490 {
491         int i, sum = 0;
492
493         for (i = 0; i < 10; i++) {
494                 a1 [i] = 'F';
495         }
496         
497         return sum;
498 }
499
500 typedef struct {
501         int a;
502         int b;
503         int c;
504         const char *d;
505         gunichar2 *d2;
506 } simplestruct;
507
508 typedef struct {
509         double x;
510         double y;
511 } point;
512
513 LIBTEST_API simplestruct STDCALL 
514 mono_test_return_vtype (int i)
515 {
516         simplestruct res;
517         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
518
519         res.a = 0;
520         res.b = 1;
521         res.c = 0;
522         res.d = "TEST";
523         res.d2 = test2;
524
525         return res;
526 }
527
528 LIBTEST_API void STDCALL
529 mono_test_delegate_struct (void)
530 {
531         // printf ("TEST\n");
532 }
533
534 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
535
536 LIBTEST_API char * STDCALL 
537 mono_test_return_string (ReturnStringDelegate func)
538 {
539         char *res;
540
541         // printf ("mono_test_return_string\n");
542
543         res = func ("TEST");
544         marshal_free (res);
545
546         // printf ("got string: %s\n", res);
547         return marshal_strdup ("12345");
548 }
549
550 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
551
552 LIBTEST_API int STDCALL 
553 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
554 {
555         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
556             !strcmp (ss->d, "TEST1")) {
557                 ss->a = 1;
558                 ss->b = 0;
559                 ss->c = 1;
560                 ss->d = "TEST2";
561
562                 return func (a, ss, b);
563         }
564
565         return 1;
566 }
567
568 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
569
570 LIBTEST_API int STDCALL 
571 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
572 {
573         /* Check that the input pointer is ignored */
574         ss->d = (gpointer)0x12345678;
575
576         func (a, ss, b);
577
578         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
579                 return 0;
580         else
581                 return 1;
582 }
583
584 typedef struct {
585         int a;
586         SimpleDelegate func, func2, func3;
587 } DelegateStruct;
588
589 LIBTEST_API DelegateStruct STDCALL 
590 mono_test_marshal_delegate_struct (DelegateStruct ds)
591 {
592         DelegateStruct res;
593
594         res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
595         res.func = ds.func;
596         res.func2 = ds.func2;
597         res.func3 = NULL;
598
599         return res;
600 }
601
602 LIBTEST_API int STDCALL  
603 mono_test_marshal_struct (simplestruct ss)
604 {
605         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
606             !strcmp (ss.d, "TEST"))
607                 return 0;
608
609         return 1;
610 }
611
612 LIBTEST_API int STDCALL 
613 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
614 {
615         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
616
617         marshal_free ((char*)ss->d);
618
619         ss->a = !ss->a;
620         ss->b = !ss->b;
621         ss->c = !ss->c;
622         ss->d = marshal_strdup ("DEF");
623
624         return res ? 0 : 1;
625 }
626
627 typedef struct {
628         int a;
629         int b;
630         int c;
631         char *d;
632         unsigned char e;
633         double f;
634         unsigned char g;
635         guint64 h;
636 } simplestruct2;
637
638 LIBTEST_API int STDCALL 
639 mono_test_marshal_struct2 (simplestruct2 ss)
640 {
641         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
642             !strcmp (ss.d, "TEST") && 
643             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
644                 return 0;
645
646         return 1;
647 }
648
649 /* on HP some of the struct should be on the stack and not in registers */
650 LIBTEST_API int STDCALL 
651 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
652 {
653         if (i != 10 || j != 11 || k != 12)
654                 return 1;
655         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
656             !strcmp (ss.d, "TEST") && 
657             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
658                 return 0;
659
660         return 1;
661 }
662
663 LIBTEST_API int STDCALL  
664 mono_test_marshal_lpstruct (simplestruct *ss)
665 {
666         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
667             !strcmp (ss->d, "TEST"))
668                 return 0;
669
670         return 1;
671 }
672
673 LIBTEST_API int STDCALL  
674 mono_test_marshal_lpstruct_blittable (point *p)
675 {
676         if (p->x == 1.0 && p->y == 2.0)
677                 return 0;
678         else
679                 return 1;
680 }
681
682 LIBTEST_API int STDCALL 
683 mono_test_marshal_struct_array (simplestruct2 *ss)
684 {
685         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
686                    !strcmp (ss[0].d, "TEST") && 
687                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
688                 return 1;
689
690         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
691                    !strcmp (ss[1].d, "TEST2") && 
692                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
693                 return 1;
694
695         return 0;
696 }
697
698 typedef struct long_align_struct {
699         gint32 a;
700         gint64 b;
701         gint64 c;
702 } long_align_struct;
703
704 LIBTEST_API int STDCALL 
705 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
706 {
707         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
708 }
709
710 LIBTEST_API simplestruct2 * STDCALL 
711 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
712 {
713         simplestruct2 *res;
714
715         if (!ss)
716                 return NULL;
717
718         if (i != 10 || j != 11 || k != 12 || l != 14)
719                 return NULL;
720         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
721                    !strcmp (ss->d, "TEST") && 
722                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
723                 return NULL;
724
725         res = marshal_new0 (simplestruct2, 1);
726         memcpy (res, ss, sizeof (simplestruct2));
727         res->d = marshal_strdup ("TEST");
728         return res;
729 }
730
731 LIBTEST_API int STDCALL 
732 mono_test_marshal_byref_class (simplestruct2 **ssp)
733 {
734         simplestruct2 *ss = *ssp;
735         simplestruct2 *res;
736         
737         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
738                    !strcmp (ss->d, "TEST") && 
739                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
740                 return 1;
741
742         res = marshal_new0 (simplestruct2, 1);
743         memcpy (res, ss, sizeof (simplestruct2));
744         res->d = marshal_strdup ("TEST-RES");
745
746         *ssp = res;
747         return 0;
748 }
749
750 static void *
751 get_sp (void)
752 {
753         int i;
754         void *p;
755
756         /* Yes, this is correct, we are only trying to determine the value of the stack here */
757         p = &i;
758         return p;
759 }
760
761 LIBTEST_API int STDCALL 
762 reliable_delegate (int a)
763 {
764         return a;
765 }
766
767 /*
768  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
769  */
770 static gboolean
771 is_get_sp_reliable (void)
772 {
773         void *sp1, *sp2;
774
775         reliable_delegate(1);
776         sp1 = get_sp();
777         reliable_delegate(1);
778         sp2 = get_sp();
779         return sp1 == sp2;
780
781
782 LIBTEST_API int STDCALL 
783 mono_test_marshal_delegate (SimpleDelegate delegate)
784 {
785         void *sp1, *sp2;
786
787         /* Check that the delegate wrapper is stdcall */
788         delegate (2);
789         sp1 = get_sp ();
790         delegate (2);
791         sp2 = get_sp ();
792         if (is_get_sp_reliable())
793                 g_assert (sp1 == sp2);
794
795         return delegate (2);
796 }
797
798 static int STDCALL inc_cb (int i)
799 {
800         return i + 1;
801 }
802
803 LIBTEST_API int STDCALL 
804 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
805 {
806         *delegate = inc_cb;
807
808         return 0;
809 }
810
811 LIBTEST_API SimpleDelegate STDCALL 
812 mono_test_marshal_return_delegate (SimpleDelegate delegate)
813 {
814         return delegate;
815 }
816
817 static int STDCALL
818 return_plus_one (int i)
819 {
820         return i + 1;
821 }
822
823 LIBTEST_API SimpleDelegate STDCALL 
824 mono_test_marshal_return_delegate_2 (void)
825 {
826         return return_plus_one;
827 }
828
829 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
830
831 static gboolean
832 is_utf16_equals (gunichar2 *s1, const char *s2)
833 {
834         char *s;
835         int res;
836
837         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
838         res = strcmp (s, s2);
839         g_free (s);
840
841         return res == 0;
842 }
843
844 LIBTEST_API int STDCALL 
845 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
846 {
847         simplestruct ss, res;
848
849         ss.a = 0;
850         ss.b = 1;
851         ss.c = 0;
852         ss.d = "TEST";
853         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
854
855         res = delegate (ss);
856         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
857                 return 1;
858
859         return 0;
860 }
861
862 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
863
864 LIBTEST_API int STDCALL 
865 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
866 {
867         simplestruct ss;
868         simplestruct *res;
869
870         ss.a = 0;
871         ss.b = 1;
872         ss.c = 0;
873         ss.d = "TEST";
874
875         /* Check argument */
876         res = delegate (&ss);
877         if (!res)
878                 return 1;
879
880         /* Check return value */
881         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
882                 return 2;
883
884         /* Check NULL argument and NULL result */
885         res = delegate (NULL);
886         if (res)
887                 return 3;
888
889         return 0;
890 }
891
892 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
893
894 LIBTEST_API int STDCALL 
895 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
896 {
897         simplestruct ss;
898         int res;
899         simplestruct *ptr;
900
901         ss.a = 0;
902         ss.b = 1;
903         ss.c = 0;
904         ss.d = "TEST";
905
906         ptr = &ss;
907
908         res = delegate (&ptr);
909         if (res != 0)
910                 return 1;
911
912         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
913                 return 2;
914
915         return 0;
916 }
917
918 LIBTEST_API int STDCALL 
919 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
920 {
921         int res;
922
923         res = delegate (NULL);
924
925         return 0;
926 }
927
928 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
929
930 LIBTEST_API int STDCALL 
931 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
932 {
933         int res;
934         simplestruct *ptr;
935
936         /* Check that the input pointer is ignored */
937         ptr = (gpointer)0x12345678;
938
939         res = delegate (&ptr);
940         if (res != 0)
941                 return 1;
942
943         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
944                 return 2;
945
946         return 0;
947 }
948
949 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
950
951 LIBTEST_API int STDCALL 
952 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
953 {
954         int res;
955         simplestruct ss;
956
957         ss.a = FALSE;
958         ss.b = TRUE;
959         ss.c = FALSE;
960         ss.d = g_strdup_printf ("%s", "FOO");
961
962         res = delegate (&ss);
963         if (res != 0)
964                 return 1;
965
966         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
967                 return 2;
968
969         return 0;
970 }
971
972 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
973
974 LIBTEST_API int STDCALL 
975 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
976 {
977         return delegate (s);
978 }
979
980 typedef int (STDCALL *return_int_fnt) (int i);
981 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
982
983 LIBTEST_API int STDCALL 
984 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
985 {
986         return delegate (ftn);
987 }
988
989 static int STDCALL 
990 return_self (int i)
991 {
992         return i;
993 }
994
995 LIBTEST_API int STDCALL 
996 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
997 {
998         return delegate (return_self);
999 }
1000
1001 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
1002
1003 LIBTEST_API int STDCALL 
1004 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
1005 {
1006         int i = 1;
1007
1008         int res = delegate (&i);
1009         if (res != 0)
1010                 return res;
1011
1012         if (i != 2)
1013                 return 2;
1014
1015         return 0;
1016 }
1017
1018 typedef int (STDCALL *return_int_delegate) (int i);
1019
1020 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
1021
1022 LIBTEST_API int STDCALL 
1023 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
1024 {
1025         return (d ()) (55);
1026 }
1027
1028 LIBTEST_API int STDCALL  
1029 mono_test_marshal_stringbuilder (char *s, int n)
1030 {
1031         const char m[] = "This is my message.  Isn't it nice?";
1032
1033         if (strcmp (s, "ABCD") != 0)
1034                 return 1;
1035         strncpy(s, m, n);
1036         s [n] = '\0';
1037         return 0;
1038 }
1039
1040 LIBTEST_API int STDCALL  
1041 mono_test_marshal_stringbuilder_default (char *s, int n)
1042 {
1043         const char m[] = "This is my message.  Isn't it nice?";
1044
1045         strncpy(s, m, n);
1046         s [n] = '\0';
1047         return 0;
1048 }
1049
1050 LIBTEST_API int STDCALL  
1051 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1052 {
1053         const char m[] = "This is my message.  Isn't it nice?";
1054         gunichar2* s2;
1055         glong len;
1056
1057         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1058         
1059         len = (len * 2) + 2;
1060         if (len > (n * 2))
1061                 len = n * 2;
1062         memcpy (s, s2, len);
1063
1064         g_free (s2);
1065
1066         return 0;
1067 }
1068
1069 LIBTEST_API void STDCALL
1070 mono_test_marshal_stringbuilder_out (char **s)
1071 {
1072         const char m[] = "This is my message.  Isn't it nice?";
1073         char *str;
1074
1075         str = marshal_alloc (strlen (m) + 1);
1076         memcpy (str, m, strlen (m) + 1);
1077         
1078         *s = str;
1079 }
1080
1081 LIBTEST_API int STDCALL  
1082 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1083 {
1084         const char m[] = "This is my message.  Isn't it nice?";
1085         gunichar2 *s2;
1086         glong len;
1087
1088         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1089         
1090         len = (len * 2) + 2;
1091         *s = marshal_alloc (len);
1092         memcpy (*s, s2, len);
1093
1094         g_free (s2);
1095
1096         return 0;
1097 }
1098
1099 LIBTEST_API int STDCALL
1100 mono_test_marshal_stringbuilder_ref (char **s)
1101 {
1102         const char m[] = "This is my message.  Isn't it nice?";
1103         char *str;
1104
1105         if (strcmp (*s, "ABC"))
1106                 return 1;
1107
1108         str = marshal_alloc (strlen (m) + 1);
1109         memcpy (str, m, strlen (m) + 1);
1110         
1111         *s = str;
1112         return 0;
1113 }
1114
1115 typedef struct {
1116 #ifndef __GNUC__
1117     char a;
1118 #endif
1119 } EmptyStruct;
1120
1121 LIBTEST_API int STDCALL 
1122 mono_test_marshal_empty_string_array (char **array)
1123 {
1124         return (array == NULL) ? 0 : 1;
1125 }
1126
1127 LIBTEST_API int STDCALL 
1128 mono_test_marshal_string_array (char **array)
1129 {
1130         if (strcmp (array [0], "ABC"))
1131                 return 1;
1132         if (strcmp (array [1], "DEF"))
1133                 return 2;
1134
1135         if (array [2] != NULL)
1136                 return 3;
1137
1138         return 0;
1139 }
1140
1141 LIBTEST_API int STDCALL 
1142 mono_test_marshal_byref_string_array (char ***array)
1143 {
1144         if (*array == NULL)
1145                 return 0;
1146
1147         if (strcmp ((*array) [0], "Alpha"))
1148                 return 2;
1149         if (strcmp ((*array) [1], "Beta"))
1150                 return 2;
1151         if (strcmp ((*array) [2], "Gamma"))
1152                 return 2;
1153
1154         return 1;
1155 }
1156
1157 LIBTEST_API int STDCALL 
1158 mono_test_marshal_stringbuilder_array (char **array)
1159 {
1160         if (strcmp (array [0], "ABC"))
1161                 return 1;
1162         if (strcmp (array [1], "DEF"))
1163                 return 2;
1164
1165         strcpy (array [0], "DEF");
1166         strcpy (array [1], "ABC");
1167
1168         return 0;
1169 }
1170
1171 LIBTEST_API int STDCALL 
1172 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1173 {
1174         GError *error = NULL;
1175         char *s;
1176         
1177         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1178         if (strcmp (s, "ABC")) {
1179                 g_free (s);
1180                 return 1;
1181         }
1182         else
1183                 g_free (s);
1184
1185         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1186         if (strcmp (s, "DEF")) {
1187                 g_free (s);
1188                 return 2;
1189         }
1190         else
1191                 g_free (s);
1192
1193         if (strcmp (array2 [0], "ABC"))
1194                 return 3;
1195
1196         if (strcmp (array2 [1], "DEF")) 
1197                 return 4;
1198
1199         return 0;
1200 }
1201
1202 /* this does not work on Redhat gcc 2.96 */
1203 LIBTEST_API int STDCALL  
1204 mono_test_empty_struct (int a, EmptyStruct es, int b)
1205 {
1206         // printf ("mono_test_empty_struct %d %d\n", a, b);
1207
1208         // Intel icc on ia64 passes 'es' in 2 registers
1209 #if defined(__ia64) && defined(__INTEL_COMPILER)
1210         return 0;
1211 #else
1212         if (a == 1 && b == 2)
1213                 return 0;
1214         return 1;
1215 #endif
1216 }
1217
1218 typedef struct {
1219        char a[100];
1220 } ByValStrStruct;
1221
1222 LIBTEST_API ByValStrStruct * STDCALL 
1223 mono_test_byvalstr_gen (void)
1224 {
1225         ByValStrStruct *ret;
1226        
1227         ret = malloc(sizeof(ByValStrStruct));
1228         memset(ret, 'a', sizeof(ByValStrStruct)-1);
1229         ret->a[sizeof(ByValStrStruct)-1] = 0;
1230
1231         return ret;
1232 }
1233
1234 LIBTEST_API int STDCALL 
1235 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1236 {
1237         int ret;
1238
1239         ret = strcmp(data->a, correctString);
1240         // printf ("T1: %s\n", data->a);
1241         // printf ("T2: %s\n", correctString);
1242
1243         /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1244         g_free (data);
1245         return (ret != 0);
1246 }
1247
1248 typedef struct {
1249         guint16 a[4];
1250         int  flag;
1251 } ByValStrStruct_Unicode;
1252
1253 LIBTEST_API int STDCALL 
1254 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1255 {
1256         if (ref->flag != 0x1234abcd){
1257                 printf ("overwritten data");
1258                 return 1;
1259         }
1260             
1261         if (test == 1 || test == 3){
1262                 if (ref->a [0] != '1' ||
1263                     ref->a [1] != '2'   ||
1264                     ref->a [2] != '3')
1265                         return 1;
1266                 return 0;
1267         }
1268         if (test == 2){
1269                 if (ref->a [0] != '1' ||
1270                     ref->a [1] != '2')
1271                         return 1;
1272                 return 0;
1273         }
1274         return 10;
1275 }
1276
1277 LIBTEST_API int STDCALL 
1278 NameManglingAnsi (char *data)
1279 {
1280         return data [0] + data [1] + data [2];
1281 }
1282
1283 LIBTEST_API int STDCALL 
1284 NameManglingAnsiA (char *data)
1285 {
1286         g_assert_not_reached ();
1287 }
1288
1289 LIBTEST_API int STDCALL 
1290 NameManglingAnsiW (char *data)
1291 {
1292         g_assert_not_reached ();
1293 }
1294
1295 LIBTEST_API int STDCALL 
1296 NameManglingAnsi2A (char *data)
1297 {
1298         return data [0] + data [1] + data [2];
1299 }
1300
1301 LIBTEST_API int STDCALL 
1302 NameManglingAnsi2W (char *data)
1303 {
1304         g_assert_not_reached ();
1305 }
1306
1307 LIBTEST_API int STDCALL 
1308 NameManglingUnicode (char *data)
1309 {
1310         g_assert_not_reached ();
1311 }
1312
1313 LIBTEST_API int STDCALL 
1314 NameManglingUnicodeW (gunichar2 *data)
1315 {
1316         return data [0] + data [1] + data [2];
1317 }
1318
1319 LIBTEST_API int STDCALL 
1320 NameManglingUnicode2 (gunichar2 *data)
1321 {
1322         return data [0] + data [1] + data [2];
1323 }
1324
1325 LIBTEST_API int STDCALL 
1326 NameManglingAutoW (char *data)
1327 {
1328 #ifdef WIN32
1329         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1330 #else
1331         g_assert_not_reached ();
1332 #endif
1333 }
1334
1335 LIBTEST_API int STDCALL 
1336 NameManglingAuto (char *data)
1337 {
1338 #ifndef WIN32
1339         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1340 #else
1341         g_assert_not_reached ();
1342 #endif
1343 }
1344
1345 typedef int (STDCALL *intcharFunc)(const char*);
1346
1347 LIBTEST_API void STDCALL 
1348 callFunction (intcharFunc f)
1349 {
1350         f ("ABC");
1351 }
1352
1353 typedef struct {
1354         const char* str;
1355         int i;
1356 } SimpleObj;
1357
1358 LIBTEST_API int STDCALL 
1359 class_marshal_test0 (SimpleObj *obj1)
1360 {
1361         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1362
1363         if (strcmp(obj1->str, "T1"))
1364                 return -1;
1365         if (obj1->i != 4)
1366                 return -2;
1367
1368         return 0;
1369 }
1370
1371 LIBTEST_API int STDCALL 
1372 class_marshal_test4 (SimpleObj *obj1)
1373 {
1374         if (obj1)
1375                 return -1;
1376
1377         return 0;
1378 }
1379
1380 LIBTEST_API void STDCALL
1381 class_marshal_test1 (SimpleObj **obj1)
1382 {
1383         SimpleObj *res = malloc (sizeof (SimpleObj));
1384
1385         res->str = marshal_strdup ("ABC");
1386         res->i = 5;
1387
1388         *obj1 = res;
1389 }
1390
1391 LIBTEST_API int STDCALL 
1392 class_marshal_test2 (SimpleObj **obj1)
1393 {
1394         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1395
1396         if (strcmp((*obj1)->str, "ABC"))
1397                 return -1;
1398         if ((*obj1)->i != 5)
1399                 return -2;
1400
1401         return 0;
1402 }
1403
1404 LIBTEST_API int STDCALL 
1405 string_marshal_test0 (char *str)
1406 {
1407         if (strcmp (str, "TEST0"))
1408                 return -1;
1409
1410         return 0;
1411 }
1412
1413 LIBTEST_API void STDCALL
1414 string_marshal_test1 (const char **str)
1415 {
1416         *str = marshal_strdup ("TEST1");
1417 }
1418
1419 LIBTEST_API int STDCALL 
1420 string_marshal_test2 (char **str)
1421 {
1422         // printf ("string_marshal_test2 %s\n", *str);
1423
1424         if (strcmp (*str, "TEST1"))
1425                 return -1;
1426
1427         *str = marshal_strdup ("TEST2");
1428
1429         return 0;
1430 }
1431
1432 LIBTEST_API int STDCALL 
1433 string_marshal_test3 (char *str)
1434 {
1435         if (str)
1436                 return -1;
1437
1438         return 0;
1439 }
1440
1441 typedef struct {
1442         int a;
1443         int b;
1444 } BlittableClass;
1445
1446 LIBTEST_API BlittableClass* STDCALL 
1447 TestBlittableClass (BlittableClass *vl)
1448 {
1449         BlittableClass *res;
1450
1451         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1452
1453         if (vl) {
1454                 vl->a++;
1455                 vl->b++;
1456
1457                 res = marshal_new0 (BlittableClass, 1);
1458                 memcpy (res, vl, sizeof (BlittableClass));
1459         } else {
1460                 res = marshal_new0 (BlittableClass, 1);
1461                 res->a = 42;
1462                 res->b = 43;
1463         }
1464
1465         return res;
1466 }
1467
1468 typedef struct OSVERSIONINFO_STRUCT
1469
1470         int a; 
1471         int b; 
1472 } OSVERSIONINFO_STRUCT;
1473
1474 LIBTEST_API int STDCALL  
1475 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1476 {
1477
1478         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1479
1480         osvi->a += 1;
1481         osvi->b += 1;
1482
1483         return osvi->a + osvi->b;
1484 }
1485
1486 LIBTEST_API int STDCALL  
1487 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1488 {
1489
1490         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1491
1492         osvi->a += 1;
1493         osvi->b += 1;
1494
1495         return osvi->a + osvi->b;
1496 }
1497
1498 LIBTEST_API int STDCALL 
1499 mono_test_marshal_point (point pt)
1500 {
1501         // printf("point %g %g\n", pt.x, pt.y);
1502         if (pt.x == 1.25 && pt.y == 3.5)
1503                 return 0;
1504
1505         return 1;
1506 }
1507
1508 typedef struct {
1509         int x;
1510         double y;
1511 } mixed_point;
1512
1513 LIBTEST_API int STDCALL 
1514 mono_test_marshal_mixed_point (mixed_point pt)
1515 {
1516         // printf("mixed point %d %g\n", pt.x, pt.y);
1517         if (pt.x == 5 && pt.y == 6.75)
1518                 return 0;
1519
1520         return 1;
1521 }
1522
1523 LIBTEST_API int STDCALL 
1524 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1525 {
1526         if (pt->x != 5 || pt->y != 6.75)
1527                 return 1;
1528
1529         pt->x = 10;
1530         pt->y = 12.35;
1531
1532         return 0;
1533 }
1534
1535 LIBTEST_API int STDCALL  
1536 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1537 {
1538     int res = 1;
1539     if (*b1 != 0 && *b1 != 1)
1540         return 1;
1541     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1542         return 1;
1543     if (*b3 != 0 && *b3 != 1)
1544         return 1;
1545     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1546         res = 0;
1547     *b1 = !*b1;
1548     *b2 = ~*b2;
1549     *b3 = !*b3;
1550     return res;
1551 }
1552
1553 struct BoolStruct
1554 {
1555     int i;
1556     char b1;
1557     short b2; /* variant_bool */
1558     int b3;
1559 };
1560
1561 LIBTEST_API int STDCALL  
1562 marshal_test_bool_struct(struct BoolStruct *s)
1563 {
1564     int res = 1;
1565     if (s->b1 != 0 && s->b1 != 1)
1566         return 1;
1567     if (s->b2 != 0 && s->b2 != -1)
1568         return 1;
1569     if (s->b3 != 0 && s->b3 != 1)
1570         return 1;
1571     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1572         res = 0;
1573     s->b1 = !s->b1;
1574     s->b2 = ~s->b2;
1575     s->b3 = !s->b3;
1576     return res;
1577 }
1578
1579 typedef struct {
1580         gint64 l;
1581 } LongStruct2;
1582
1583 typedef struct {
1584         int i;
1585         LongStruct2 l;
1586 } LongStruct;
1587
1588 LIBTEST_API int STDCALL
1589 mono_test_marshal_long_struct (LongStruct *s)
1590 {
1591         return s->i + s->l.l;
1592 }
1593
1594 LIBTEST_API void STDCALL
1595 mono_test_last_error (int err)
1596 {
1597 #ifdef WIN32
1598         SetLastError (err);
1599 #else
1600         errno = err;
1601 #endif
1602 }
1603
1604 LIBTEST_API int STDCALL 
1605 mono_test_asany (void *ptr, int what)
1606 {
1607         switch (what) {
1608         case 1:
1609                 return (*(int*)ptr == 5) ? 0 : 1;
1610         case 2:
1611                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1612         case 3: {
1613                 simplestruct2 ss = *(simplestruct2*)ptr;
1614
1615                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1616             !strcmp (ss.d, "TEST") && 
1617             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1618                         return 0;
1619                 else
1620                         return 1;
1621         }
1622         case 4: {
1623                 GError *error = NULL;
1624                 char *s;
1625
1626                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1627
1628                 if (!s)
1629                         return 1;
1630
1631                 if (!strcmp (s, "ABC")) {
1632                         g_free (s);
1633                         return 0;
1634                 }
1635                 else {
1636                         g_free (s);
1637                         return 1;
1638                 }
1639         }
1640         default:
1641                 g_assert_not_reached ();
1642         }
1643
1644         return 1;
1645 }
1646
1647 typedef struct
1648 {
1649         int i;
1650         int j;
1651         int k;
1652         char *s;
1653 } AsAnyStruct;
1654
1655 LIBTEST_API int STDCALL 
1656 mono_test_marshal_asany_in (void* ptr)
1657 {
1658         AsAnyStruct* asAny = ptr;
1659         int res = asAny->i + asAny->j + asAny->k;
1660
1661         return res;
1662 }
1663
1664 LIBTEST_API int STDCALL 
1665 mono_test_marshal_asany_inout (void* ptr)
1666 {
1667         AsAnyStruct* asAny = ptr;
1668         int res = asAny->i + asAny->j + asAny->k;
1669
1670         marshal_free (asAny->s);
1671
1672         asAny->i = 10;
1673         asAny->j = 20;
1674         asAny->k = 30;
1675         asAny->s = 0;
1676
1677         return res;
1678 }
1679
1680 LIBTEST_API int STDCALL 
1681 mono_test_marshal_asany_out (void* ptr)
1682 {
1683         AsAnyStruct* asAny = ptr;
1684         int res = asAny->i + asAny->j + asAny->k;
1685
1686         asAny->i = 10;
1687         asAny->j = 20;
1688         asAny->k = 30;
1689         asAny->s = 0;
1690
1691         return res;
1692 }
1693
1694 /*
1695  * AMD64 marshalling tests.
1696  */
1697
1698 typedef struct amd64_struct1 {
1699         int i;
1700         int j;
1701         int k;
1702         int l;
1703 } amd64_struct1;
1704
1705 LIBTEST_API amd64_struct1 STDCALL 
1706 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1707 {
1708         s.i ++;
1709         s.j ++;
1710         s.k ++;
1711         s.l ++;
1712
1713         return s;
1714 }
1715
1716 LIBTEST_API amd64_struct1 STDCALL 
1717 mono_test_marshal_amd64_pass_return_struct1_many_args (amd64_struct1 s, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8)
1718 {
1719         s.i ++;
1720         s.j ++;
1721         s.k ++;
1722         s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1723
1724         return s;
1725 }
1726
1727 typedef struct amd64_struct2 {
1728         int i;
1729         int j;
1730 } amd64_struct2;
1731
1732 LIBTEST_API amd64_struct2 STDCALL 
1733 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1734 {
1735         s.i ++;
1736         s.j ++;
1737
1738         return s;
1739 }
1740
1741 typedef struct amd64_struct3 {
1742         int i;
1743 } amd64_struct3;
1744
1745 LIBTEST_API amd64_struct3 STDCALL 
1746 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1747 {
1748         s.i ++;
1749
1750         return s;
1751 }
1752
1753 typedef struct amd64_struct4 {
1754         double d1, d2;
1755 } amd64_struct4;
1756
1757 LIBTEST_API amd64_struct4 STDCALL 
1758 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1759 {
1760         s.d1 ++;
1761         s.d2 ++;
1762
1763         return s;
1764 }
1765
1766 /*
1767  * IA64 marshalling tests.
1768  */
1769 typedef struct test_struct5 {
1770         float d1, d2;
1771 } test_struct5;
1772
1773 LIBTEST_API test_struct5 STDCALL 
1774 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1775 {
1776         s.d1 += d1 + d2 + i;
1777         s.d2 += d3 + d4 + i;
1778
1779         return s;
1780 }
1781
1782 typedef struct test_struct6 {
1783         double d1, d2;
1784 } test_struct6;
1785
1786 LIBTEST_API test_struct6 STDCALL 
1787 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1788 {
1789         s.d1 += d1 + d2 + i;
1790         s.d2 += d3 + d4;
1791
1792         return s;
1793 }
1794
1795 static guint32 custom_res [2];
1796
1797 LIBTEST_API void* STDCALL
1798 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1799 {
1800         /* ptr will be freed by CleanupNative, so make a copy */
1801         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1802         custom_res [1] = ptr [1];
1803
1804         return &custom_res;
1805 }
1806
1807 LIBTEST_API int STDCALL 
1808 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1809 {
1810         custom_res [0] = 0;
1811         custom_res [1] = i + j + 10;
1812
1813         *ptr = custom_res;
1814
1815         return 0;
1816 }
1817
1818 LIBTEST_API int STDCALL 
1819 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1820 {
1821         ptr [0] = 0;
1822         ptr [1] = i + ptr [1] + j;
1823
1824         return 0;
1825 }
1826
1827 LIBTEST_API int STDCALL 
1828 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1829 {
1830         return ptr == NULL ? 0 : 1;
1831 }
1832
1833 LIBTEST_API int STDCALL 
1834 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1835 {
1836         (*ptr)[1] += i + j;
1837
1838         return 0;
1839 }
1840
1841 LIBTEST_API void* STDCALL
1842 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1843 {
1844         g_assert_not_reached ();
1845
1846         return NULL;
1847 }
1848
1849 LIBTEST_API void* STDCALL
1850 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1851 {
1852         g_assert (ptr == NULL);
1853
1854         return NULL;
1855 }
1856
1857 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1858
1859 LIBTEST_API int STDCALL 
1860 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1861 {
1862         guint32 buf [2];
1863         guint32 res;
1864         guint32 *ptr;
1865
1866         buf [0] = 0;
1867         buf [1] = 10;
1868
1869         ptr = del (&buf);
1870
1871         res = ptr [1];
1872
1873 #ifdef WIN32
1874         /* FIXME: Freed with FreeHGlobal */
1875 #else
1876         g_free (ptr);
1877 #endif
1878
1879         return res;
1880 }
1881
1882 LIBTEST_API int STDCALL 
1883 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1884 {
1885         void *ptr = del (NULL);
1886
1887         return (ptr == NULL) ? 15 : 0;
1888 }
1889
1890 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
1891
1892 LIBTEST_API int STDCALL 
1893 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
1894 {
1895         void* pptr = del;
1896
1897         del (&pptr);
1898
1899         if(pptr != NULL)
1900                 return 1;
1901
1902         return 0;
1903 }
1904
1905 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1906
1907 LIBTEST_API int STDCALL 
1908 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1909 {
1910         return func (1);
1911 }
1912
1913 typedef struct {
1914         int a, b, c;
1915         gint64 d;
1916 } BlittableStruct;
1917         
1918 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1919
1920 LIBTEST_API int STDCALL 
1921 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1922 {
1923         BlittableStruct ss, res;
1924
1925         ss.a = 1;
1926         ss.b = 2;
1927         ss.c = 3;
1928         ss.d = 55;
1929
1930         res = delegate (ss);
1931         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1932                 return 1;
1933
1934         return 0;
1935 }
1936
1937 LIBTEST_API int STDCALL 
1938 mono_test_stdcall_name_mangling (int a, int b, int c)
1939 {
1940         return a + b + c;
1941 }
1942
1943 /*
1944  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1945  */
1946
1947 typedef struct {
1948         int i;
1949 } SmallStruct1;
1950         
1951 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1952
1953 LIBTEST_API int STDCALL 
1954 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1955 {
1956         SmallStruct1 ss, res;
1957
1958         ss.i = 1;
1959
1960         res = delegate (ss);
1961         if (! (res.i == -1))
1962                 return 1;
1963
1964         return 0;
1965 }
1966
1967 typedef struct {
1968         gint16 i, j;
1969 } SmallStruct2;
1970         
1971 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1972
1973 LIBTEST_API int STDCALL 
1974 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1975 {
1976         SmallStruct2 ss, res;
1977
1978         ss.i = 2;
1979         ss.j = 3;
1980
1981         res = delegate (ss);
1982         if (! ((res.i == -2) && (res.j == -3)))
1983                 return 1;
1984
1985         return 0;
1986 }
1987
1988 typedef struct {
1989         gint16 i;
1990         gint8 j;
1991 } SmallStruct3;
1992         
1993 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1994
1995 LIBTEST_API int STDCALL 
1996 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1997 {
1998         SmallStruct3 ss, res;
1999
2000         ss.i = 1;
2001         ss.j = 2;
2002
2003         res = delegate (ss);
2004         if (! ((res.i == -1) && (res.j == -2)))
2005                 return 1;
2006
2007         return 0;
2008 }
2009
2010 typedef struct {
2011         gint16 i;
2012 } SmallStruct4;
2013         
2014 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
2015
2016 LIBTEST_API int STDCALL 
2017 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
2018 {
2019         SmallStruct4 ss, res;
2020
2021         ss.i = 1;
2022
2023         res = delegate (ss);
2024         if (! (res.i == -1))
2025                 return 1;
2026
2027         return 0;
2028 }
2029
2030 typedef struct {
2031         gint64 i;
2032 } SmallStruct5;
2033         
2034 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
2035
2036 LIBTEST_API int STDCALL 
2037 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
2038 {
2039         SmallStruct5 ss, res;
2040
2041         ss.i = 5;
2042
2043         res = delegate (ss);
2044         if (! (res.i == -5))
2045                 return 1;
2046
2047         return 0;
2048 }
2049
2050 typedef struct {
2051         int i, j;
2052 } SmallStruct6;
2053         
2054 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
2055
2056 LIBTEST_API int STDCALL 
2057 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
2058 {
2059         SmallStruct6 ss, res;
2060
2061         ss.i = 1;
2062         ss.j = 2;
2063
2064         res = delegate (ss);
2065         if (! ((res.i == -1) && (res.j == -2)))
2066                 return 1;
2067
2068         return 0;
2069 }
2070
2071 typedef struct {
2072         int i;
2073         gint16 j;
2074 } SmallStruct7;
2075         
2076 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2077
2078 LIBTEST_API int STDCALL 
2079 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2080 {
2081         SmallStruct7 ss, res;
2082
2083         ss.i = 1;
2084         ss.j = 2;
2085
2086         res = delegate (ss);
2087         if (! ((res.i == -1) && (res.j == -2)))
2088                 return 1;
2089
2090         return 0;
2091 }
2092
2093 typedef struct {
2094         float i;
2095 } SmallStruct8;
2096         
2097 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2098
2099 LIBTEST_API int STDCALL 
2100 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2101 {
2102         SmallStruct8 ss, res;
2103
2104         ss.i = 1.0;
2105
2106         res = delegate (ss);
2107         if (! ((res.i == -1.0)))
2108                 return 1;
2109
2110         return 0;
2111 }
2112
2113 typedef struct {
2114         double i;
2115 } SmallStruct9;
2116         
2117 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2118
2119 LIBTEST_API int STDCALL 
2120 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2121 {
2122         SmallStruct9 ss, res;
2123
2124         ss.i = 1.0;
2125
2126         res = delegate (ss);
2127         if (! ((res.i == -1.0)))
2128                 return 1;
2129
2130         return 0;
2131 }
2132
2133 typedef struct {
2134         float i, j;
2135 } SmallStruct10;
2136         
2137 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2138
2139 LIBTEST_API int STDCALL 
2140 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2141 {
2142         SmallStruct10 ss, res;
2143
2144         ss.i = 1.0;
2145         ss.j = 2.0;
2146
2147         res = delegate (ss);
2148         if (! ((res.i == -1.0) && (res.j == -2.0)))
2149                 return 1;
2150
2151         return 0;
2152 }
2153
2154 typedef struct {
2155         float i;
2156         int j;
2157 } SmallStruct11;
2158         
2159 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2160
2161 LIBTEST_API int STDCALL 
2162 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2163 {
2164         SmallStruct11 ss, res;
2165
2166         ss.i = 1.0;
2167         ss.j = 2;
2168
2169         res = delegate (ss);
2170         if (! ((res.i == -1.0) && (res.j == -2)))
2171                 return 1;
2172
2173         return 0;
2174 }
2175
2176 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2177
2178 LIBTEST_API int STDCALL 
2179 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2180 {
2181         return del (len, NULL, arr);
2182 }
2183
2184 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2185
2186 LIBTEST_API int STDCALL 
2187 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2188 {
2189         return del (len, NULL, arr);
2190 }
2191
2192 LIBTEST_API int STDCALL 
2193 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2194 {
2195         del (len, NULL, arr);
2196
2197         if ((arr [0] != 1) || (arr [1] != 2))
2198                 return 1;
2199         else
2200                 return 0;
2201 }
2202
2203 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2204
2205 LIBTEST_API int STDCALL 
2206 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2207 {
2208         const char m[] = "abcdef";
2209         gunichar2 *s2, *res;
2210         glong len;
2211
2212         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2213
2214         res = del (s2);
2215
2216         marshal_free (res);
2217
2218         return 0;
2219 }
2220
2221 LIBTEST_API int STDCALL 
2222 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2223 {
2224         del (len, NULL, arr);
2225
2226         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2227                 return 0;
2228         else
2229                 return 1;
2230 }
2231
2232 typedef int (*CdeclDelegate) (int i, int j);
2233
2234 LIBTEST_API int STDCALL 
2235 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2236 {
2237         int i;
2238
2239         for (i = 0; i < 1000; ++i)
2240                 del (1, 2);
2241
2242         return 0;
2243 }
2244
2245 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2246
2247 LIBTEST_API int STDCALL 
2248 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2249 {
2250         char **arr = d (2);
2251         int res;
2252
2253         if (arr == NULL)
2254                 return 3;
2255
2256         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2257                 res = 1;
2258         else
2259                 res = 0;
2260
2261         marshal_free (arr);
2262
2263         return res;
2264 }
2265
2266 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2267
2268 LIBTEST_API int STDCALL 
2269 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2270 {
2271         char *s = (char*)"ABC";
2272         int res;
2273
2274         res = d (&s);
2275         if (res != 0)
2276                 return res;
2277
2278         if (!strcmp (s, "DEF"))
2279                 res = 0;
2280         else
2281                 res = 2;
2282
2283         marshal_free (s);
2284
2285         return res;
2286 }
2287
2288 LIBTEST_API int STDCALL 
2289 add_delegate (int i, int j)
2290 {
2291         return i + j;
2292 }
2293
2294 LIBTEST_API gpointer STDCALL 
2295 mono_test_marshal_return_fnptr (void)
2296 {
2297         return &add_delegate;
2298 }
2299
2300 LIBTEST_API int STDCALL 
2301 mono_xr (int code)
2302 {
2303         printf ("codigo %x\n", code);
2304         return code + 1234;
2305 }
2306
2307 typedef struct {
2308         int handle;
2309 } HandleRef;
2310
2311 LIBTEST_API HandleRef STDCALL 
2312 mono_xr_as_handle (int code)
2313 {
2314         HandleRef ref;
2315
2316         memset (&ref, 0, sizeof (ref));
2317
2318         return ref;
2319 }
2320  
2321 typedef struct {
2322         int   a;
2323         void *handle1;
2324         void *handle2;
2325         int   b;
2326 } HandleStructs;
2327
2328 LIBTEST_API int STDCALL 
2329 mono_safe_handle_struct_ref (HandleStructs *x)
2330 {
2331         printf ("Dingus Ref! \n");
2332         printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2333         if (x->a != 1234)
2334                 return 1;
2335         if (x->b != 8743)
2336                 return 2;
2337
2338         if (x->handle1 != (void*) 0x7080feed)
2339                 return 3;
2340
2341         if (x->handle2 != (void*) 0x1234abcd)
2342                 return 4;
2343
2344         return 0xf00d;
2345 }
2346
2347 LIBTEST_API int STDCALL 
2348 mono_safe_handle_struct (HandleStructs x)
2349 {
2350         printf ("Dingus Standard! \n");
2351         printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2352         if (x.a != 1234)
2353                 return 1;
2354         if (x.b != 8743)
2355                 return 2;
2356
2357         if (x.handle1 != (void*) 0x7080feed)
2358                 return 3;
2359
2360         if (x.handle2 != (void*) 0x1234abcd)
2361                 return 4;
2362         
2363         return 0xf00f;
2364 }
2365
2366 typedef struct {
2367         void *a;
2368 } TrivialHandle;
2369
2370 LIBTEST_API int STDCALL 
2371 mono_safe_handle_struct_simple (TrivialHandle x)
2372 {
2373         printf ("The value is %p\n", x.a);
2374         return ((int)(gsize)x.a) * 2;
2375 }
2376
2377 LIBTEST_API int STDCALL 
2378 mono_safe_handle_return (void)
2379 {
2380         return 0x1000f00d;
2381 }
2382
2383 LIBTEST_API void STDCALL
2384 mono_safe_handle_ref (void **handle)
2385 {
2386         if (*handle != 0){
2387                 *handle = (void *) 0xbad;
2388                 return;
2389         }
2390
2391         *handle = (void *) 0x800d;
2392 }
2393
2394 LIBTEST_API double STDCALL
2395 mono_test_marshal_date_time (double d, double *d2)
2396 {
2397         *d2 = d;
2398         return d;
2399 }
2400
2401 /*
2402  * COM INTEROP TESTS
2403  */
2404
2405 #ifndef WIN32
2406
2407 typedef struct {
2408         guint16 vt;
2409         guint16 wReserved1;
2410         guint16 wReserved2;
2411         guint16 wReserved3;
2412         union {
2413                 gint64 llVal;
2414                 gint32 lVal;
2415                 guint8  bVal;
2416                 gint16 iVal;
2417                 float  fltVal;
2418                 double dblVal;
2419                 gint16 boolVal;
2420                 gunichar2* bstrVal;
2421                 gint8 cVal;
2422                 guint16 uiVal;
2423                 guint32 ulVal;
2424                 guint64 ullVal;
2425                 struct {
2426                         gpointer pvRecord;
2427                         gpointer pRecInfo;
2428                 };
2429         };
2430 } VARIANT;
2431
2432 typedef enum {
2433         VARIANT_TRUE = -1,
2434         VARIANT_FALSE = 0
2435 } VariantBool;
2436
2437 typedef enum {
2438         VT_EMPTY = 0,
2439         VT_NULL = 1,
2440         VT_I2 = 2,
2441         VT_I4 = 3,
2442         VT_R4 = 4,
2443         VT_R8 = 5,
2444         VT_CY = 6,
2445         VT_DATE = 7,
2446         VT_BSTR = 8,
2447         VT_DISPATCH = 9,
2448         VT_ERROR = 10,
2449         VT_BOOL = 11,
2450         VT_VARIANT = 12,
2451         VT_UNKNOWN = 13,
2452         VT_DECIMAL = 14,
2453         VT_I1 = 16,
2454         VT_UI1 = 17,
2455         VT_UI2 = 18,
2456         VT_UI4 = 19,
2457         VT_I8 = 20,
2458         VT_UI8 = 21,
2459         VT_INT = 22,
2460         VT_UINT = 23,
2461         VT_VOID = 24,
2462         VT_HRESULT = 25,
2463         VT_PTR = 26,
2464         VT_SAFEARRAY = 27,
2465         VT_CARRAY = 28,
2466         VT_USERDEFINED = 29,
2467         VT_LPSTR = 30,
2468         VT_LPWSTR = 31,
2469         VT_RECORD = 36,
2470         VT_FILETIME = 64,
2471         VT_BLOB = 65,
2472         VT_STREAM = 66,
2473         VT_STORAGE = 67,
2474         VT_STREAMED_OBJECT = 68,
2475         VT_STORED_OBJECT = 69,
2476         VT_BLOB_OBJECT = 70,
2477         VT_CF = 71,
2478         VT_CLSID = 72,
2479         VT_VECTOR = 4096,
2480         VT_ARRAY = 8192,
2481         VT_BYREF = 16384
2482 } VarEnum;
2483
2484 void VariantInit(VARIANT* vt)
2485 {
2486         vt->vt = VT_EMPTY;
2487 }
2488
2489 typedef struct
2490 {
2491         guint32 a;
2492         guint16 b;
2493         guint16 c;
2494         guint8 d[8];
2495 } GUID;
2496
2497 #define S_OK 0
2498
2499 #endif
2500
2501 LIBTEST_API int STDCALL 
2502 mono_test_marshal_bstr_in(gunichar2* bstr)
2503 {
2504         gint32 result = 0;
2505         gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2506         result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2507         g_free(bstr_utf8);
2508         if (result == 0)
2509                 return 0;
2510         return 1;
2511 }
2512
2513 LIBTEST_API int STDCALL 
2514 mono_test_marshal_bstr_out(gunichar2** bstr)
2515 {
2516         *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2517         return 0;
2518 }
2519
2520 LIBTEST_API int STDCALL 
2521 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2522 {
2523         if (!bstr)
2524                 return 0;
2525         return 1;
2526 }
2527
2528 LIBTEST_API int STDCALL 
2529 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2530 {
2531         *bstr = NULL;
2532         return 0;
2533 }
2534
2535 LIBTEST_API int STDCALL 
2536 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2537 {
2538         if (variant.vt == VT_I1 && variant.cVal == 100)
2539                 return 0;
2540         return 1;
2541 }
2542
2543 LIBTEST_API int STDCALL 
2544 mono_test_marshal_variant_in_byte(VARIANT variant)
2545 {
2546         if (variant.vt == VT_UI1 && variant.bVal == 100)
2547                 return 0;
2548         return 1;
2549 }
2550
2551 LIBTEST_API int STDCALL 
2552 mono_test_marshal_variant_in_short(VARIANT variant)
2553 {
2554         if (variant.vt == VT_I2 && variant.iVal == 314)
2555                 return 0;
2556         return 1;
2557 }
2558
2559 LIBTEST_API int STDCALL 
2560 mono_test_marshal_variant_in_ushort(VARIANT variant)
2561 {
2562         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2563                 return 0;
2564         return 1;
2565 }
2566
2567 LIBTEST_API int STDCALL 
2568 mono_test_marshal_variant_in_int(VARIANT variant)
2569 {
2570         if (variant.vt == VT_I4 && variant.lVal == 314)
2571                 return 0;
2572         return 1;
2573 }
2574
2575 LIBTEST_API int STDCALL 
2576 mono_test_marshal_variant_in_uint(VARIANT variant)
2577 {
2578         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2579                 return 0;
2580         return 1;
2581 }
2582
2583 LIBTEST_API int STDCALL 
2584 mono_test_marshal_variant_in_long(VARIANT variant)
2585 {
2586         if (variant.vt == VT_I8 && variant.llVal == 314)
2587                 return 0;
2588         return 1;
2589 }
2590
2591 LIBTEST_API int STDCALL 
2592 mono_test_marshal_variant_in_ulong(VARIANT variant)
2593 {
2594         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2595                 return 0;
2596         return 1;
2597 }
2598
2599 LIBTEST_API int STDCALL 
2600 mono_test_marshal_variant_in_float(VARIANT variant)
2601 {
2602         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2603                 return 0;
2604         return 1;
2605 }
2606
2607 LIBTEST_API int STDCALL 
2608 mono_test_marshal_variant_in_double(VARIANT variant)
2609 {
2610         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2611                 return 0;
2612         return 1;
2613 }
2614
2615 LIBTEST_API int STDCALL 
2616 mono_test_marshal_variant_in_bstr(VARIANT variant)
2617 {
2618         gint32 result = 0;
2619         gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2620         result = strcmp("PI", bstr_utf8);
2621         g_free(bstr_utf8);
2622
2623         if (variant.vt == VT_BSTR && !result)
2624                 return 0;
2625         return 1;
2626 }
2627
2628 LIBTEST_API int STDCALL 
2629 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2630 {
2631         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2632                 return 0;
2633         return 1;
2634 }
2635
2636 LIBTEST_API int STDCALL 
2637 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2638 {
2639         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2640                 return 0;
2641         return 1;
2642 }
2643
2644 LIBTEST_API int STDCALL 
2645 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2646 {
2647         variant->vt = VT_I1;
2648         variant->cVal = 100;
2649
2650         return 0;
2651 }
2652
2653 LIBTEST_API int STDCALL 
2654 mono_test_marshal_variant_out_byte(VARIANT* variant)
2655 {       
2656         variant->vt = VT_UI1;
2657         variant->bVal = 100;
2658
2659         return 0;
2660 }
2661
2662 LIBTEST_API int STDCALL 
2663 mono_test_marshal_variant_out_short(VARIANT* variant)
2664 {
2665         variant->vt = VT_I2;
2666         variant->iVal = 314;
2667
2668         return 0;
2669 }
2670
2671 LIBTEST_API int STDCALL 
2672 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2673 {
2674         variant->vt = VT_UI2;
2675         variant->uiVal = 314;
2676
2677         return 0;
2678 }
2679
2680 LIBTEST_API int STDCALL 
2681 mono_test_marshal_variant_out_int(VARIANT* variant)
2682 {
2683         variant->vt = VT_I4;
2684         variant->lVal = 314;
2685
2686         return 0;
2687 }
2688
2689 LIBTEST_API int STDCALL 
2690 mono_test_marshal_variant_out_uint(VARIANT* variant)
2691 {
2692         variant->vt = VT_UI4;
2693         variant->ulVal = 314;
2694
2695         return 0;
2696 }
2697
2698 LIBTEST_API int STDCALL 
2699 mono_test_marshal_variant_out_long(VARIANT* variant)
2700 {
2701         variant->vt = VT_I8;
2702         variant->llVal = 314;
2703
2704         return 0;
2705 }
2706
2707 LIBTEST_API int STDCALL 
2708 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2709 {
2710         variant->vt = VT_UI8;
2711         variant->ullVal = 314;
2712
2713         return 0;
2714 }
2715
2716 LIBTEST_API int STDCALL 
2717 mono_test_marshal_variant_out_float(VARIANT* variant)
2718 {
2719         variant->vt = VT_R4;
2720         variant->fltVal = 3.14;
2721
2722         return 0;
2723 }
2724
2725 LIBTEST_API int STDCALL 
2726 mono_test_marshal_variant_out_double(VARIANT* variant)
2727 {
2728         variant->vt = VT_R8;
2729         variant->dblVal = 3.14;
2730
2731         return 0;
2732 }
2733
2734 LIBTEST_API int STDCALL 
2735 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2736 {
2737         variant->vt = VT_BSTR;
2738         variant->bstrVal = marshal_bstr_alloc("PI");
2739
2740         return 0;
2741 }
2742
2743 LIBTEST_API int STDCALL 
2744 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2745 {
2746         variant->vt = VT_BOOL;
2747         variant->boolVal = VARIANT_TRUE;
2748
2749         return 0;
2750 }
2751
2752 LIBTEST_API int STDCALL 
2753 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
2754 {
2755         variant->vt = VT_BOOL;
2756         variant->boolVal = VARIANT_FALSE;
2757
2758         return 0;
2759 }
2760
2761 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
2762 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
2763
2764 LIBTEST_API int STDCALL 
2765 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
2766 {
2767         VARIANT vt;
2768         vt.vt = VT_I1;
2769         vt.cVal = -100;
2770         return func (VT_I1, vt);
2771 }
2772
2773 LIBTEST_API int STDCALL 
2774 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
2775 {
2776         VARIANT vt;
2777         vt.vt = VT_UI1;
2778         vt.bVal = 100;
2779         return func (VT_UI1, vt);
2780 }
2781
2782 LIBTEST_API int STDCALL 
2783 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
2784 {
2785         VARIANT vt;
2786         vt.vt = VT_I2;
2787         vt.iVal = -100;
2788         return func (VT_I2, vt);
2789 }
2790
2791 LIBTEST_API int STDCALL 
2792 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
2793 {
2794         VARIANT vt;
2795         vt.vt = VT_UI2;
2796         vt.uiVal = 100;
2797         return func (VT_UI2, vt);
2798 }
2799
2800 LIBTEST_API int STDCALL 
2801 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
2802 {
2803         VARIANT vt;
2804         vt.vt = VT_I4;
2805         vt.lVal = -100;
2806         return func (VT_I4, vt);
2807 }
2808
2809 LIBTEST_API int STDCALL 
2810 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
2811 {
2812         VARIANT vt;
2813         vt.vt = VT_UI4;
2814         vt.ulVal = 100;
2815         return func (VT_UI4, vt);
2816 }
2817
2818 LIBTEST_API int STDCALL 
2819 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
2820 {
2821         VARIANT vt;
2822         vt.vt = VT_I8;
2823         vt.llVal = -100;
2824         return func (VT_I8, vt);
2825 }
2826
2827 LIBTEST_API int STDCALL 
2828 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
2829 {
2830         VARIANT vt;
2831         vt.vt = VT_UI8;
2832         vt.ullVal = 100;
2833         return func (VT_UI8, vt);
2834 }
2835
2836 LIBTEST_API int STDCALL 
2837 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
2838 {
2839         VARIANT vt;
2840         vt.vt = VT_R4;
2841         vt.fltVal = 3.14;
2842         return func (VT_R4, vt);
2843 }
2844
2845 LIBTEST_API int STDCALL 
2846 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
2847 {
2848         VARIANT vt;
2849         vt.vt = VT_R8;
2850         vt.dblVal = 3.14;
2851         return func (VT_R8, vt);
2852 }
2853
2854 LIBTEST_API int STDCALL 
2855 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
2856 {
2857         VARIANT vt;
2858         vt.vt = VT_BSTR;
2859         vt.bstrVal = marshal_bstr_alloc("PI");
2860         return func (VT_BSTR, vt);
2861 }
2862
2863 LIBTEST_API int STDCALL 
2864 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
2865 {
2866         VARIANT vt;
2867         vt.vt = VT_BOOL;
2868         vt.boolVal = VARIANT_TRUE;
2869         return func (VT_BOOL, vt);
2870 }
2871
2872 LIBTEST_API int STDCALL 
2873 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
2874 {
2875         VARIANT vt;
2876         vt.vt = VT_BOOL;
2877         vt.boolVal = VARIANT_FALSE;
2878         return func (VT_BOOL, vt);
2879 }
2880
2881 LIBTEST_API int STDCALL 
2882 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
2883 {
2884         VARIANT vt;
2885         VariantInit (&vt);
2886         func (VT_I1, &vt);
2887         if (vt.vt == VT_I1 && vt.cVal == -100)
2888                 return 0;
2889         return 1;
2890 }
2891
2892 LIBTEST_API int STDCALL 
2893 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
2894 {
2895         VARIANT vt;
2896         VariantInit (&vt);
2897         func (VT_UI1, &vt);
2898         if (vt.vt == VT_UI1 && vt.bVal == 100)
2899                 return 0;
2900         return 1;
2901 }
2902
2903 LIBTEST_API int STDCALL 
2904 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
2905 {
2906         VARIANT vt;
2907         VariantInit (&vt);
2908         func (VT_I2, &vt);
2909         if (vt.vt == VT_I2 && vt.iVal == -100)
2910                 return 0;
2911         return 1;
2912 }
2913
2914 LIBTEST_API int STDCALL 
2915 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
2916 {
2917         VARIANT vt;
2918         VariantInit (&vt);
2919         func (VT_UI2, &vt);
2920         if (vt.vt == VT_UI2 && vt.uiVal == 100)
2921                 return 0;
2922         return 1;
2923 }
2924
2925 LIBTEST_API int STDCALL 
2926 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
2927 {
2928         VARIANT vt;
2929         VariantInit (&vt);
2930         func (VT_I4, &vt);
2931         if (vt.vt == VT_I4 && vt.lVal == -100)
2932                 return 0;
2933         return 1;
2934 }
2935
2936 LIBTEST_API int STDCALL 
2937 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
2938 {
2939         VARIANT vt;
2940         VariantInit (&vt);
2941         func (VT_UI4, &vt);
2942         if (vt.vt == VT_UI4 && vt.ulVal == 100)
2943                 return 0;
2944         return 1;
2945 }
2946
2947 LIBTEST_API int STDCALL 
2948 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
2949 {
2950         VARIANT vt;
2951         VariantInit (&vt);
2952         func (VT_I8, &vt);
2953         if (vt.vt == VT_I8 && vt.llVal == -100)
2954                 return 0;
2955         return 1;
2956 }
2957
2958 LIBTEST_API int STDCALL 
2959 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
2960 {
2961         VARIANT vt;
2962         VariantInit (&vt);
2963         func (VT_UI8, &vt);
2964         if (vt.vt == VT_UI8 && vt.ullVal == 100)
2965                 return 0;
2966         return 1;
2967 }
2968
2969 LIBTEST_API int STDCALL 
2970 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
2971 {
2972         VARIANT vt;
2973         VariantInit (&vt);
2974         func (VT_R4, &vt);
2975         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
2976                 return 0;
2977         return 1;
2978 }
2979
2980 LIBTEST_API int STDCALL 
2981 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
2982 {
2983         VARIANT vt;
2984         VariantInit (&vt);
2985         func (VT_R8, &vt);
2986         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
2987                 return 0;
2988         return 1;
2989 }
2990
2991 LIBTEST_API int STDCALL 
2992 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
2993 {
2994         VARIANT vt;
2995         gchar* bstr_utf8;
2996         gint32 result = 0;
2997
2998
2999         VariantInit (&vt);
3000         func (VT_BSTR, &vt);
3001         bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
3002         result = strcmp("PI", bstr_utf8);
3003         g_free(bstr_utf8);
3004         if (vt.vt == VT_BSTR && !result)
3005                 return 0;
3006         return 1;
3007 }
3008
3009 LIBTEST_API int STDCALL 
3010 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
3011 {
3012         VARIANT vt;
3013         VariantInit (&vt);
3014         func (VT_BOOL, &vt);
3015         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3016                 return 0;
3017         return 1;
3018 }
3019
3020 LIBTEST_API int STDCALL 
3021 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
3022 {
3023         VARIANT vt;
3024         VariantInit (&vt);
3025         func (VT_BOOL, &vt);
3026         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3027                 return 0;
3028         return 1;
3029 }
3030
3031 typedef struct MonoComObject MonoComObject;
3032
3033 typedef struct
3034 {
3035         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
3036         int (STDCALL *AddRef)(MonoComObject* pUnk);
3037         int (STDCALL *Release)(MonoComObject* pUnk);
3038         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3039         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
3040         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
3041         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
3042         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
3043         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
3044         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
3045         int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
3046         int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
3047         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
3048         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
3049         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
3050         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3051 } MonoIUnknown;
3052
3053 struct MonoComObject
3054 {
3055         MonoIUnknown* vtbl;
3056         int m_ref;
3057 };
3058
3059 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
3060 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3061 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3062
3063 LIBTEST_API int STDCALL
3064 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3065 {
3066
3067         *ppv = NULL;
3068         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3069                 *ppv = pUnk;
3070                 return S_OK;
3071         }
3072         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3073                 *ppv = pUnk;
3074                 return S_OK;
3075         }
3076         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3077                 *ppv = pUnk;
3078                 return S_OK;
3079         }
3080         return 0x80004002; //E_NOINTERFACE;
3081 }
3082
3083 LIBTEST_API int STDCALL 
3084 MonoAddRef(MonoComObject* pUnk)
3085 {
3086         return ++(pUnk->m_ref);
3087 }
3088
3089 LIBTEST_API int STDCALL 
3090 MonoRelease(MonoComObject* pUnk)
3091 {
3092         return --(pUnk->m_ref);
3093 }
3094
3095 LIBTEST_API int STDCALL 
3096 SByteIn(MonoComObject* pUnk, char a)
3097 {
3098         return S_OK;
3099 }
3100
3101 LIBTEST_API int STDCALL 
3102 ByteIn(MonoComObject* pUnk, unsigned char a)
3103 {
3104         return S_OK;
3105 }
3106
3107 LIBTEST_API int STDCALL 
3108 ShortIn(MonoComObject* pUnk, short a)
3109 {
3110         return S_OK;
3111 }
3112
3113 LIBTEST_API int STDCALL 
3114 UShortIn(MonoComObject* pUnk, unsigned short a)
3115 {
3116         return S_OK;
3117 }
3118
3119 LIBTEST_API int STDCALL 
3120 IntIn(MonoComObject* pUnk, int a)
3121 {
3122         return S_OK;
3123 }
3124
3125 LIBTEST_API int STDCALL 
3126 UIntIn(MonoComObject* pUnk, unsigned int a)
3127 {
3128         return S_OK;
3129 }
3130
3131 LIBTEST_API int STDCALL 
3132 LongIn(MonoComObject* pUnk, gint64 a)
3133 {
3134         return S_OK;
3135 }
3136
3137 LIBTEST_API int STDCALL 
3138 ULongIn(MonoComObject* pUnk, guint64 a)
3139 {
3140         return S_OK;
3141 }
3142
3143 LIBTEST_API int STDCALL 
3144 FloatIn(MonoComObject* pUnk, float a)
3145 {
3146         return S_OK;
3147 }
3148
3149 LIBTEST_API int STDCALL 
3150 DoubleIn(MonoComObject* pUnk, double a)
3151 {
3152         return S_OK;
3153 }
3154
3155 LIBTEST_API int STDCALL 
3156 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3157 {
3158         return S_OK;
3159 }
3160
3161 LIBTEST_API int STDCALL 
3162 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3163 {
3164         return S_OK;
3165 }
3166
3167 static void create_com_object (MonoComObject** pOut);
3168
3169 LIBTEST_API int STDCALL 
3170 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3171 {
3172         create_com_object (ppUnk);
3173         return S_OK;
3174 }
3175
3176 static void create_com_object (MonoComObject** pOut)
3177 {
3178         *pOut = marshal_new0 (MonoComObject, 1);
3179         (*pOut)->vtbl = marshal_new0 (MonoIUnknown, 1);
3180
3181         (*pOut)->m_ref = 1;
3182         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3183         (*pOut)->vtbl->AddRef = MonoAddRef;
3184         (*pOut)->vtbl->Release = MonoRelease;
3185         (*pOut)->vtbl->SByteIn = SByteIn;
3186         (*pOut)->vtbl->ByteIn = ByteIn;
3187         (*pOut)->vtbl->ShortIn = ShortIn;
3188         (*pOut)->vtbl->UShortIn = UShortIn;
3189         (*pOut)->vtbl->IntIn = IntIn;
3190         (*pOut)->vtbl->UIntIn = UIntIn;
3191         (*pOut)->vtbl->LongIn = LongIn;
3192         (*pOut)->vtbl->ULongIn = ULongIn;
3193         (*pOut)->vtbl->FloatIn = FloatIn;
3194         (*pOut)->vtbl->DoubleIn = DoubleIn;
3195         (*pOut)->vtbl->ITestIn = ITestIn;
3196         (*pOut)->vtbl->ITestOut = ITestOut;
3197         (*pOut)->vtbl->get_ITest = get_ITest;
3198 }
3199
3200 static MonoComObject* same_object = NULL;
3201
3202 LIBTEST_API int STDCALL 
3203 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3204 {
3205         create_com_object (pUnk);
3206
3207         if (!same_object)
3208                 same_object = *pUnk;
3209
3210         return 0;
3211 }
3212
3213 LIBTEST_API int STDCALL 
3214 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3215 {
3216         *pUnk = same_object;
3217
3218         return 0;
3219 }
3220
3221 LIBTEST_API int STDCALL 
3222 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3223 {
3224         int ref = --(pUnk->m_ref);
3225         g_free(pUnk->vtbl);
3226         g_free(pUnk);
3227
3228         return ref;
3229 }
3230
3231 LIBTEST_API int STDCALL 
3232 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3233 {
3234         return pUnk->m_ref;
3235 }
3236
3237 LIBTEST_API int STDCALL 
3238 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3239 {
3240         int hr = 0;
3241         MonoComObject* pTest;
3242
3243         if (!pUnk)
3244                 return 1;
3245
3246         hr = pUnk->vtbl->SByteIn (pUnk, -100);
3247         if (hr != 0)
3248                 return 2;
3249         hr = pUnk->vtbl->ByteIn (pUnk, 100);
3250         if (hr != 0)
3251                 return 3;
3252         hr = pUnk->vtbl->ShortIn (pUnk, -100);
3253         if (hr != 0)
3254                 return 4;
3255         hr = pUnk->vtbl->UShortIn (pUnk, 100);
3256         if (hr != 0)
3257                 return 5;
3258         hr = pUnk->vtbl->IntIn (pUnk, -100);
3259         if (hr != 0)
3260                 return 6;
3261         hr = pUnk->vtbl->UIntIn (pUnk, 100);
3262         if (hr != 0)
3263                 return 7;
3264         hr = pUnk->vtbl->LongIn (pUnk, -100);
3265         if (hr != 0)
3266                 return 8;
3267         hr = pUnk->vtbl->ULongIn (pUnk, 100);
3268         if (hr != 0)
3269                 return 9;
3270         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3271         if (hr != 0)
3272                 return 10;
3273         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3274         if (hr != 0)
3275                 return 11;
3276         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3277         if (hr != 0)
3278                 return 12;
3279         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3280         if (hr != 0)
3281                 return 13;
3282
3283         return 0;
3284 }
3285
3286 /*
3287  * mono_method_get_unmanaged_thunk tests
3288  */
3289
3290 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3291 #define ALIGN(size) __attribute__ ((aligned(size)))
3292 #else
3293 #define ALIGN(size)
3294 #endif
3295
3296
3297 /* thunks.cs:TestStruct */
3298 typedef struct _TestStruct {
3299         int A;
3300         double B;
3301 } TestStruct;
3302
3303 /* Searches for mono symbols in all loaded modules */
3304 static gpointer
3305 lookup_mono_symbol (const char *symbol_name)
3306 {
3307         gpointer symbol;
3308         if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3309                 return symbol;
3310         else
3311                 return NULL;
3312 }
3313
3314 LIBTEST_API gpointer STDCALL
3315 mono_test_marshal_lookup_symbol (const char *symbol_name)
3316 {
3317         return lookup_mono_symbol (symbol_name);
3318 }
3319
3320 /**
3321  * test_method_thunk:
3322  *
3323  * @test_id: the test number
3324  * @test_method_handle: MonoMethod* of the C# test method
3325  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3326  */
3327 LIBTEST_API int STDCALL  
3328 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3329 {
3330         gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3331                 = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3332
3333         gpointer (*mono_string_new_wrapper)(const char *)
3334                 = lookup_mono_symbol ("mono_string_new_wrapper");
3335
3336         char* (*mono_string_to_utf8)(gpointer)
3337                 = lookup_mono_symbol ("mono_string_to_utf8");
3338
3339         gpointer (*mono_object_unbox)(gpointer)
3340                 = lookup_mono_symbol ("mono_object_unbox");
3341
3342         gpointer test_method, ex = NULL;
3343         gpointer (STDCALL *CreateObject)(gpointer*);
3344
3345
3346         if (!mono_method_get_unmanaged_thunk)
3347                 return 1;
3348
3349         test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
3350         if (!test_method)
3351                 return 2;
3352
3353         CreateObject = mono_method_get_unmanaged_thunk (create_object_method_handle);
3354         if (!CreateObject)
3355                 return 3;
3356
3357
3358         switch (test_id) {
3359
3360         case 0: {
3361                 /* thunks.cs:Test.Test0 */
3362                 void (STDCALL *F)(gpointer*) = test_method;
3363                 F (&ex);
3364                 break;
3365         }
3366
3367         case 1: {
3368                 /* thunks.cs:Test.Test1 */
3369                 int (STDCALL *F)(gpointer*) = test_method;
3370                 if (F (&ex) != 42)
3371                         return 4;
3372                 break;
3373         }
3374
3375         case 2: {
3376                 /* thunks.cs:Test.Test2 */
3377                 gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
3378                 gpointer str = mono_string_new_wrapper ("foo");
3379                 if (str != F (str, &ex))
3380                         return 4;
3381                 break;
3382         }
3383
3384         case 3: {
3385                 /* thunks.cs:Test.Test3 */
3386                 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3387                 gpointer obj;
3388                 gpointer str;
3389
3390                 F = test_method;
3391                 obj = CreateObject (&ex);
3392                 str = mono_string_new_wrapper ("bar");
3393
3394                 if (str != F (obj, str, &ex))
3395                         return 4;
3396                 break;
3397         }
3398
3399         case 4: {
3400                 /* thunks.cs:Test.Test4 */
3401                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3402                 gpointer obj;
3403                 gpointer str;
3404
3405                 F = test_method;
3406                 obj = CreateObject (&ex);
3407                 str = mono_string_new_wrapper ("bar");
3408
3409                 if (42 != F (obj, str, 42, &ex))
3410                         return 4;
3411
3412                 break;
3413         }
3414
3415         case 5: {
3416                 /* thunks.cs:Test.Test5 */
3417                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3418                 gpointer obj;
3419                 gpointer str;
3420
3421                 F = test_method;
3422                 obj = CreateObject (&ex);
3423                 str = mono_string_new_wrapper ("bar");
3424
3425                 F (obj, str, 42, &ex);
3426                 if (!ex)
3427                     return 4;
3428
3429                 break;
3430         }
3431
3432         case 6: {
3433                 /* thunks.cs:Test.Test6 */
3434                 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3435                                  gpointer, gpointer*);
3436                 gpointer obj;
3437                 gpointer str = mono_string_new_wrapper ("Test6");
3438                 int res;
3439
3440                 F = test_method;
3441                 obj = CreateObject (&ex);
3442
3443                 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3444                 if (ex)
3445                         return 4;
3446
3447                 if (!res)
3448                         return 5;
3449
3450                 break;
3451         }
3452
3453         case 7: {
3454                 /* thunks.cs:Test.Test7 */
3455                 gint64 (STDCALL *F)(gpointer*) = test_method;
3456                 if (F (&ex) != G_MAXINT64)
3457                         return 4;
3458                 break;
3459         }
3460
3461         case 8: {
3462                 /* thunks.cs:Test.Test8 */
3463                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3464                                  gpointer*, gpointer*);
3465
3466                 guint8 a1;
3467                 gint16 a2;
3468                 gint32 a3;
3469                 gint64 a4;
3470                 float a5;
3471                 double a6;
3472                 gpointer a7;
3473
3474                 F = test_method;
3475
3476                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3477                 if (ex)
3478                         return 4;
3479
3480                 if (!(a1 == 254 &&
3481                       a2 == 32700 &&
3482                       a3 == -245378 &&
3483                       a4 == 6789600 &&
3484                       (fabs (a5 - 3.1415) < 0.001) &&
3485                       (fabs (a6 - 3.1415) < 0.001) &&
3486                       strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
3487                         return 5;
3488
3489                 break;
3490         }
3491
3492         case 9: {
3493                 /* thunks.cs:Test.Test9 */
3494                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3495                                  gpointer*, gpointer*);
3496
3497                 guint8 a1;
3498                 gint16 a2;
3499                 gint32 a3;
3500                 gint64 a4;
3501                 float a5;
3502                 double a6;
3503                 gpointer a7;
3504
3505                 F = test_method;
3506
3507                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3508                 if (!ex)
3509                         return 4;
3510
3511                 break;
3512         }
3513
3514         case 10: {
3515                 /* thunks.cs:Test.Test10 */
3516                 void (STDCALL *F)(gpointer*, gpointer*);
3517
3518                 gpointer obj1, obj2;
3519
3520                 obj1 = obj2 = CreateObject (&ex);
3521                 if (ex)
3522                         return 4;
3523
3524                 F = test_method;
3525
3526                 F (&obj1, &ex);
3527                 if (ex)
3528                         return 5;
3529
3530                 if (obj1 == obj2)
3531                         return 6;
3532
3533                 break;
3534         }
3535
3536         case 100: {
3537                 /* thunks.cs:TestStruct.Test0 */
3538                 int (STDCALL *F)(gpointer*, gpointer*);
3539
3540                 gpointer obj;
3541                 TestStruct *a1;
3542                 int res;
3543
3544                 obj = CreateObject (&ex);
3545                 if (ex)
3546                         return 4;
3547
3548                 if (!obj)
3549                         return 5;
3550
3551                 a1 = mono_object_unbox (obj);
3552                 if (!a1)
3553                         return 6;
3554
3555                 a1->A = 42;
3556                 a1->B = 3.1415;
3557
3558                 F = test_method;
3559
3560                 res = F (obj, &ex);
3561                 if (ex)
3562                         return 7;
3563
3564                 if (!res)
3565                         return 8;
3566
3567                 /* check whether the call was really by value */
3568                 if (a1->A != 42 || a1->B != 3.1415)
3569                         return 9;
3570
3571                 break;
3572         }
3573
3574         case 101: {
3575                 /* thunks.cs:TestStruct.Test1 */
3576                 void (STDCALL *F)(gpointer, gpointer*);
3577
3578                 TestStruct *a1;
3579                 gpointer obj;
3580
3581                 obj = CreateObject (&ex);
3582                 if (ex)
3583                         return 4;
3584
3585                 if (!obj)
3586                         return 5;
3587
3588                 a1 = mono_object_unbox (obj);
3589                 if (!a1)
3590                         return 6;
3591
3592                 F = test_method;
3593
3594                 F (obj, &ex);
3595                 if (ex)
3596                         return 7;
3597
3598                 if (a1->A != 42)
3599                         return 8;
3600
3601                 if (!fabs (a1->B - 3.1415) < 0.001)
3602                         return 9;
3603
3604                 break;
3605         }
3606
3607         case 102: {
3608                 /* thunks.cs:TestStruct.Test2 */
3609                 gpointer (STDCALL *F)(gpointer*);
3610
3611                 TestStruct *a1;
3612                 gpointer obj;
3613
3614                 F = test_method;
3615
3616                 obj = F (&ex);
3617                 if (ex)
3618                         return 4;
3619
3620                 if (!obj)
3621                         return 5;
3622
3623                 a1 = mono_object_unbox (obj);
3624
3625                 if (a1->A != 42)
3626                         return 5;
3627
3628                 if (!fabs (a1->B - 3.1415) < 0.001)
3629                         return 6;
3630
3631                 break;
3632         }
3633
3634         case 103: {
3635                 /* thunks.cs:TestStruct.Test3 */
3636                 void (STDCALL *F)(gpointer, gpointer*);
3637
3638                 TestStruct *a1;
3639                 gpointer obj;
3640
3641                 obj = CreateObject (&ex);
3642                 if (ex)
3643                         return 4;
3644
3645                 if (!obj)
3646                         return 5;
3647                 
3648                 a1 = mono_object_unbox (obj);
3649
3650                 if (!a1)
3651                         return 6;
3652
3653                 a1->A = 42;
3654                 a1->B = 3.1415;
3655
3656                 F = test_method;
3657
3658                 F (obj, &ex);
3659                 if (ex)
3660                         return 4;
3661
3662                 if (a1->A != 1)
3663                         return 5;
3664
3665                 if (a1->B != 17)
3666                         return 6;
3667
3668                 break;
3669         }
3670
3671         default:
3672                 return 9;
3673
3674         }
3675
3676         return 0;
3677 }
3678
3679 typedef struct 
3680 {
3681         char a;
3682 } winx64_struct1;
3683
3684 LIBTEST_API int STDCALL  
3685 mono_test_Winx64_struct1_in (winx64_struct1 var)
3686 {
3687         if (var.a != 123)
3688                 return 1;
3689         return 0;
3690 }
3691
3692 typedef struct
3693 {
3694         char a;
3695         char b;
3696 } winx64_struct2;
3697
3698 LIBTEST_API int STDCALL  
3699 mono_test_Winx64_struct2_in (winx64_struct2 var)
3700 {
3701         if (var.a != 4)
3702                 return 1;
3703         if (var.b != 5)
3704                 return 2;
3705         return 0;
3706 }
3707
3708
3709 typedef struct
3710 {
3711         char a;
3712         char b;
3713         short c;
3714 } winx64_struct3;
3715
3716 LIBTEST_API int STDCALL  
3717 mono_test_Winx64_struct3_in (winx64_struct3 var)
3718 {
3719         if (var.a != 4)
3720                 return 1;
3721         if (var.b != 5)
3722                 return 2;
3723         if (var.c != 0x1234)
3724                 return 3;
3725         return 0;
3726 }
3727
3728 typedef struct
3729 {
3730         char a;
3731         char b;
3732         short c;
3733         unsigned int d;
3734 } winx64_struct4;
3735
3736 LIBTEST_API int STDCALL  
3737 mono_test_Winx64_struct4_in (winx64_struct4 var)
3738 {
3739         if (var.a != 4)
3740                 return 1;
3741         if (var.b != 5)
3742                 return 2;
3743         if (var.c != 0x1234)
3744                 return 3;
3745         if (var.d != 0x87654321)
3746                 return 4;
3747         return 0;
3748 }
3749
3750 typedef struct
3751 {
3752         char a;
3753         char b;
3754         char c;
3755 } winx64_struct5;
3756
3757 LIBTEST_API int STDCALL  
3758 mono_test_Winx64_struct5_in (winx64_struct5 var)
3759 {
3760         if (var.a != 4)
3761                 return 1;
3762         if (var.b != 5)
3763                 return 2;
3764         if (var.c != 6)
3765                 return 3;
3766         return 0;
3767 }
3768
3769 typedef struct
3770 {
3771         winx64_struct1 a;
3772         short b;
3773         char c;
3774 } winx64_struct6;
3775
3776 LIBTEST_API int STDCALL  
3777 mono_test_Winx64_struct6_in (winx64_struct6 var)
3778 {
3779         if (var.a.a != 4)
3780                 return 1;
3781         if (var.b != 5)
3782                 return 2;
3783         if (var.c != 6)
3784                 return 3;
3785         return 0;
3786 }
3787
3788 LIBTEST_API int STDCALL  
3789 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
3790                          winx64_struct2 var2,
3791                          winx64_struct3 var3,
3792                          winx64_struct4 var4)
3793 {
3794         if (var1.a != 123)
3795                 return 1;
3796         
3797         if (var2.a != 4)
3798                 return 2;
3799         if (var2.b != 5)
3800                 return 3;
3801         
3802         if (var3.a != 4)
3803                 return 4;
3804         if (var3.b != 5)
3805                 return 2;
3806         if (var3.c != 0x1234)
3807                 return 5;
3808         
3809         if (var4.a != 4)
3810                 return 6;
3811         if (var4.b != 5)
3812                 return 7;
3813         if (var4.c != 0x1234)
3814                 return 8;
3815         if (var4.d != 0x87654321)
3816                 return 9;
3817         return 0;
3818 }
3819
3820 LIBTEST_API int STDCALL  
3821 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
3822                          winx64_struct1 var2,
3823                          winx64_struct1 var3,
3824                          winx64_struct1 var4,
3825                          winx64_struct1 var5)
3826 {
3827         if (var1.a != 1)
3828                 return 1;
3829         if (var2.a != 2)
3830                 return 2;
3831         if (var3.a != 3)
3832                 return 3;
3833         if (var4.a != 4)
3834                 return 4;
3835         if (var5.a != 5)
3836                 return 5;
3837         
3838         return 0;
3839 }
3840
3841 LIBTEST_API int STDCALL  
3842 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
3843                          winx64_struct5 var2,
3844                          winx64_struct1 var3,
3845                          winx64_struct5 var4,
3846                          winx64_struct1 var5,
3847                          winx64_struct5 var6)
3848 {
3849         if (var1.a != 1)
3850                 return 1;
3851         
3852         if (var2.a != 2)
3853                 return 2;
3854         if (var2.b != 3)
3855                 return 2;
3856         if (var2.c != 4)
3857                 return 4;
3858         
3859         if (var3.a != 5)
3860                 return 5;
3861         
3862         if (var4.a != 6)
3863                 return 6;
3864         if (var4.b != 7)
3865                 return 7;
3866         if (var4.c != 8)
3867                 return 8;
3868         
3869         if (var5.a != 9)
3870                 return 9;
3871
3872         if (var6.a != 10)
3873                 return 10;
3874         if (var6.b != 11)
3875                 return 11;
3876         if (var6.c != 12)
3877                 return 12;
3878         
3879         return 0;
3880 }
3881
3882 LIBTEST_API winx64_struct1 STDCALL  
3883 mono_test_Winx64_struct1_ret (void)
3884 {
3885         winx64_struct1 ret;
3886         ret.a = 123;
3887         return ret;
3888 }
3889
3890 LIBTEST_API winx64_struct2 STDCALL  
3891 mono_test_Winx64_struct2_ret (void)
3892 {
3893         winx64_struct2 ret;
3894         ret.a = 4;
3895         ret.b = 5;
3896         return ret;
3897 }
3898
3899 LIBTEST_API winx64_struct3 STDCALL  
3900 mono_test_Winx64_struct3_ret (void)
3901 {
3902         winx64_struct3 ret;
3903         ret.a = 4;
3904         ret.b = 5;
3905         ret.c = 0x1234;
3906         return ret;
3907 }
3908
3909 LIBTEST_API winx64_struct4 STDCALL  
3910 mono_test_Winx64_struct4_ret (void)
3911 {
3912         winx64_struct4 ret;
3913         ret.a = 4;
3914         ret.b = 5;
3915         ret.c = 0x1234;
3916         ret.d = 0x87654321;
3917         return ret;
3918 }
3919
3920 LIBTEST_API winx64_struct5 STDCALL  
3921 mono_test_Winx64_struct5_ret (void)
3922 {
3923         winx64_struct5 ret;
3924         ret.a = 4;
3925         ret.b = 5;
3926         ret.c = 6;
3927         return ret;
3928 }
3929
3930 LIBTEST_API winx64_struct1 STDCALL  
3931 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
3932 {
3933         winx64_struct1 ret;
3934         ret.a = a + b + c + d + e;
3935         return ret;
3936 }
3937
3938 LIBTEST_API winx64_struct5 STDCALL
3939 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
3940 {
3941         winx64_struct5 ret;
3942         ret.a = a + b;
3943         ret.b = c + d;
3944         ret.c = e;
3945         return ret;
3946 }
3947
3948 typedef struct
3949 {
3950         float a;
3951         float b;
3952 } winx64_floatStruct;
3953
3954 LIBTEST_API int STDCALL  
3955 mono_test_Winx64_floatStruct (winx64_floatStruct a)
3956 {
3957         if (a.a > 5.6 || a.a < 5.4)
3958                 return 1;
3959
3960         if (a.b > 9.6 || a.b < 9.4)
3961                 return 2;
3962         
3963         return 0;
3964 }
3965
3966 typedef struct
3967 {
3968         double a;
3969 } winx64_doubleStruct;
3970
3971 LIBTEST_API int STDCALL  
3972 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
3973 {
3974         if (a.a > 5.6 || a.a < 5.4)
3975                 return 1;
3976         
3977         return 0;
3978 }
3979
3980 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
3981
3982 LIBTEST_API int STDCALL 
3983 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
3984 {
3985         winx64_struct1 val;
3986         val.a = 5;
3987         return func (val);
3988 }
3989
3990 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
3991
3992 LIBTEST_API int STDCALL 
3993 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
3994 {
3995         winx64_struct5 val;
3996         val.a = 5;
3997         val.b = 0x10;
3998         val.c = 0x99;
3999         return func (val);
4000 }
4001
4002 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
4003                                                          winx64_struct1 c, winx64_struct5 d,
4004                                                          winx64_struct1 e, winx64_struct5 f);
4005
4006 LIBTEST_API int STDCALL 
4007 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
4008 {
4009         winx64_struct1 a, c, e;
4010         winx64_struct5 b, d, f;
4011         a.a = 1;
4012         b.a = 2; b.b = 3; b.c = 4;
4013         c.a = 5;
4014         d.a = 6; d.b = 7; d.c = 8;
4015         e.a = 9;
4016         f.a = 10; f.b = 11; f.c = 12;
4017
4018         return func (a, b, c, d, e, f);
4019 }
4020
4021 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
4022
4023 LIBTEST_API int STDCALL 
4024 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
4025 {
4026         winx64_struct1 ret;
4027
4028         ret = func ();
4029
4030         if (ret.a != 0x45)
4031                 return 1;
4032         
4033         return 0;
4034 }
4035
4036 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
4037
4038 LIBTEST_API int STDCALL 
4039 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
4040 {
4041         winx64_struct5 ret;
4042
4043         ret = func ();
4044
4045         if (ret.a != 0x12)
4046                 return 1;
4047         if (ret.b != 0x34)
4048                 return 2;
4049         if (ret.c != 0x56)
4050                 return 3;
4051         
4052         return 0;
4053 }
4054
4055 LIBTEST_API int STDCALL 
4056 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
4057                            char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
4058 {
4059         switch (arg) {
4060         case 1: 
4061                 if (bDefaultMarsh != expected)
4062                         return 1;
4063                 break;
4064         case 2: 
4065                 if (bBoolCustMarsh != expected)
4066                         return 2;
4067                 break;
4068         case 3: 
4069                 if (bI1CustMarsh != expected)
4070                         return 3;
4071                 break;
4072         case 4: 
4073                 if (bU1CustMarsh != expected)
4074                         return 4;
4075                 break;
4076         case 5: 
4077                 if (bVBCustMarsh != expected)
4078                         return 5;
4079                 break;
4080         default:
4081                 return 999;             
4082         }
4083         return 0;
4084 }
4085
4086 LIBTEST_API int STDCALL 
4087 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4088                            char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4089 {
4090         switch (arg) {
4091         case 1: 
4092                 if (!bDefaultMarsh)
4093                         return 1;
4094                 *bDefaultMarsh = testVal;
4095                 break;  
4096         case 2: 
4097                 if (!bBoolCustMarsh)
4098                         return 2;
4099                 *bBoolCustMarsh = testVal;
4100                 break;  
4101         case 3: 
4102                 if (!bI1CustMarsh)
4103                         return 3;
4104                 *bI1CustMarsh = (char)testVal;
4105                 break;  
4106         case 4: 
4107                 if (!bU1CustMarsh)
4108                         return 4;
4109                 *bU1CustMarsh = (unsigned char)testVal;
4110                 break;  
4111         case 5: 
4112                 if (!bVBCustMarsh)
4113                         return 5;
4114                 *bVBCustMarsh = (unsigned short)testVal;
4115                 break;  
4116         default:
4117                 return 999;
4118         }
4119         return 0;
4120 }
4121
4122 LIBTEST_API int STDCALL 
4123 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4124                             unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, 
4125                             unsigned short* bVBCustMarsh)
4126 {
4127         switch (arg) {
4128         case 1: 
4129                 if (!bDefaultMarsh)
4130                         return 1;
4131                 if (*bDefaultMarsh != expected)
4132                         return 2;
4133                 *bDefaultMarsh = testVal;
4134                 break;
4135         case 2: 
4136                 if (!bBoolCustMarsh)
4137                         return 3;
4138                 if (*bBoolCustMarsh != expected)
4139                         return 4;
4140                 *bBoolCustMarsh = testVal;
4141                 break;
4142         case 3: 
4143                 if (!bI1CustMarsh)
4144                         return 5;
4145                 if (*bI1CustMarsh != expected)
4146                         return 6;
4147                 *bI1CustMarsh = (char)testVal;
4148                 break;
4149         case 4: 
4150                 if (!bU1CustMarsh)
4151                         return 7;
4152                 if (*bU1CustMarsh != expected)
4153                         return 8;
4154                 *bU1CustMarsh = (unsigned char)testVal;
4155                 break;
4156         case 5: 
4157                 if (!bVBCustMarsh)
4158                         return 9;
4159                 if (*bVBCustMarsh != expected)
4160                         return 10;
4161                 *bVBCustMarsh = (unsigned short)testVal;
4162                 break;
4163         default:
4164                 return 999;             
4165         }
4166         return 0;
4167 }
4168
4169
4170 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4171         unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4172
4173 LIBTEST_API int STDCALL 
4174 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4175 {
4176         if (!pfcn)
4177                 return 0x9900;
4178
4179         switch (arg) {
4180         case 1:
4181                 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4182         case 2:
4183                 return pfcn (arg, expected, 0, testVal,  0, 0, 0);
4184         case 3:
4185                 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4186         case 4:
4187                 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4188         case 5:
4189                 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4190         default:
4191                 return 0x9800;
4192         }
4193
4194         return 0;
4195 }
4196
4197 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4198         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4199
4200 LIBTEST_API int STDCALL 
4201 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4202 {
4203         int ret;
4204         unsigned int lDefaultMarsh, lBoolCustMarsh;
4205         char lI1CustMarsh = 0;
4206         unsigned char lU1CustMarsh = 0;
4207         unsigned short lVBCustMarsh = 0;
4208         lDefaultMarsh = lBoolCustMarsh = 0;
4209
4210         if (!pfcn)
4211                 return 0x9900;
4212
4213         switch (arg) {
4214         case 1: {
4215                 unsigned int ltVal = 0;
4216                 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4217                 if (ret)
4218                         return 0x0100 + ret;
4219                 if (expected != ltVal)
4220                         return 0x0200;
4221                 break;
4222         }
4223         case 2: {
4224                 unsigned int ltVal = 0;
4225                 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4226                 if (ret)
4227                         return 0x0300 + ret;
4228                 if (expected != ltVal)
4229                         return 0x0400;
4230                 break;
4231         }
4232         case 3: {
4233                 char ltVal = 0;
4234                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4235                 if (ret)
4236                         return 0x0500 + ret;
4237                 if (expected != ltVal)
4238                         return 0x0600;
4239                 break;
4240         }
4241         case 4: {
4242                 unsigned char ltVal = 0;
4243                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4244                 if (ret)
4245                         return 0x0700 + ret;
4246                 if (expected != ltVal)
4247                         return 0x0800;
4248                 break;
4249         }
4250         case 5: {
4251                 unsigned short ltVal = 0;
4252                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4253                 if (ret)
4254                         return 0x0900 + ret;
4255                 if (expected != ltVal)
4256                         return 0x1000;
4257                 break;
4258         }
4259         default:
4260                 return 0x9800;
4261         }
4262
4263         return 0;
4264 }
4265
4266 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4267         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4268
4269 LIBTEST_API int STDCALL 
4270 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4271                                     unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4272 {
4273         int ret;
4274         unsigned int lDefaultMarsh, lBoolCustMarsh;
4275         char lI1CustMarsh = 0;
4276         unsigned char lU1CustMarsh = 0;
4277         unsigned short lVBCustMarsh = 0;
4278         lDefaultMarsh = lBoolCustMarsh = 0;
4279
4280         if (!pfcn)
4281                 return 0x9900;
4282
4283         switch (arg) {
4284         case 1:
4285         {
4286                 unsigned int ltestVal = testVal;
4287                 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4288                 if (ret)
4289                         return 0x0100 + ret;
4290                 if (outExpected != ltestVal)
4291                         return 0x0200;
4292                 break;
4293         }
4294         case 2:
4295         {
4296                 unsigned int ltestVal = testVal;
4297                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4298                 if (ret)
4299                         return 0x0300 + ret;
4300                 if (outExpected != ltestVal)
4301                         return 0x0400;
4302                 break;
4303         }
4304         case 3:
4305         {
4306                 char ltestVal = testVal;
4307                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4308                 if (ret)
4309                         return 0x0500 + ret;
4310                 if (outExpected != ltestVal)
4311                         return 0x0600;
4312                 break;
4313         }
4314         case 4:
4315         {
4316                 unsigned char ltestVal = testVal;
4317                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4318                 if (ret)
4319                         return 0x0700 + ret;
4320                 if (outExpected != ltestVal)
4321                         return 0x0800;
4322                 break;
4323         }
4324         case 5:
4325         {
4326                 unsigned short ltestVal = testVal;
4327                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4328                 if (ret)
4329                         return 0x0900 + ret;
4330                 if (outExpected != ltestVal)
4331                         return 0x1000;
4332                 break;
4333         }
4334         default:
4335                 return 0x9800;
4336         }
4337
4338         return 0;
4339 }
4340
4341 #ifdef WIN32
4342
4343 LIBTEST_API int STDCALL 
4344 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4345 {
4346         /* Create an empty one-dimensional array of variants */
4347         SAFEARRAY *pSA;
4348         SAFEARRAYBOUND dimensions [1];
4349
4350         dimensions [0].lLbound = 0;
4351         dimensions [0].cElements = 0;
4352
4353         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4354         *safearray = pSA;
4355         return S_OK;
4356 }
4357
4358 LIBTEST_API int STDCALL 
4359 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4360 {
4361         /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4362         SAFEARRAY *pSA;
4363         SAFEARRAYBOUND dimensions [1];
4364         long i;
4365         gchar buffer [20];
4366         HRESULT hr = S_OK;
4367         long indices [1];
4368
4369         dimensions [0].lLbound = 0;
4370         dimensions [0].cElements = 10;
4371
4372         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4373         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4374                 VARIANT vOut;
4375                 VariantInit (&vOut);
4376                 vOut.vt = VT_BSTR;
4377                 _ltoa (i,buffer,10);
4378                 vOut.bstrVal= marshal_bstr_alloc (buffer);
4379                 indices [0] = i;
4380                 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4381                         VariantClear (&vOut);
4382                         SafeArrayDestroy (pSA);
4383                         return hr;
4384                 }
4385                 VariantClear (&vOut);
4386         }
4387         *safearray = pSA;
4388         return hr;
4389 }
4390
4391 LIBTEST_API int STDCALL 
4392 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
4393 {
4394         /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4395         SAFEARRAY *pSA;
4396         SAFEARRAYBOUND dimensions [2];
4397         long i, j;
4398         HRESULT hr = S_OK;
4399         long indices [2];
4400
4401         dimensions [0].lLbound = 0;
4402         dimensions [0].cElements = 4;
4403         dimensions [1].lLbound = 0;
4404         dimensions [1].cElements = 3;
4405
4406         pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4407         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4408                 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4409                         VARIANT vOut;
4410                         VariantInit (&vOut);
4411                         vOut.vt = VT_I4;
4412                         vOut.lVal = (i+1)*10+(j+1);
4413                         indices [0] = i;
4414                         indices [1] = j;
4415                         if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4416                                 VariantClear (&vOut);
4417                                 SafeArrayDestroy (pSA);
4418                                 return hr;
4419                         }
4420                         VariantClear (&vOut);  // does a deep destroy of source VARIANT 
4421                 }
4422         }
4423         *safearray = pSA;
4424         return hr;
4425 }
4426
4427 LIBTEST_API int STDCALL 
4428 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
4429 {
4430         /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4431         /* Also use non zero lower bounds                                                 */
4432         SAFEARRAY *pSA;
4433         SAFEARRAYBOUND dimensions [4];
4434         long i;
4435         HRESULT hr = S_OK;
4436         VARIANT *pData;
4437
4438         dimensions [0].lLbound = 15;
4439         dimensions [0].cElements = 10;
4440         dimensions [1].lLbound = 20;
4441         dimensions [1].cElements = 3;
4442         dimensions [2].lLbound = 5;
4443         dimensions [2].cElements = 6;
4444         dimensions [3].lLbound = 12;
4445         dimensions [3].cElements = 7;
4446
4447         pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4448
4449         SafeArrayAccessData (pSA, (void **)&pData);
4450
4451         for (i= 0; i< 10*3*6*7; i++) {
4452                 VariantInit(&pData [i]);
4453                 pData [i].vt = VT_I4;
4454                 pData [i].lVal = i;
4455         }
4456         SafeArrayUnaccessData (pSA);
4457         *safearray = pSA;
4458         return hr;
4459 }
4460
4461 LIBTEST_API int STDCALL 
4462 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
4463 {
4464         /* Check that array is one dimensional and empty */
4465
4466         UINT dim;
4467         long lbound, ubound;
4468         
4469         dim = SafeArrayGetDim (safearray);
4470         if (dim != 1)
4471                 return 1;
4472
4473         SafeArrayGetLBound (safearray, 1, &lbound);
4474         SafeArrayGetUBound (safearray, 1, &ubound);
4475
4476         if ((lbound > 0) || (ubound > 0))
4477                 return 1;
4478
4479         return 0;
4480 }
4481
4482 LIBTEST_API int STDCALL 
4483 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4484 {
4485         /* Check that array is one dimensional containing integers from 1 to 10 */
4486
4487         UINT dim;
4488         long lbound, ubound;
4489         VARIANT *pData; 
4490         long i;
4491         int result=0;
4492
4493         dim = SafeArrayGetDim (safearray);
4494         if (dim != 1)
4495                 return 1;
4496
4497         SafeArrayGetLBound (safearray, 1, &lbound);
4498         SafeArrayGetUBound (safearray, 1, &ubound);
4499
4500         if ((lbound != 0) || (ubound != 9))
4501                 return 1;
4502
4503         SafeArrayAccessData (safearray, (void **)&pData);
4504         for (i= lbound; i <= ubound; i++) {
4505                 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
4506                         result = 1;
4507         }
4508         SafeArrayUnaccessData (safearray);
4509
4510         return result;
4511 }
4512
4513 LIBTEST_API int STDCALL 
4514 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
4515 {
4516         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4517
4518         UINT dim;
4519         long lbound, ubound;
4520         VARIANT *pData; 
4521         long i;
4522         long indices [1];
4523         VARIANT element;
4524         int result=0;
4525
4526         VariantInit (&element);
4527
4528         dim = SafeArrayGetDim (safearray);
4529         if (dim != 1)
4530                 return 1;
4531
4532         SafeArrayGetLBound (safearray, 1, &lbound);
4533         SafeArrayGetUBound (safearray, 1, &ubound);
4534                 
4535         if ((lbound != 0) || (ubound != 12))
4536                 return 1;
4537
4538         SafeArrayAccessData (safearray, (void **)&pData);
4539         for (i= lbound; i <= ubound; i++) {
4540                 if ((i%2 == 0) && (pData [i].vt != VT_I4))
4541                         result = 1;
4542                 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
4543                         result = 1;
4544                 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
4545                         result = 1;
4546         }
4547         SafeArrayUnaccessData (safearray);
4548
4549         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4550
4551         indices [0] = 0;
4552         element.vt = VT_I4;
4553         element.lVal = 333;
4554         SafeArrayPutElement (safearray, indices, &element);
4555         VariantClear (&element);
4556
4557         return result;
4558 }
4559
4560 LIBTEST_API int STDCALL 
4561 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
4562 {
4563         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4564
4565         UINT dim;
4566         long lbound1, ubound1, lbound2, ubound2;
4567         long i, j, failed;
4568         long indices [2];
4569         VARIANT element;
4570
4571         VariantInit (&element);
4572
4573         dim = SafeArrayGetDim (safearray);
4574         if (dim != 2)
4575                 return 1;
4576
4577         SafeArrayGetLBound (safearray, 1, &lbound1);
4578         SafeArrayGetUBound (safearray, 1, &ubound1);
4579
4580         if ((lbound1 != 0) || (ubound1 != 1))
4581                 return 1;
4582
4583         SafeArrayGetLBound (safearray, 2, &lbound2);
4584         SafeArrayGetUBound (safearray, 2, &ubound2);
4585
4586         if ((lbound2 != 0) || (ubound2 != 3)) {
4587                 return 1;
4588         }
4589
4590         for (i= lbound1; i <= ubound1; i++) {
4591                 indices [0] = i;
4592                 for (j= lbound2; j <= ubound2; j++) {
4593                         indices [1] = j;
4594                         if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4595                                 return 1;
4596                         failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
4597                         VariantClear (&element);
4598                         if (failed)
4599                                 return 1;
4600                 }
4601         }
4602
4603         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4604
4605         indices [0] = 0;
4606         indices [1] = 0;
4607         element.vt = VT_I4;
4608         element.lVal = 333;
4609         SafeArrayPutElement (safearray, indices, &element);
4610         VariantClear (&element);
4611
4612         return 0;
4613 }
4614
4615 LIBTEST_API int STDCALL 
4616 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
4617 {
4618         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4619
4620         UINT dim;
4621         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4622         long i, j, k, failed;
4623         long indices [3];
4624         VARIANT element;
4625
4626         VariantInit (&element);
4627
4628         dim = SafeArrayGetDim (safearray);
4629         if (dim != 3)
4630                 return 1;
4631
4632         SafeArrayGetLBound (safearray, 1, &lbound1);
4633         SafeArrayGetUBound (safearray, 1, &ubound1);
4634
4635         if ((lbound1 != 0) || (ubound1 != 1))
4636                 return 1;
4637
4638         SafeArrayGetLBound (safearray, 2, &lbound2);
4639         SafeArrayGetUBound (safearray, 2, &ubound2);
4640
4641         if ((lbound2 != 0) || (ubound2 != 1))
4642                 return 1;
4643
4644         SafeArrayGetLBound (safearray, 3, &lbound3);
4645         SafeArrayGetUBound (safearray, 3, &ubound3);
4646
4647         if ((lbound3 != 0) || (ubound3 != 2))
4648                 return 1;
4649
4650         for (i= lbound1; i <= ubound1; i++) {
4651                 indices [0] = i;
4652                 for (j= lbound2; j <= ubound2; j++) {
4653                         indices [1] = j;
4654                 for (k= lbound3; k <= ubound3; k++) {
4655                                 indices [2] = k;
4656                                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4657                                         return 1;
4658                                 failed = ((element.vt != VT_BSTR) 
4659                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
4660                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4661                                 VariantClear (&element);
4662                                 if (failed)
4663                                         return 1;
4664                         }
4665                 }
4666         }
4667
4668         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4669
4670         indices [0] = 0;
4671         indices [1] = 0;
4672         indices [2] = 0;
4673         element.vt = VT_BSTR;
4674         element.bstrVal = SysAllocString(L"Should not be copied");
4675         SafeArrayPutElement (safearray, indices, &element);
4676         VariantClear (&element);
4677
4678         return 0;
4679 }
4680
4681 LIBTEST_API int STDCALL 
4682 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
4683 {
4684         return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
4685 }
4686
4687 LIBTEST_API int STDCALL 
4688 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
4689 {
4690         /* Check that the input array is what is expected and change it so the caller can check */
4691         /* correct marshalling back to managed code                                             */
4692
4693         UINT dim;
4694         long lbound, ubound;
4695         SAFEARRAYBOUND dimensions [1];
4696         long i;
4697         wchar_t buffer [20];
4698         HRESULT hr = S_OK;
4699         long indices [1];
4700
4701         /* Check that in array is one dimensional and empty */
4702
4703         dim = SafeArrayGetDim (*safearray);
4704         if (dim != 1) {
4705                 return 1;
4706         }
4707
4708         SafeArrayGetLBound (*safearray, 1, &lbound);
4709         SafeArrayGetUBound (*safearray, 1, &ubound);
4710                 
4711         if ((lbound > 0) || (ubound > 0)) {
4712                 return 1;
4713         }
4714
4715         /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
4716
4717         dimensions [0].lLbound = 0;
4718         dimensions [0].cElements = 8;
4719
4720         hr = SafeArrayRedim (*safearray, dimensions);
4721         if (hr != S_OK)
4722                 return 1;
4723
4724         for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
4725                 VARIANT vOut;
4726                 VariantInit (&vOut);
4727                 vOut.vt = VT_BSTR;
4728                 _ltow (i,buffer,10);
4729                 vOut.bstrVal = SysAllocString (buffer);
4730                 indices [0] = i;
4731                 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
4732                         VariantClear (&vOut);
4733                         SafeArrayDestroy (*safearray);
4734                         return hr;
4735                 }
4736                 VariantClear (&vOut);
4737         }
4738         return hr;
4739 }
4740
4741 LIBTEST_API int STDCALL 
4742 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
4743 {
4744         /* Check that the input array is what is expected and change it so the caller can check */
4745         /* correct marshalling back to managed code                                             */
4746
4747         UINT dim;
4748         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4749         SAFEARRAYBOUND dimensions [1];
4750         long i, j, k, failed;
4751         wchar_t buffer [20];
4752         HRESULT hr = S_OK;
4753         long indices [3];
4754         VARIANT element;
4755
4756         VariantInit (&element);
4757
4758         /* Check that in array is three dimensional and contains the expected values */
4759
4760         dim = SafeArrayGetDim (*safearray);
4761         if (dim != 3)
4762                 return 1;
4763
4764         SafeArrayGetLBound (*safearray, 1, &lbound1);
4765         SafeArrayGetUBound (*safearray, 1, &ubound1);
4766
4767         if ((lbound1 != 0) || (ubound1 != 1))
4768                 return 1;
4769
4770         SafeArrayGetLBound (*safearray, 2, &lbound2);
4771         SafeArrayGetUBound (*safearray, 2, &ubound2);
4772
4773         if ((lbound2 != 0) || (ubound2 != 1))
4774                 return 1;
4775
4776         SafeArrayGetLBound (*safearray, 3, &lbound3);
4777         SafeArrayGetUBound (*safearray, 3, &ubound3);
4778
4779         if ((lbound3 != 0) || (ubound3 != 2))
4780                 return 1;
4781
4782         for (i= lbound1; i <= ubound1; i++) {
4783                 indices [0] = i;
4784                 for (j= lbound2; j <= ubound2; j++) {
4785                         indices [1] = j;
4786                         for (k= lbound3; k <= ubound3; k++) {
4787                                 indices [2] = k;
4788                                 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
4789                                         return 1;
4790                                 failed = ((element.vt != VT_BSTR) 
4791                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
4792                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4793                                 VariantClear (&element);
4794                                 if (failed)
4795                                         return 1;
4796                         }
4797                 }
4798         }
4799
4800         hr = SafeArrayDestroy (*safearray);
4801         if (hr != S_OK)
4802                 return 1;
4803
4804         /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
4805
4806         dimensions [0].lLbound = 0;
4807         dimensions [0].cElements = 8;
4808
4809         *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
4810
4811         for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
4812                 VARIANT vOut;
4813                 VariantInit (&vOut);
4814                 vOut.vt = VT_BSTR;
4815                 _ltow (i,buffer,10);
4816                 vOut.bstrVal = SysAllocString (buffer);
4817                 indices [0] = i;
4818                 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
4819                         VariantClear (&vOut);
4820                         SafeArrayDestroy (*safearray);
4821                         return hr;
4822                 }
4823                 VariantClear (&vOut);
4824         }
4825         return hr;
4826 }
4827
4828 LIBTEST_API int STDCALL 
4829 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
4830 {
4831         /* Check that the input array is what is expected and change it so the caller can check */
4832         /* correct marshalling back to managed code                                             */
4833
4834         UINT dim;
4835         long lbound1, ubound1;
4836         long i, failed;
4837         HRESULT hr = S_OK;
4838         long indices [1];
4839         VARIANT element;
4840         
4841         VariantInit (&element);
4842
4843         /* Check that in array is one dimensional and contains the expected value */
4844
4845         dim = SafeArrayGetDim (*safearray);
4846         if (dim != 1)
4847                 return 1;
4848
4849         SafeArrayGetLBound (*safearray, 1, &lbound1);
4850         SafeArrayGetUBound (*safearray, 1, &ubound1);
4851
4852         ubound1 = 1;
4853         if ((lbound1 != 0) || (ubound1 != 1))
4854                 return 1;
4855         ubound1 = 0;
4856
4857         for (i= lbound1; i <= ubound1; i++) {
4858                 indices [0] = i;
4859                 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
4860                         return 1;
4861                 failed = (element.vt != VT_I4) || (element.lVal != i+1);
4862                 VariantClear (&element);
4863                 if (failed)
4864                         return 1;
4865         }
4866
4867         /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
4868
4869         indices [0] = 0;
4870         element.vt = VT_I4;
4871         element.lVal = -1;
4872         SafeArrayPutElement (*safearray, indices, &element);
4873         VariantClear (&element);
4874
4875         return hr;
4876 }
4877
4878 LIBTEST_API int STDCALL 
4879 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4880 {
4881         /* Check that the input array is what is expected and change it so the caller can check */
4882         /* correct marshalling back to managed code                                             */
4883
4884         UINT dim;
4885         long lbound1, ubound1;
4886         SAFEARRAYBOUND dimensions [1];
4887         long i, failed;
4888         HRESULT hr = S_OK;
4889         long indices [1];
4890         VARIANT element;
4891
4892         VariantInit (&element);
4893
4894         /* Check that in array is one dimensional and contains the expected value */
4895
4896         dim = SafeArrayGetDim (safearray);
4897         if (dim != 1)
4898                 return 1;
4899
4900         SafeArrayGetLBound (safearray, 1, &lbound1);
4901         SafeArrayGetUBound (safearray, 1, &ubound1);
4902                 
4903         if ((lbound1 != 0) || (ubound1 != 0))
4904                 return 1;
4905
4906         for (i= lbound1; i <= ubound1; i++) {
4907                 indices [0] = i;
4908                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4909                         return 1;
4910                 failed = (element.vt != VT_I4) || (element.lVal != i+1);
4911                 VariantClear (&element);
4912                 if (failed)
4913                         return 1;
4914         }
4915
4916         /* Change the array to verify how [out] parameter is marshalled back to the managed side */
4917
4918         /* Redimension the array */
4919         dimensions [0].lLbound = lbound1;
4920         dimensions [0].cElements = 2;
4921         hr = SafeArrayRedim(safearray, dimensions);
4922
4923         indices [0] = 0;
4924         element.vt = VT_I4;
4925         element.lVal = 12345;
4926         SafeArrayPutElement (safearray, indices, &element);
4927         VariantClear (&element);
4928
4929         indices [0] = 1;
4930         element.vt = VT_I4;
4931         element.lVal = -12345;
4932         SafeArrayPutElement (safearray, indices, &element);
4933         VariantClear (&element);
4934
4935         return hr;
4936 }
4937
4938 LIBTEST_API int STDCALL 
4939 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
4940 {
4941         /* Check that the input array is what is expected and change it so the caller can check */
4942         /* correct marshalling back to managed code                                             */
4943
4944         UINT dim;
4945         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4946         long i, j, k, failed;
4947         HRESULT hr = S_OK;
4948         long indices [3];
4949         VARIANT element;
4950
4951         VariantInit (&element);
4952
4953         /* Check that in array is three dimensional and contains the expected values */
4954
4955         dim = SafeArrayGetDim (safearray);
4956         if (dim != 3)
4957                 return 1;
4958
4959         SafeArrayGetLBound (safearray, 1, &lbound1);
4960         SafeArrayGetUBound (safearray, 1, &ubound1);
4961
4962         if ((lbound1 != 0) || (ubound1 != 1))
4963                 return 1;
4964
4965         SafeArrayGetLBound (safearray, 2, &lbound2);
4966         SafeArrayGetUBound (safearray, 2, &ubound2);
4967
4968         if ((lbound2 != 0) || (ubound2 != 1))
4969                 return 1;
4970
4971         SafeArrayGetLBound (safearray, 3, &lbound3);
4972         SafeArrayGetUBound (safearray, 3, &ubound3);
4973
4974         if ((lbound3 != 0) || (ubound3 != 2))
4975                 return 1;
4976
4977         for (i= lbound1; i <= ubound1; i++) {
4978                 indices [0] = i;
4979                 for (j= lbound2; j <= ubound2; j++) {
4980                         indices [1] = j;
4981                         for (k= lbound3; k <= ubound3; k++) {
4982                                 indices [2] = k;
4983                                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4984                                         return 1;
4985                                 failed = ((element.vt != VT_BSTR) 
4986                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
4987                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
4988                                 VariantClear (&element);
4989                                 if (failed)
4990                                         return 1;
4991                         }
4992                 }
4993         }
4994
4995         /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
4996
4997         indices [0] = 1;
4998         indices [1] = 1;
4999         indices [2] = 2;
5000         element.vt = VT_I4;
5001         element.lVal = 333;
5002         SafeArrayPutElement (safearray, indices, &element);
5003         VariantClear (&element);
5004
5005         indices [0] = 1;
5006         indices [1] = 1;
5007         indices [2] = 1;
5008         element.vt = VT_I4;
5009         element.lVal = 111;
5010         SafeArrayPutElement (safearray, indices, &element);
5011         VariantClear (&element);
5012
5013         indices [0] = 0;
5014         indices [1] = 1;
5015         indices [2] = 0;
5016         element.vt = VT_BSTR;
5017         element.bstrVal = marshal_bstr_alloc("ABCDEFG");
5018         SafeArrayPutElement (safearray, indices, &element);
5019         VariantClear (&element);
5020
5021         return hr;
5022 }
5023
5024 LIBTEST_API int STDCALL 
5025 mono_test_marshal_safearray_mixed(
5026                 SAFEARRAY  *safearray1,
5027                 SAFEARRAY **safearray2,
5028                 SAFEARRAY  *safearray3,
5029                 SAFEARRAY **safearray4
5030                 )
5031 {
5032         HRESULT hr = S_OK;
5033
5034         /* Initialize out parameters */
5035         *safearray2 = NULL;
5036
5037         /* array1: Check that in array is one dimensional and contains the expected value */
5038         hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
5039
5040         /* array2: Fill in with some values to check on the managed side */
5041         if (hr == S_OK)
5042                 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
5043
5044         /* array3: Check that in array is one dimensional and contains the expected value */
5045         if (hr == S_OK)
5046                 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
5047
5048         /* array4: Check input values and fill in with some values to check on the managed side */
5049         if (hr == S_OK)
5050                 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
5051
5052         return hr;
5053 }
5054
5055 #endif
5056
5057 static int call_managed_res;
5058
5059 static void
5060 call_managed (gpointer arg)
5061 {
5062         SimpleDelegate del = arg;
5063
5064         call_managed_res = del (42);
5065 }
5066
5067 LIBTEST_API int STDCALL 
5068 mono_test_marshal_thread_attach (SimpleDelegate del)
5069 {
5070 #ifdef WIN32
5071         return 43;
5072 #else
5073         int res;
5074         pthread_t t;
5075
5076         res = pthread_create (&t, NULL, (gpointer)call_managed, del);
5077         g_assert (res == 0);
5078         pthread_join (t, NULL);
5079
5080         return call_managed_res;
5081 #endif
5082 }
5083
5084 typedef int (STDCALL *Callback) (void);
5085
5086 static Callback callback;
5087
5088 LIBTEST_API void STDCALL 
5089 mono_test_marshal_set_callback (Callback cb)
5090 {
5091         callback = cb;
5092 }
5093
5094 LIBTEST_API int STDCALL 
5095 mono_test_marshal_call_callback (void)
5096 {
5097         return callback ();
5098 }
5099
5100 LIBTEST_API int STDCALL
5101 mono_test_marshal_lpstr (char *str)
5102 {
5103         return strcmp ("ABC", str);
5104 }
5105
5106 LIBTEST_API int STDCALL
5107 mono_test_marshal_lpwstr (gunichar2 *str)
5108 {
5109         char *s;
5110         int res;
5111
5112         s = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
5113         res = strcmp ("ABC", s);
5114         g_free (s);
5115
5116         return res;
5117 }
5118
5119 LIBTEST_API char* STDCALL
5120 mono_test_marshal_return_lpstr (void)
5121 {
5122         char *res = marshal_alloc (4);
5123         strcpy (res, "XYZ");
5124         return res;
5125 }
5126
5127
5128 LIBTEST_API gunichar2* STDCALL
5129 mono_test_marshal_return_lpwstr (void)
5130 {
5131         gunichar2 *res = marshal_alloc (8);
5132         gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
5133
5134         memcpy (res, tmp, 8);
5135         g_free (tmp);
5136
5137         return res;
5138 }