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