Commit 7d2d8c7e authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

mshtml: Move iface_wrapper_t IUnknown implementation to htmlobject.c.

And build ifacewrap.c as x86-64 code on ARM64EC.
parent 8c1da99e
......@@ -632,6 +632,58 @@ static const IHTMLObjectElement2Vtbl HTMLObjectElement2Vtbl = {
HTMLObjectElement2_get_data
};
/*
* This object wraps any unrecognized interface overriding its IUnknown methods, allowing
* us to return external interface from our QI implementation preserving COM rules.
* This can't be done right and it seems to be broken by design.
*/
typedef struct {
IUnknown IUnknown_iface;
IUnknown *iface;
IUnknown *ref_unk;
LONG ref;
} iface_wrapper_t;
static inline iface_wrapper_t *impl_from_IUnknown(IUnknown *iface)
{
return CONTAINING_RECORD(iface, iface_wrapper_t, IUnknown_iface);
}
HRESULT WINAPI wrapper_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
iface_wrapper_t *This = impl_from_IUnknown(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
return IUnknown_QueryInterface(This->ref_unk, riid, ppv);
}
ULONG WINAPI wrapper_AddRef(IUnknown *iface)
{
iface_wrapper_t *This = impl_from_IUnknown(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
return ref;
}
ULONG WINAPI wrapper_Release(IUnknown *iface)
{
iface_wrapper_t *This = impl_from_IUnknown(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) {
IUnknown_Release(This->iface);
IUnknown_Release(This->ref_unk);
free(This);
}
return ref;
}
static inline HTMLObjectElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
{
return CONTAINING_RECORD(iface, HTMLObjectElement, plugin_container.element.node);
......@@ -665,19 +717,25 @@ static void *HTMLObjectElement_query_interface(DispatchEx *dispex, REFIID riid)
elem_iface = HTMLElement_query_interface(&This->plugin_container.element.node.event_target.dispex, riid);
if(!elem_iface && This->plugin_container.plugin_host && This->plugin_container.plugin_host->plugin_unk) {
IUnknown *plugin_iface, *ret;
IUnknown *plugin_iface;
HRESULT hres = IUnknown_QueryInterface(This->plugin_container.plugin_host->plugin_unk, riid, (void**)&plugin_iface);
if(hres == S_OK) {
hres = wrap_iface(plugin_iface, (IUnknown*)&This->IHTMLObjectElement_iface, &ret);
iface_wrapper_t *wrapper = malloc(sizeof(*wrapper));
if(!wrapper) {
IUnknown_Release(plugin_iface);
if(FAILED(hres)) {
ERR("wrap_iface failed: %08lx\n", hres);
return NULL;
}
TRACE("returning plugin iface %p wrapped to %p\n", plugin_iface, ret);
return ret;
wrapper->IUnknown_iface.lpVtbl = (const IUnknownVtbl *)iface_wrapper_vtbl;
wrapper->ref = 1;
wrapper->iface = plugin_iface;
IUnknown_AddRef(wrapper->iface);
wrapper->ref_unk = (IUnknown*)&This->IHTMLObjectElement_iface;
IUnknown_Release(plugin_iface);
TRACE("returning plugin iface %p wrapped to %p\n", plugin_iface, wrapper);
return &wrapper->IUnknown_iface;
}
}
......
......@@ -16,6 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep arm64ec_x64
#endif
#include <stdarg.h>
#define COBJMACROS
......@@ -30,60 +34,6 @@
#include "mshtml_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
/*
* This object wraps any unrecognized interface overriding its IUnknown methods, allowing
* us to return external interface from our QI implementation preserving COM rules.
* This can't be done right and it seems to be broken by design.
*/
typedef struct {
IUnknown IUnknown_iface;
IUnknown *iface;
IUnknown *ref_unk;
LONG ref;
} iface_wrapper_t;
static inline iface_wrapper_t *impl_from_IUnknown(IUnknown *iface)
{
return CONTAINING_RECORD(iface, iface_wrapper_t, IUnknown_iface);
}
static HRESULT WINAPI wrapper_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
iface_wrapper_t *This = impl_from_IUnknown(iface);
TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
return IUnknown_QueryInterface(This->ref_unk, riid, ppv);
}
static ULONG WINAPI wrapper_AddRef(IUnknown *iface)
{
iface_wrapper_t *This = impl_from_IUnknown(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
return ref;
}
static ULONG WINAPI wrapper_Release(IUnknown *iface)
{
iface_wrapper_t *This = impl_from_IUnknown(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) {
IUnknown_Release(This->iface);
IUnknown_Release(This->ref_unk);
free(This);
}
return ref;
}
#ifdef __i386__
#define DEFINE_WRAPPER_FUNC(n, off, x) \
......@@ -106,6 +56,8 @@ static ULONG WINAPI wrapper_Release(IUnknown *iface)
#else
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
#define DEFINE_WRAPPER_FUNC(n, x, off) \
static HRESULT WINAPI wrapper_func_##n(IUnknown *iface) { \
ERR("Not implemented for this architecture\n"); \
......@@ -214,15 +166,10 @@ DEFINE_WRAPPER_FUNC(98, 392, 784)
DEFINE_WRAPPER_FUNC(99, 396, 792)
/* The size was found by testing when calls start crashing. It looks like MS wraps up to 100 functions. */
static const struct {
IUnknownVtbl unk_vtbl;
const void *wrappers[97];
} wrapper_vtbl = {
{
const void *iface_wrapper_vtbl[] = {
wrapper_QueryInterface,
wrapper_AddRef,
wrapper_Release
}, {
wrapper_Release,
wrapper_func_3,
wrapper_func_4,
wrapper_func_5,
......@@ -320,26 +267,4 @@ static const struct {
wrapper_func_97,
wrapper_func_98,
wrapper_func_99
}
};
HRESULT wrap_iface(IUnknown *iface, IUnknown *ref_unk, IUnknown **ret)
{
iface_wrapper_t *wrapper;
wrapper = malloc(sizeof(*wrapper));
if(!wrapper)
return E_OUTOFMEMORY;
wrapper->IUnknown_iface.lpVtbl = &wrapper_vtbl.unk_vtbl;
wrapper->ref = 1;
IUnknown_AddRef(iface);
wrapper->iface = iface;
/* Caller AddRefs */
wrapper->ref_unk = ref_unk;
*ret = &wrapper->IUnknown_iface;
return S_OK;
}
......@@ -1224,7 +1224,10 @@ HRESULT get_doc_elem_by_id(HTMLDocumentNode*,const WCHAR*,HTMLElement**);
HTMLOuterWindow *get_target_window(HTMLOuterWindow*,nsAString*,BOOL*);
HRESULT handle_link_click_event(HTMLElement*,nsAString*,nsAString*,nsIDOMEvent*,BOOL*);
HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**);
HRESULT WINAPI wrapper_QueryInterface(IUnknown *iface, REFIID riid, void **ppv);
ULONG WINAPI wrapper_AddRef(IUnknown *iface);
ULONG WINAPI wrapper_Release(IUnknown *iface);
extern const void *iface_wrapper_vtbl[];
IHTMLElementCollection *create_all_collection(HTMLDOMNode*,BOOL);
IHTMLElementCollection *create_collection_from_nodelist(nsIDOMNodeList*,compat_mode_t);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment