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