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