Add
[mono.git] / support / supportw.c
1 /*
2  * Helper routines for some of the common methods that people P/Invoke
3  * on their applications.
4  *
5  * Authors:
6  *   Gonzalo Paniagua (gonzalo@ximian.com)
7  *   Miguel de Icaza  (miguel@novell.com)
8  *
9  * (C) 2005 Novell, Inc.
10  *
11  */
12 #include <glib.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include "supportw.h"
17 #include "mono/metadata/assembly.h"
18 #include "mono/metadata/class.h"
19 #include "mono/metadata/object.h"
20 #include "mono/metadata/tabledefs.h"
21 #include "mono/io-layer/wapi.h"
22 #include <limits.h>    /* for PAGESIZE */
23 #ifndef PAGESIZE
24 #define PAGESIZE 4096
25 #endif
26
27 typedef struct {
28         const char *fname;
29         void *fnptr;
30 } FnPtr;
31
32 gpointer FindWindowExW        (gpointer hwndParent, gpointer hwndChildAfter,
33                                const char *classw, const char *window);
34
35 gpointer GetProcessHeap       (void);
36
37 static FnPtr functions [] = {
38         { "FindWindowExW", NULL }, /* user32 */
39 };
40 #define NFUNCTIONS      (sizeof (functions)/sizeof (FnPtr))
41
42 static int swf_registered;
43
44 static int
45 compare_names (const void *key, const void *p)
46 {
47         FnPtr *ptr = (FnPtr *) p;
48         return strcmp (key, ptr->fname);
49 }
50
51 static gpointer
52 get_function (const char *name)
53 {
54         FnPtr *ptr;
55
56         ptr = bsearch (name, functions, NFUNCTIONS, sizeof (FnPtr),
57                         compare_names);
58
59         if (ptr == NULL) {
60                 g_warning ("Function '%s' not not found.", name);
61                 return NULL;
62         }
63
64         return ptr->fnptr;
65 }
66
67 gboolean
68 supportw_register_delegate (const char *function_name, void *fnptr)
69 {
70         FnPtr *ptr;
71
72         g_return_val_if_fail (function_name && fnptr, FALSE);
73
74         ptr = bsearch (function_name, functions, NFUNCTIONS, sizeof (FnPtr),
75                         compare_names);
76
77         if (ptr == NULL) {
78                 g_warning ("Function '%s' not supported.", function_name);
79                 return FALSE;
80         }
81
82         ptr->fnptr = fnptr;
83         return TRUE;
84 }
85
86 #define M_ATTRS (METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_STATIC)
87 static gboolean
88 register_assembly (const char *name, int *registered)
89 {
90 /* we can't use mono or wapi funcions in a support lib */
91 #if 0
92         MonoAssembly *assembly;
93         MonoImageOpenStatus status;
94         MonoImage *image;
95         MonoClass *klass;
96         MonoMethod *method;
97         MonoObject *exc;
98
99         if (*registered)
100                 return TRUE;
101
102         assembly = mono_assembly_load_with_partial_name (name, &status);
103         if (assembly == NULL) {
104                 g_warning ("Cannot load assembly '%s'.", name);
105                 return FALSE;
106         }
107
108         image = mono_assembly_get_image (assembly);
109         klass = mono_class_from_name (image, name, "LibSupport");
110         if (klass == NULL) {
111                 g_warning ("Cannot load class %s.LibSupport", name);
112                 mono_assembly_close (assembly);
113                 return FALSE;
114         }
115
116         method = mono_class_get_method_from_name_flags (klass, "Register", 0, M_ATTRS);
117         if (klass == NULL) {
118                 g_warning ("Cannot load method Register from klass %s.LibSupport", name);
119                 mono_assembly_close (assembly);
120                 return FALSE;
121         }
122
123         exc = NULL;
124         mono_runtime_invoke (method, NULL, NULL, &exc);
125         if (exc != NULL) {
126                 mono_assembly_close (assembly);
127                 mono_print_unhandled_exception (exc);
128                 return FALSE;
129         }
130         *registered = 1;
131         mono_assembly_close (assembly);
132         return TRUE;
133 #else
134         return FALSE;
135 #endif
136 }
137
138 void
139 supportw_test_all ()
140 {
141         int i;
142
143         register_assembly ("System.Windows.Forms", &swf_registered);
144         for (i = 0; i < NFUNCTIONS; i++) {
145                 FnPtr *ptr = &functions [i];
146                 if (ptr->fnptr == NULL)
147                         g_warning ("%s wasn't registered.", ptr->fname);
148         }
149 }
150
151 gpointer
152 FindWindowExW (gpointer hwndParent, gpointer hwndChildAfter, const char *classw, const char *window)
153 {
154         typedef gpointer (*func_type) (gpointer hwndParent, gpointer hwndChildAfter,
155                                         const char *classw, const char *window);
156         static func_type func;
157
158         g_return_val_if_fail (register_assembly ("System.Windows.Forms", &swf_registered), NULL);
159         if (func == NULL)
160                 func = (func_type) get_function ("FindWindowExW");
161
162         return func (hwndParent, hwndChildAfter, classw, window);
163 }
164
165