mshtml: Added noscript tag handling tests.
[wine] / dlls / mshtml / ifacewrap.c
1 /*
2  * Copyright 2011 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
29
30 #include "wine/debug.h"
31
32 #include "mshtml_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
35
36 /*
37  * This object wraps any unrecognized interface overriding its IUnknown methods, allowing
38  * us to return external interface from our QI implementation preserving COM rules.
39  * This can't be done right and it seems to be broken by design.
40  */
41 typedef struct {
42     IUnknown IUnknown_iface;
43     IUnknown *iface;
44     IUnknown *ref_unk;
45     LONG ref;
46 } iface_wrapper_t;
47
48 static inline iface_wrapper_t *impl_from_IUnknown(IUnknown *iface)
49 {
50     return CONTAINING_RECORD(iface, iface_wrapper_t, IUnknown_iface);
51 }
52
53 static HRESULT WINAPI wrapper_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
54 {
55     iface_wrapper_t *This = impl_from_IUnknown(iface);
56
57     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
58
59     return IUnknown_QueryInterface(This->ref_unk, riid, ppv);
60 }
61
62 static HRESULT WINAPI wrapper_AddRef(IUnknown *iface)
63 {
64     iface_wrapper_t *This = impl_from_IUnknown(iface);
65     LONG ref = InterlockedIncrement(&This->ref);
66
67     TRACE("(%p) ref=%d\n", This, ref);
68
69     return ref;
70 }
71
72 static HRESULT WINAPI wrapper_Release(IUnknown *iface)
73 {
74     iface_wrapper_t *This = impl_from_IUnknown(iface);
75     LONG ref = InterlockedDecrement(&This->ref);
76
77     TRACE("(%p) ref=%d\n", This, ref);
78
79     if(!ref) {
80         IUnknown_Release(This->iface);
81         IUnknown_Release(This->ref_unk);
82         heap_free(This);
83     }
84
85     return ref;
86 }
87
88 #ifdef __i386__
89
90 #define DEFINE_WRAPPER_FUNC(n, off, x)          \
91     HRESULT wrapper_func_##n(IUnknown*);        \
92     __ASM_GLOBAL_FUNC(wrapper_func_##n,         \
93         "movl 4(%esp), %eax\n\t"                \
94         "movl 4(%eax), %eax\n\t"                \
95         "movl %eax, 4(%esp)\n\t"                \
96         "movl 0(%eax), %eax\n\t"                \
97         "jmp *" #off "(%eax)\n\t")
98
99 #elif defined(__x86_64__)
100
101 #define DEFINE_WRAPPER_FUNC(n, x, off)          \
102     HRESULT WINAPI wrapper_func_##n(IUnknown*); \
103     __ASM_GLOBAL_FUNC(wrapper_func_##n,         \
104         "movq 8(%rcx), %rcx\n\t"                \
105         "movq 0(%rcx), %rax\n\t"                \
106         "jmp *" #off "(%rax)\n\t")
107
108 #else
109
110 #define DEFINE_WRAPPER_FUNC(n, x, off)                           \
111     static HRESULT WINAPI wrapper_func_##n(IUnknown *iface) {    \
112         ERR("Not implemented for this architecture\n");          \
113         return E_NOTIMPL;                                        \
114     }
115
116 #endif
117
118 /* DEFINE_WRAPPER_FUNC takes 3 arguments: index in vtbl, 32-bit offset in vtbl and 64-bit offset in vtbl */
119 DEFINE_WRAPPER_FUNC(3, 12, 24)
120 DEFINE_WRAPPER_FUNC(4, 16, 32)
121 DEFINE_WRAPPER_FUNC(5, 20, 40)
122 DEFINE_WRAPPER_FUNC(6, 24, 48)
123 DEFINE_WRAPPER_FUNC(7, 28, 56)
124 DEFINE_WRAPPER_FUNC(8, 32, 64)
125 DEFINE_WRAPPER_FUNC(9, 36, 72)
126 DEFINE_WRAPPER_FUNC(10, 40, 80)
127 DEFINE_WRAPPER_FUNC(11, 44, 88)
128 DEFINE_WRAPPER_FUNC(12, 48, 96)
129 DEFINE_WRAPPER_FUNC(13, 52, 104)
130 DEFINE_WRAPPER_FUNC(14, 56, 112)
131 DEFINE_WRAPPER_FUNC(15, 60, 120)
132 DEFINE_WRAPPER_FUNC(16, 64, 128)
133 DEFINE_WRAPPER_FUNC(17, 68, 136)
134 DEFINE_WRAPPER_FUNC(18, 72, 144)
135 DEFINE_WRAPPER_FUNC(19, 76, 152)
136 DEFINE_WRAPPER_FUNC(20, 80, 160)
137 DEFINE_WRAPPER_FUNC(21, 84, 168)
138 DEFINE_WRAPPER_FUNC(22, 88, 176)
139 DEFINE_WRAPPER_FUNC(23, 92, 184)
140 DEFINE_WRAPPER_FUNC(24, 96, 192)
141 DEFINE_WRAPPER_FUNC(25, 100, 200)
142 DEFINE_WRAPPER_FUNC(26, 104, 208)
143 DEFINE_WRAPPER_FUNC(27, 108, 216)
144 DEFINE_WRAPPER_FUNC(28, 112, 224)
145 DEFINE_WRAPPER_FUNC(29, 116, 232)
146 DEFINE_WRAPPER_FUNC(30, 120, 240)
147 DEFINE_WRAPPER_FUNC(31, 124, 248)
148 DEFINE_WRAPPER_FUNC(32, 128, 256)
149 DEFINE_WRAPPER_FUNC(33, 132, 264)
150 DEFINE_WRAPPER_FUNC(34, 136, 272)
151 DEFINE_WRAPPER_FUNC(35, 140, 280)
152 DEFINE_WRAPPER_FUNC(36, 144, 288)
153 DEFINE_WRAPPER_FUNC(37, 148, 296)
154 DEFINE_WRAPPER_FUNC(38, 152, 304)
155 DEFINE_WRAPPER_FUNC(39, 156, 312)
156 DEFINE_WRAPPER_FUNC(40, 160, 320)
157 DEFINE_WRAPPER_FUNC(41, 164, 328)
158 DEFINE_WRAPPER_FUNC(42, 168, 336)
159 DEFINE_WRAPPER_FUNC(43, 172, 344)
160 DEFINE_WRAPPER_FUNC(44, 176, 352)
161 DEFINE_WRAPPER_FUNC(45, 180, 360)
162 DEFINE_WRAPPER_FUNC(46, 184, 368)
163 DEFINE_WRAPPER_FUNC(47, 188, 376)
164 DEFINE_WRAPPER_FUNC(48, 192, 384)
165 DEFINE_WRAPPER_FUNC(49, 196, 392)
166 DEFINE_WRAPPER_FUNC(50, 200, 400)
167 DEFINE_WRAPPER_FUNC(51, 204, 408)
168 DEFINE_WRAPPER_FUNC(52, 208, 416)
169 DEFINE_WRAPPER_FUNC(53, 212, 424)
170 DEFINE_WRAPPER_FUNC(54, 216, 432)
171 DEFINE_WRAPPER_FUNC(55, 220, 440)
172 DEFINE_WRAPPER_FUNC(56, 224, 448)
173 DEFINE_WRAPPER_FUNC(57, 228, 456)
174 DEFINE_WRAPPER_FUNC(58, 232, 464)
175 DEFINE_WRAPPER_FUNC(59, 236, 472)
176 DEFINE_WRAPPER_FUNC(60, 240, 480)
177 DEFINE_WRAPPER_FUNC(61, 244, 488)
178 DEFINE_WRAPPER_FUNC(62, 248, 496)
179 DEFINE_WRAPPER_FUNC(63, 252, 504)
180 DEFINE_WRAPPER_FUNC(64, 256, 512)
181 DEFINE_WRAPPER_FUNC(65, 260, 520)
182 DEFINE_WRAPPER_FUNC(66, 264, 528)
183 DEFINE_WRAPPER_FUNC(67, 268, 536)
184 DEFINE_WRAPPER_FUNC(68, 272, 544)
185 DEFINE_WRAPPER_FUNC(69, 276, 552)
186 DEFINE_WRAPPER_FUNC(70, 280, 560)
187 DEFINE_WRAPPER_FUNC(71, 284, 568)
188 DEFINE_WRAPPER_FUNC(72, 288, 576)
189 DEFINE_WRAPPER_FUNC(73, 292, 584)
190 DEFINE_WRAPPER_FUNC(74, 296, 592)
191 DEFINE_WRAPPER_FUNC(75, 300, 600)
192 DEFINE_WRAPPER_FUNC(76, 304, 608)
193 DEFINE_WRAPPER_FUNC(77, 308, 616)
194 DEFINE_WRAPPER_FUNC(78, 312, 624)
195 DEFINE_WRAPPER_FUNC(79, 316, 632)
196 DEFINE_WRAPPER_FUNC(80, 320, 640)
197 DEFINE_WRAPPER_FUNC(81, 324, 648)
198 DEFINE_WRAPPER_FUNC(82, 328, 656)
199 DEFINE_WRAPPER_FUNC(83, 332, 664)
200 DEFINE_WRAPPER_FUNC(84, 336, 672)
201 DEFINE_WRAPPER_FUNC(85, 340, 680)
202 DEFINE_WRAPPER_FUNC(86, 344, 688)
203 DEFINE_WRAPPER_FUNC(87, 348, 696)
204 DEFINE_WRAPPER_FUNC(88, 352, 704)
205 DEFINE_WRAPPER_FUNC(89, 356, 712)
206 DEFINE_WRAPPER_FUNC(90, 360, 720)
207 DEFINE_WRAPPER_FUNC(91, 364, 728)
208 DEFINE_WRAPPER_FUNC(92, 368, 736)
209 DEFINE_WRAPPER_FUNC(93, 372, 744)
210 DEFINE_WRAPPER_FUNC(94, 376, 752)
211 DEFINE_WRAPPER_FUNC(95, 380, 760)
212 DEFINE_WRAPPER_FUNC(96, 384, 768)
213 DEFINE_WRAPPER_FUNC(97, 388, 776)
214 DEFINE_WRAPPER_FUNC(98, 392, 784)
215 DEFINE_WRAPPER_FUNC(99, 396, 792)
216
217 /* The size was found by testing when calls start crashing. It looks like MS wraps up to 100 functions. */
218 static const void *wrapper_vtbl[] = {
219     wrapper_QueryInterface,
220     wrapper_AddRef,
221     wrapper_Release,
222     wrapper_func_3,
223     wrapper_func_4,
224     wrapper_func_5,
225     wrapper_func_6,
226     wrapper_func_7,
227     wrapper_func_8,
228     wrapper_func_9,
229     wrapper_func_10,
230     wrapper_func_11,
231     wrapper_func_12,
232     wrapper_func_13,
233     wrapper_func_14,
234     wrapper_func_15,
235     wrapper_func_16,
236     wrapper_func_17,
237     wrapper_func_18,
238     wrapper_func_19,
239     wrapper_func_20,
240     wrapper_func_21,
241     wrapper_func_22,
242     wrapper_func_23,
243     wrapper_func_24,
244     wrapper_func_25,
245     wrapper_func_26,
246     wrapper_func_27,
247     wrapper_func_28,
248     wrapper_func_29,
249     wrapper_func_30,
250     wrapper_func_31,
251     wrapper_func_32,
252     wrapper_func_33,
253     wrapper_func_34,
254     wrapper_func_35,
255     wrapper_func_36,
256     wrapper_func_37,
257     wrapper_func_38,
258     wrapper_func_39,
259     wrapper_func_40,
260     wrapper_func_41,
261     wrapper_func_42,
262     wrapper_func_43,
263     wrapper_func_44,
264     wrapper_func_45,
265     wrapper_func_46,
266     wrapper_func_47,
267     wrapper_func_48,
268     wrapper_func_49,
269     wrapper_func_50,
270     wrapper_func_51,
271     wrapper_func_52,
272     wrapper_func_53,
273     wrapper_func_54,
274     wrapper_func_55,
275     wrapper_func_56,
276     wrapper_func_57,
277     wrapper_func_58,
278     wrapper_func_59,
279     wrapper_func_60,
280     wrapper_func_61,
281     wrapper_func_62,
282     wrapper_func_63,
283     wrapper_func_64,
284     wrapper_func_65,
285     wrapper_func_66,
286     wrapper_func_67,
287     wrapper_func_68,
288     wrapper_func_69,
289     wrapper_func_70,
290     wrapper_func_71,
291     wrapper_func_72,
292     wrapper_func_73,
293     wrapper_func_74,
294     wrapper_func_75,
295     wrapper_func_76,
296     wrapper_func_77,
297     wrapper_func_78,
298     wrapper_func_79,
299     wrapper_func_80,
300     wrapper_func_81,
301     wrapper_func_82,
302     wrapper_func_83,
303     wrapper_func_84,
304     wrapper_func_85,
305     wrapper_func_86,
306     wrapper_func_87,
307     wrapper_func_88,
308     wrapper_func_89,
309     wrapper_func_90,
310     wrapper_func_91,
311     wrapper_func_92,
312     wrapper_func_93,
313     wrapper_func_94,
314     wrapper_func_95,
315     wrapper_func_96,
316     wrapper_func_97,
317     wrapper_func_98,
318     wrapper_func_99
319 };
320
321 HRESULT wrap_iface(IUnknown *iface, IUnknown *ref_unk, IUnknown **ret)
322 {
323     iface_wrapper_t *wrapper;
324
325     wrapper = heap_alloc(sizeof(*wrapper));
326     if(!wrapper)
327         return E_OUTOFMEMORY;
328
329     wrapper->IUnknown_iface.lpVtbl = (const IUnknownVtbl*)wrapper_vtbl;
330     wrapper->ref = 1;
331
332     IUnknown_AddRef(iface);
333     wrapper->iface = iface;
334
335     IUnknown_AddRef(ref_unk);
336     wrapper->ref_unk = ref_unk;
337
338     *ret = &wrapper->IUnknown_iface;
339     return S_OK;
340 }