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 */ 27 typedef struct { 28 IUnknown IUnknown_iface; 29 IUnknown *iface; 30 IUnknown *ref_unk; 31 LONG ref; 32 } iface_wrapper_t; 33 34 static inline iface_wrapper_t *impl_from_IUnknown(IUnknown *iface) 35 { 36 return CONTAINING_RECORD(iface, iface_wrapper_t, IUnknown_iface); 37 } 38 39 static HRESULT WINAPI wrapper_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) 40 { 41 iface_wrapper_t *This = impl_from_IUnknown(iface); 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 48 static HRESULT WINAPI wrapper_AddRef(IUnknown *iface) 49 { 50 iface_wrapper_t *This = impl_from_IUnknown(iface); 51 LONG ref = InterlockedIncrement(&This->ref); 52 53 TRACE("(%p) ref=%d\n", This, ref); 54 55 return ref; 56 } 57 58 static HRESULT WINAPI wrapper_Release(IUnknown *iface) 59 { 60 iface_wrapper_t *This = impl_from_IUnknown(iface); 61 LONG ref = InterlockedDecrement(&This->ref); 62 63 TRACE("(%p) ref=%d\n", This, ref); 64 65 if(!ref) { 66 IUnknown_Release(This->iface); 67 IUnknown_Release(This->ref_unk); 68 heap_free(This); 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 */ 109 DEFINE_WRAPPER_FUNC(3, 12, 24) 110 DEFINE_WRAPPER_FUNC(4, 16, 32) 111 DEFINE_WRAPPER_FUNC(5, 20, 40) 112 DEFINE_WRAPPER_FUNC(6, 24, 48) 113 DEFINE_WRAPPER_FUNC(7, 28, 56) 114 DEFINE_WRAPPER_FUNC(8, 32, 64) 115 DEFINE_WRAPPER_FUNC(9, 36, 72) 116 DEFINE_WRAPPER_FUNC(10, 40, 80) 117 DEFINE_WRAPPER_FUNC(11, 44, 88) 118 DEFINE_WRAPPER_FUNC(12, 48, 96) 119 DEFINE_WRAPPER_FUNC(13, 52, 104) 120 DEFINE_WRAPPER_FUNC(14, 56, 112) 121 DEFINE_WRAPPER_FUNC(15, 60, 120) 122 DEFINE_WRAPPER_FUNC(16, 64, 128) 123 DEFINE_WRAPPER_FUNC(17, 68, 136) 124 DEFINE_WRAPPER_FUNC(18, 72, 144) 125 DEFINE_WRAPPER_FUNC(19, 76, 152) 126 DEFINE_WRAPPER_FUNC(20, 80, 160) 127 DEFINE_WRAPPER_FUNC(21, 84, 168) 128 DEFINE_WRAPPER_FUNC(22, 88, 176) 129 DEFINE_WRAPPER_FUNC(23, 92, 184) 130 DEFINE_WRAPPER_FUNC(24, 96, 192) 131 DEFINE_WRAPPER_FUNC(25, 100, 200) 132 DEFINE_WRAPPER_FUNC(26, 104, 208) 133 DEFINE_WRAPPER_FUNC(27, 108, 216) 134 DEFINE_WRAPPER_FUNC(28, 112, 224) 135 DEFINE_WRAPPER_FUNC(29, 116, 232) 136 DEFINE_WRAPPER_FUNC(30, 120, 240) 137 DEFINE_WRAPPER_FUNC(31, 124, 248) 138 DEFINE_WRAPPER_FUNC(32, 128, 256) 139 DEFINE_WRAPPER_FUNC(33, 132, 264) 140 DEFINE_WRAPPER_FUNC(34, 136, 272) 141 DEFINE_WRAPPER_FUNC(35, 140, 280) 142 DEFINE_WRAPPER_FUNC(36, 144, 288) 143 DEFINE_WRAPPER_FUNC(37, 148, 296) 144 DEFINE_WRAPPER_FUNC(38, 152, 304) 145 DEFINE_WRAPPER_FUNC(39, 156, 312) 146 DEFINE_WRAPPER_FUNC(40, 160, 320) 147 DEFINE_WRAPPER_FUNC(41, 164, 328) 148 DEFINE_WRAPPER_FUNC(42, 168, 336) 149 DEFINE_WRAPPER_FUNC(43, 172, 344) 150 DEFINE_WRAPPER_FUNC(44, 176, 352) 151 DEFINE_WRAPPER_FUNC(45, 180, 360) 152 DEFINE_WRAPPER_FUNC(46, 184, 368) 153 DEFINE_WRAPPER_FUNC(47, 188, 376) 154 DEFINE_WRAPPER_FUNC(48, 192, 384) 155 DEFINE_WRAPPER_FUNC(49, 196, 392) 156 DEFINE_WRAPPER_FUNC(50, 200, 400) 157 DEFINE_WRAPPER_FUNC(51, 204, 408) 158 DEFINE_WRAPPER_FUNC(52, 208, 416) 159 DEFINE_WRAPPER_FUNC(53, 212, 424) 160 DEFINE_WRAPPER_FUNC(54, 216, 432) 161 DEFINE_WRAPPER_FUNC(55, 220, 440) 162 DEFINE_WRAPPER_FUNC(56, 224, 448) 163 DEFINE_WRAPPER_FUNC(57, 228, 456) 164 DEFINE_WRAPPER_FUNC(58, 232, 464) 165 DEFINE_WRAPPER_FUNC(59, 236, 472) 166 DEFINE_WRAPPER_FUNC(60, 240, 480) 167 DEFINE_WRAPPER_FUNC(61, 244, 488) 168 DEFINE_WRAPPER_FUNC(62, 248, 496) 169 DEFINE_WRAPPER_FUNC(63, 252, 504) 170 DEFINE_WRAPPER_FUNC(64, 256, 512) 171 DEFINE_WRAPPER_FUNC(65, 260, 520) 172 DEFINE_WRAPPER_FUNC(66, 264, 528) 173 DEFINE_WRAPPER_FUNC(67, 268, 536) 174 DEFINE_WRAPPER_FUNC(68, 272, 544) 175 DEFINE_WRAPPER_FUNC(69, 276, 552) 176 DEFINE_WRAPPER_FUNC(70, 280, 560) 177 DEFINE_WRAPPER_FUNC(71, 284, 568) 178 DEFINE_WRAPPER_FUNC(72, 288, 576) 179 DEFINE_WRAPPER_FUNC(73, 292, 584) 180 DEFINE_WRAPPER_FUNC(74, 296, 592) 181 DEFINE_WRAPPER_FUNC(75, 300, 600) 182 DEFINE_WRAPPER_FUNC(76, 304, 608) 183 DEFINE_WRAPPER_FUNC(77, 308, 616) 184 DEFINE_WRAPPER_FUNC(78, 312, 624) 185 DEFINE_WRAPPER_FUNC(79, 316, 632) 186 DEFINE_WRAPPER_FUNC(80, 320, 640) 187 DEFINE_WRAPPER_FUNC(81, 324, 648) 188 DEFINE_WRAPPER_FUNC(82, 328, 656) 189 DEFINE_WRAPPER_FUNC(83, 332, 664) 190 DEFINE_WRAPPER_FUNC(84, 336, 672) 191 DEFINE_WRAPPER_FUNC(85, 340, 680) 192 DEFINE_WRAPPER_FUNC(86, 344, 688) 193 DEFINE_WRAPPER_FUNC(87, 348, 696) 194 DEFINE_WRAPPER_FUNC(88, 352, 704) 195 DEFINE_WRAPPER_FUNC(89, 356, 712) 196 DEFINE_WRAPPER_FUNC(90, 360, 720) 197 DEFINE_WRAPPER_FUNC(91, 364, 728) 198 DEFINE_WRAPPER_FUNC(92, 368, 736) 199 DEFINE_WRAPPER_FUNC(93, 372, 744) 200 DEFINE_WRAPPER_FUNC(94, 376, 752) 201 DEFINE_WRAPPER_FUNC(95, 380, 760) 202 DEFINE_WRAPPER_FUNC(96, 384, 768) 203 DEFINE_WRAPPER_FUNC(97, 388, 776) 204 DEFINE_WRAPPER_FUNC(98, 392, 784) 205 DEFINE_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. */ 208 static const void *wrapper_vtbl[] = { 209 wrapper_QueryInterface, 210 wrapper_AddRef, 211 wrapper_Release, 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 311 HRESULT wrap_iface(IUnknown *iface, IUnknown *ref_unk, IUnknown **ret) 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 } 331