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