2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
29 #include "wine/debug.h"
31 #include "mshtml_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
36 * This object wraps any unrecognized interface overriding its IUnknown methods, allowing
37 * us to return external interface from our QI implementation preserving COM rules.
38 * This can't be done right and it seems to be broken by design.
41 IUnknown IUnknown_iface
;
47 static inline iface_wrapper_t
*impl_from_IUnknown(IUnknown
*iface
)
49 return CONTAINING_RECORD(iface
, iface_wrapper_t
, IUnknown_iface
);
52 static HRESULT WINAPI
wrapper_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
54 iface_wrapper_t
*This
= impl_from_IUnknown(iface
);
56 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
58 return IUnknown_QueryInterface(This
->ref_unk
, riid
, ppv
);
61 static ULONG WINAPI
wrapper_AddRef(IUnknown
*iface
)
63 iface_wrapper_t
*This
= impl_from_IUnknown(iface
);
64 LONG ref
= InterlockedIncrement(&This
->ref
);
66 TRACE("(%p) ref=%d\n", This
, ref
);
71 static ULONG WINAPI
wrapper_Release(IUnknown
*iface
)
73 iface_wrapper_t
*This
= impl_from_IUnknown(iface
);
74 LONG ref
= InterlockedDecrement(&This
->ref
);
76 TRACE("(%p) ref=%d\n", This
, ref
);
79 IUnknown_Release(This
->iface
);
80 IUnknown_Release(This
->ref_unk
);
89 #define DEFINE_WRAPPER_FUNC(n, off, x) \
90 HRESULT wrapper_func_##n(IUnknown*); \
91 __ASM_GLOBAL_FUNC(wrapper_func_##n, \
92 "movl 4(%esp), %eax\n\t" \
93 "movl 4(%eax), %eax\n\t" \
94 "movl %eax, 4(%esp)\n\t" \
95 "movl 0(%eax), %eax\n\t" \
96 "jmp *" #off "(%eax)\n\t")
98 #elif defined(__x86_64__)
100 #define DEFINE_WRAPPER_FUNC(n, x, off) \
101 HRESULT WINAPI wrapper_func_##n(IUnknown*); \
102 __ASM_GLOBAL_FUNC(wrapper_func_##n, \
103 "movq 8(%rcx), %rcx\n\t" \
104 "movq 0(%rcx), %rax\n\t" \
105 "jmp *" #off "(%rax)\n\t")
109 #define DEFINE_WRAPPER_FUNC(n, x, off) \
110 static HRESULT WINAPI wrapper_func_##n(IUnknown *iface) { \
111 ERR("Not implemented for this architecture\n"); \
117 /* DEFINE_WRAPPER_FUNC takes 3 arguments: index in vtbl, 32-bit offset in vtbl and 64-bit offset in vtbl */
118 DEFINE_WRAPPER_FUNC(3, 12, 24)
119 DEFINE_WRAPPER_FUNC(4, 16, 32)
120 DEFINE_WRAPPER_FUNC(5, 20, 40)
121 DEFINE_WRAPPER_FUNC(6, 24, 48)
122 DEFINE_WRAPPER_FUNC(7, 28, 56)
123 DEFINE_WRAPPER_FUNC(8, 32, 64)
124 DEFINE_WRAPPER_FUNC(9, 36, 72)
125 DEFINE_WRAPPER_FUNC(10, 40, 80)
126 DEFINE_WRAPPER_FUNC(11, 44, 88)
127 DEFINE_WRAPPER_FUNC(12, 48, 96)
128 DEFINE_WRAPPER_FUNC(13, 52, 104)
129 DEFINE_WRAPPER_FUNC(14, 56, 112)
130 DEFINE_WRAPPER_FUNC(15, 60, 120)
131 DEFINE_WRAPPER_FUNC(16, 64, 128)
132 DEFINE_WRAPPER_FUNC(17, 68, 136)
133 DEFINE_WRAPPER_FUNC(18, 72, 144)
134 DEFINE_WRAPPER_FUNC(19, 76, 152)
135 DEFINE_WRAPPER_FUNC(20, 80, 160)
136 DEFINE_WRAPPER_FUNC(21, 84, 168)
137 DEFINE_WRAPPER_FUNC(22, 88, 176)
138 DEFINE_WRAPPER_FUNC(23, 92, 184)
139 DEFINE_WRAPPER_FUNC(24, 96, 192)
140 DEFINE_WRAPPER_FUNC(25, 100, 200)
141 DEFINE_WRAPPER_FUNC(26, 104, 208)
142 DEFINE_WRAPPER_FUNC(27, 108, 216)
143 DEFINE_WRAPPER_FUNC(28, 112, 224)
144 DEFINE_WRAPPER_FUNC(29, 116, 232)
145 DEFINE_WRAPPER_FUNC(30, 120, 240)
146 DEFINE_WRAPPER_FUNC(31, 124, 248)
147 DEFINE_WRAPPER_FUNC(32, 128, 256)
148 DEFINE_WRAPPER_FUNC(33, 132, 264)
149 DEFINE_WRAPPER_FUNC(34, 136, 272)
150 DEFINE_WRAPPER_FUNC(35, 140, 280)
151 DEFINE_WRAPPER_FUNC(36, 144, 288)
152 DEFINE_WRAPPER_FUNC(37, 148, 296)
153 DEFINE_WRAPPER_FUNC(38, 152, 304)
154 DEFINE_WRAPPER_FUNC(39, 156, 312)
155 DEFINE_WRAPPER_FUNC(40, 160, 320)
156 DEFINE_WRAPPER_FUNC(41, 164, 328)
157 DEFINE_WRAPPER_FUNC(42, 168, 336)
158 DEFINE_WRAPPER_FUNC(43, 172, 344)
159 DEFINE_WRAPPER_FUNC(44, 176, 352)
160 DEFINE_WRAPPER_FUNC(45, 180, 360)
161 DEFINE_WRAPPER_FUNC(46, 184, 368)
162 DEFINE_WRAPPER_FUNC(47, 188, 376)
163 DEFINE_WRAPPER_FUNC(48, 192, 384)
164 DEFINE_WRAPPER_FUNC(49, 196, 392)
165 DEFINE_WRAPPER_FUNC(50, 200, 400)
166 DEFINE_WRAPPER_FUNC(51, 204, 408)
167 DEFINE_WRAPPER_FUNC(52, 208, 416)
168 DEFINE_WRAPPER_FUNC(53, 212, 424)
169 DEFINE_WRAPPER_FUNC(54, 216, 432)
170 DEFINE_WRAPPER_FUNC(55, 220, 440)
171 DEFINE_WRAPPER_FUNC(56, 224, 448)
172 DEFINE_WRAPPER_FUNC(57, 228, 456)
173 DEFINE_WRAPPER_FUNC(58, 232, 464)
174 DEFINE_WRAPPER_FUNC(59, 236, 472)
175 DEFINE_WRAPPER_FUNC(60, 240, 480)
176 DEFINE_WRAPPER_FUNC(61, 244, 488)
177 DEFINE_WRAPPER_FUNC(62, 248, 496)
178 DEFINE_WRAPPER_FUNC(63, 252, 504)
179 DEFINE_WRAPPER_FUNC(64, 256, 512)
180 DEFINE_WRAPPER_FUNC(65, 260, 520)
181 DEFINE_WRAPPER_FUNC(66, 264, 528)
182 DEFINE_WRAPPER_FUNC(67, 268, 536)
183 DEFINE_WRAPPER_FUNC(68, 272, 544)
184 DEFINE_WRAPPER_FUNC(69, 276, 552)
185 DEFINE_WRAPPER_FUNC(70, 280, 560)
186 DEFINE_WRAPPER_FUNC(71, 284, 568)
187 DEFINE_WRAPPER_FUNC(72, 288, 576)
188 DEFINE_WRAPPER_FUNC(73, 292, 584)
189 DEFINE_WRAPPER_FUNC(74, 296, 592)
190 DEFINE_WRAPPER_FUNC(75, 300, 600)
191 DEFINE_WRAPPER_FUNC(76, 304, 608)
192 DEFINE_WRAPPER_FUNC(77, 308, 616)
193 DEFINE_WRAPPER_FUNC(78, 312, 624)
194 DEFINE_WRAPPER_FUNC(79, 316, 632)
195 DEFINE_WRAPPER_FUNC(80, 320, 640)
196 DEFINE_WRAPPER_FUNC(81, 324, 648)
197 DEFINE_WRAPPER_FUNC(82, 328, 656)
198 DEFINE_WRAPPER_FUNC(83, 332, 664)
199 DEFINE_WRAPPER_FUNC(84, 336, 672)
200 DEFINE_WRAPPER_FUNC(85, 340, 680)
201 DEFINE_WRAPPER_FUNC(86, 344, 688)
202 DEFINE_WRAPPER_FUNC(87, 348, 696)
203 DEFINE_WRAPPER_FUNC(88, 352, 704)
204 DEFINE_WRAPPER_FUNC(89, 356, 712)
205 DEFINE_WRAPPER_FUNC(90, 360, 720)
206 DEFINE_WRAPPER_FUNC(91, 364, 728)
207 DEFINE_WRAPPER_FUNC(92, 368, 736)
208 DEFINE_WRAPPER_FUNC(93, 372, 744)
209 DEFINE_WRAPPER_FUNC(94, 376, 752)
210 DEFINE_WRAPPER_FUNC(95, 380, 760)
211 DEFINE_WRAPPER_FUNC(96, 384, 768)
212 DEFINE_WRAPPER_FUNC(97, 388, 776)
213 DEFINE_WRAPPER_FUNC(98, 392, 784)
214 DEFINE_WRAPPER_FUNC(99, 396, 792)
216 /* The size was found by testing when calls start crashing. It looks like MS wraps up to 100 functions. */
217 static const struct {
218 IUnknownVtbl unk_vtbl
;
219 const void *wrappers
[97];
222 wrapper_QueryInterface
,
326 HRESULT
wrap_iface(IUnknown
*iface
, IUnknown
*ref_unk
, IUnknown
**ret
)
328 iface_wrapper_t
*wrapper
;
330 wrapper
= heap_alloc(sizeof(*wrapper
));
332 return E_OUTOFMEMORY
;
334 wrapper
->IUnknown_iface
.lpVtbl
= &wrapper_vtbl
.unk_vtbl
;
337 IUnknown_AddRef(iface
);
338 wrapper
->iface
= iface
;
340 IUnknown_AddRef(ref_unk
);
341 wrapper
->ref_unk
= ref_unk
;
343 *ret
= &wrapper
->IUnknown_iface
;