htmlobject.c 25.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright 2010 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
20
#include <assert.h>
21 22 23 24 25 26 27 28 29 30 31 32

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "ole2.h"

#include "wine/debug.h"

#include "mshtml_private.h"
33
#include "pluginhost.h"
34 35 36

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

37
struct HTMLObjectElement {
38
    HTMLPluginContainer plugin_container;
39

40
    IHTMLObjectElement IHTMLObjectElement_iface;
41
    IHTMLObjectElement2 IHTMLObjectElement2_iface;
42 43

    nsIDOMHTMLObjectElement *nsobject;
44
};
45

46 47 48 49
static inline HTMLObjectElement *impl_from_IHTMLObjectElement(IHTMLObjectElement *iface)
{
    return CONTAINING_RECORD(iface, HTMLObjectElement, IHTMLObjectElement_iface);
}
50 51 52 53

static HRESULT WINAPI HTMLObjectElement_QueryInterface(IHTMLObjectElement *iface,
        REFIID riid, void **ppv)
{
54
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
55

56 57
    return IHTMLDOMNode_QueryInterface(&This->plugin_container.element.node.IHTMLDOMNode_iface,
            riid, ppv);
58 59 60 61
}

static ULONG WINAPI HTMLObjectElement_AddRef(IHTMLObjectElement *iface)
{
62
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
63

64
    return IHTMLDOMNode_AddRef(&This->plugin_container.element.node.IHTMLDOMNode_iface);
65 66 67 68
}

static ULONG WINAPI HTMLObjectElement_Release(IHTMLObjectElement *iface)
{
69
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
70

71
    return IHTMLDOMNode_Release(&This->plugin_container.element.node.IHTMLDOMNode_iface);
72 73 74 75
}

static HRESULT WINAPI HTMLObjectElement_GetTypeInfoCount(IHTMLObjectElement *iface, UINT *pctinfo)
{
76
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
77
    return IDispatchEx_GetTypeInfoCount(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
78
            pctinfo);
79 80 81 82 83
}

static HRESULT WINAPI HTMLObjectElement_GetTypeInfo(IHTMLObjectElement *iface, UINT iTInfo,
                                              LCID lcid, ITypeInfo **ppTInfo)
{
84
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
85
    return IDispatchEx_GetTypeInfo(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
86
            iTInfo, lcid, ppTInfo);
87 88 89 90 91 92
}

static HRESULT WINAPI HTMLObjectElement_GetIDsOfNames(IHTMLObjectElement *iface, REFIID riid,
                                                LPOLESTR *rgszNames, UINT cNames,
                                                LCID lcid, DISPID *rgDispId)
{
93
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
94
    return IDispatchEx_GetIDsOfNames(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
95
            riid, rgszNames, cNames, lcid, rgDispId);
96 97 98 99 100 101
}

static HRESULT WINAPI HTMLObjectElement_Invoke(IHTMLObjectElement *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
102
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
103
    return IDispatchEx_Invoke(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
104
            dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
105 106 107 108
}

static HRESULT WINAPI HTMLObjectElement_get_object(IHTMLObjectElement *iface, IDispatch **p)
{
109
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
110 111 112 113

    TRACE("(%p)->(%p)\n", This, p);

    return get_plugin_disp(&This->plugin_container, p);
114 115 116 117
}

static HRESULT WINAPI HTMLObjectElement_get_classid(IHTMLObjectElement *iface, BSTR *p)
{
118
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
119 120 121

    TRACE("(%p)->(%p)\n", This, p);

122
    return IHTMLObjectElement2_get_classid(&This->IHTMLObjectElement2_iface, p);
123 124 125 126
}

static HRESULT WINAPI HTMLObjectElement_get_data(IHTMLObjectElement *iface, BSTR *p)
{
127
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
128 129 130

    TRACE("(%p)->(%p)\n", This, p);

131
    return IHTMLObjectElement2_get_data(&This->IHTMLObjectElement2_iface, p);
132 133 134 135
}

static HRESULT WINAPI HTMLObjectElement_put_recordset(IHTMLObjectElement *iface, IDispatch *v)
{
136
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
137 138 139 140 141 142
    FIXME("(%p)->(%p)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_recordset(IHTMLObjectElement *iface, IDispatch **p)
{
143
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
144 145 146 147 148 149
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_align(IHTMLObjectElement *iface, BSTR v)
{
150
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
151 152 153 154 155 156
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_align(IHTMLObjectElement *iface, BSTR *p)
{
157
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
158 159 160 161 162 163
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_name(IHTMLObjectElement *iface, BSTR v)
{
164
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
165 166 167 168 169 170 171 172 173
    nsAString nsstr;
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_w(v));

    nsAString_InitDepend(&nsstr, v);
    nsres = nsIDOMHTMLObjectElement_SetName(This->nsobject, &nsstr);
    nsAString_Finish(&nsstr);
    return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
174 175 176 177
}

static HRESULT WINAPI HTMLObjectElement_get_name(IHTMLObjectElement *iface, BSTR *p)
{
178
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
179 180 181 182 183 184 185 186
    nsAString nsstr;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&nsstr, NULL);
    nsres = nsIDOMHTMLObjectElement_GetName(This->nsobject, &nsstr);
    return return_nsstr(nsres, &nsstr, p);
187 188 189 190
}

static HRESULT WINAPI HTMLObjectElement_put_codeBase(IHTMLObjectElement *iface, BSTR v)
{
191
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
192 193 194 195 196 197
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_codeBase(IHTMLObjectElement *iface, BSTR *p)
{
198
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
199 200 201 202 203 204
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_codeType(IHTMLObjectElement *iface, BSTR v)
{
205
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
206 207 208 209 210 211
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_codeType(IHTMLObjectElement *iface, BSTR *p)
{
212
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
213 214 215 216 217 218
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_code(IHTMLObjectElement *iface, BSTR v)
{
219
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
220 221 222 223 224 225
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_code(IHTMLObjectElement *iface, BSTR *p)
{
226
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
227 228 229 230 231 232
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_BaseHref(IHTMLObjectElement *iface, BSTR *p)
{
233
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
234 235 236 237 238 239
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_type(IHTMLObjectElement *iface, BSTR v)
{
240
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
241 242 243 244 245 246
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_type(IHTMLObjectElement *iface, BSTR *p)
{
247
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
248 249 250 251 252 253
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_form(IHTMLObjectElement *iface, IHTMLFormElement **p)
{
254
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
255 256 257 258 259 260
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_width(IHTMLObjectElement *iface, VARIANT v)
{
261
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
    nsAString width_str;
    PRUnichar buf[12];
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    switch(V_VT(&v)) {
    case VT_I4: {
        static const WCHAR formatW[] = {'%','d',0};
        sprintfW(buf, formatW, V_I4(&v));
        break;
    }
    default:
        FIXME("unimplemented for arg %s\n", debugstr_variant(&v));
        return E_NOTIMPL;
    }

    nsAString_InitDepend(&width_str, buf);
    nsres = nsIDOMHTMLObjectElement_SetWidth(This->nsobject, &width_str);
    nsAString_Finish(&width_str);
    if(NS_FAILED(nsres)) {
        FIXME("SetWidth failed: %08x\n", nsres);
        return E_FAIL;
    }

    notif_container_change(&This->plugin_container, DISPID_UNKNOWN);
    return S_OK;
289 290 291 292
}

static HRESULT WINAPI HTMLObjectElement_get_width(IHTMLObjectElement *iface, VARIANT *p)
{
293
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
    nsAString width_str;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&width_str, NULL);
    nsres = nsIDOMHTMLObjectElement_GetWidth(This->nsobject, &width_str);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *width;

        nsAString_GetData(&width_str, &width);
        V_VT(p) = VT_BSTR;
        V_BSTR(p) = SysAllocString(width);
        hres = V_BSTR(p) ? S_OK : E_OUTOFMEMORY;
    }else {
        ERR("GetWidth failed: %08x\n", nsres);
        hres = E_FAIL;
    }

    nsAString_Finish(&width_str);
    return hres;
316 317 318 319
}

static HRESULT WINAPI HTMLObjectElement_put_height(IHTMLObjectElement *iface, VARIANT v)
{
320
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    nsAString height_str;
    PRUnichar buf[12];
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    switch(V_VT(&v)) {
    case VT_I4: {
        static const WCHAR formatW[] = {'%','d',0};
        sprintfW(buf, formatW, V_I4(&v));
        break;
    }
    default:
        FIXME("unimplemented for arg %s\n", debugstr_variant(&v));
        return E_NOTIMPL;
    }

    nsAString_InitDepend(&height_str, buf);
    nsres = nsIDOMHTMLObjectElement_SetHeight(This->nsobject, &height_str);
    nsAString_Finish(&height_str);
    if(NS_FAILED(nsres)) {
        FIXME("SetHeight failed: %08x\n", nsres);
        return E_FAIL;
    }

    notif_container_change(&This->plugin_container, DISPID_UNKNOWN);
    return S_OK;
348 349 350 351
}

static HRESULT WINAPI HTMLObjectElement_get_height(IHTMLObjectElement *iface, VARIANT *p)
{
352
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
    nsAString height_str;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, p);

    nsAString_Init(&height_str, NULL);
    nsres = nsIDOMHTMLObjectElement_GetHeight(This->nsobject, &height_str);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *height;

        nsAString_GetData(&height_str, &height);
        V_VT(p) = VT_BSTR;
        V_BSTR(p) = SysAllocString(height);
        hres = V_BSTR(p) ? S_OK : E_OUTOFMEMORY;
    }else {
        ERR("GetHeight failed: %08x\n", nsres);
        hres = E_FAIL;
    }

    nsAString_Finish(&height_str);
    return hres;
375 376 377 378
}

static HRESULT WINAPI HTMLObjectElement_get_readyState(IHTMLObjectElement *iface, LONG *p)
{
379
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
380 381 382 383 384 385
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_onreadystatechange(IHTMLObjectElement *iface, VARIANT v)
{
386
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
387 388 389 390 391 392
    FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_onreadystatechange(IHTMLObjectElement *iface, VARIANT *p)
{
393
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
394 395 396 397 398 399
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_onerror(IHTMLObjectElement *iface, VARIANT v)
{
400
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
401 402 403 404 405 406
    FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_onerror(IHTMLObjectElement *iface, VARIANT *p)
{
407
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
408 409 410 411 412 413
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_altHtml(IHTMLObjectElement *iface, BSTR v)
{
414
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
415 416 417 418 419 420
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_altHtml(IHTMLObjectElement *iface, BSTR *p)
{
421
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
422 423 424 425 426 427
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_put_vspace(IHTMLObjectElement *iface, LONG v)
{
428
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
429 430 431 432 433 434
    FIXME("(%p)->(%d)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_vspace(IHTMLObjectElement *iface, LONG *p)
{
435
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
436 437 438 439
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

440
    nsres = nsIDOMHTMLObjectElement_GetVspace(This->nsobject, p);
441 442 443 444 445 446
    if(NS_FAILED(nsres)) {
        ERR("GetVspace failed: %08x\n", nsres);
        return E_FAIL;
    }

    return S_OK;
447 448 449 450
}

static HRESULT WINAPI HTMLObjectElement_put_hspace(IHTMLObjectElement *iface, LONG v)
{
451
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
452 453 454 455 456 457
    FIXME("(%p)->(%d)\n", This, v);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement_get_hspace(IHTMLObjectElement *iface, LONG *p)
{
458
    HTMLObjectElement *This = impl_from_IHTMLObjectElement(iface);
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static const IHTMLObjectElementVtbl HTMLObjectElementVtbl = {
    HTMLObjectElement_QueryInterface,
    HTMLObjectElement_AddRef,
    HTMLObjectElement_Release,
    HTMLObjectElement_GetTypeInfoCount,
    HTMLObjectElement_GetTypeInfo,
    HTMLObjectElement_GetIDsOfNames,
    HTMLObjectElement_Invoke,
    HTMLObjectElement_get_object,
    HTMLObjectElement_get_classid,
    HTMLObjectElement_get_data,
    HTMLObjectElement_put_recordset,
    HTMLObjectElement_get_recordset,
    HTMLObjectElement_put_align,
    HTMLObjectElement_get_align,
    HTMLObjectElement_put_name,
    HTMLObjectElement_get_name,
    HTMLObjectElement_put_codeBase,
    HTMLObjectElement_get_codeBase,
    HTMLObjectElement_put_codeType,
    HTMLObjectElement_get_codeType,
    HTMLObjectElement_put_code,
    HTMLObjectElement_get_code,
    HTMLObjectElement_get_BaseHref,
    HTMLObjectElement_put_type,
    HTMLObjectElement_get_type,
    HTMLObjectElement_get_form,
    HTMLObjectElement_put_width,
    HTMLObjectElement_get_width,
    HTMLObjectElement_put_height,
    HTMLObjectElement_get_height,
    HTMLObjectElement_get_readyState,
    HTMLObjectElement_put_onreadystatechange,
    HTMLObjectElement_get_onreadystatechange,
    HTMLObjectElement_put_onerror,
    HTMLObjectElement_get_onerror,
    HTMLObjectElement_put_altHtml,
    HTMLObjectElement_get_altHtml,
    HTMLObjectElement_put_vspace,
    HTMLObjectElement_get_vspace,
    HTMLObjectElement_put_hspace,
    HTMLObjectElement_get_hspace
};

507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
static inline HTMLObjectElement *impl_from_IHTMLObjectElement2(IHTMLObjectElement2 *iface)
{
    return CONTAINING_RECORD(iface, HTMLObjectElement, IHTMLObjectElement2_iface);
}

static HRESULT WINAPI HTMLObjectElement2_QueryInterface(IHTMLObjectElement2 *iface,
        REFIID riid, void **ppv)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);

    return IHTMLDOMNode_QueryInterface(&This->plugin_container.element.node.IHTMLDOMNode_iface,
            riid, ppv);
}

static ULONG WINAPI HTMLObjectElement2_AddRef(IHTMLObjectElement2 *iface)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);

    return IHTMLDOMNode_AddRef(&This->plugin_container.element.node.IHTMLDOMNode_iface);
}

static ULONG WINAPI HTMLObjectElement2_Release(IHTMLObjectElement2 *iface)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);

    return IHTMLDOMNode_Release(&This->plugin_container.element.node.IHTMLDOMNode_iface);
}

static HRESULT WINAPI HTMLObjectElement2_GetTypeInfoCount(IHTMLObjectElement2 *iface, UINT *pctinfo)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
538
    return IDispatchEx_GetTypeInfoCount(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
539 540 541 542 543 544 545
            pctinfo);
}

static HRESULT WINAPI HTMLObjectElement2_GetTypeInfo(IHTMLObjectElement2 *iface, UINT iTInfo,
                                              LCID lcid, ITypeInfo **ppTInfo)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
546
    return IDispatchEx_GetTypeInfo(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
547 548 549 550 551 552 553
            iTInfo, lcid, ppTInfo);
}

static HRESULT WINAPI HTMLObjectElement2_GetIDsOfNames(IHTMLObjectElement2 *iface, REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
554
    return IDispatchEx_GetIDsOfNames(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
555 556 557 558 559 560 561 562
            riid, rgszNames, cNames, lcid, rgDispId);
}

static HRESULT WINAPI HTMLObjectElement2_Invoke(IHTMLObjectElement2 *iface, DISPID dispIdMember,
        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
        EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
563
    return IDispatchEx_Invoke(&This->plugin_container.element.node.event_target.dispex.IDispatchEx_iface,
564 565 566 567 568 569 570 571 572 573 574 575 576 577
            dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI HTMLObjectElement2_namedRecordset(IHTMLObjectElement2 *iface, BSTR dataMember,
        VARIANT *hierarchy, IDispatch **ppRecordset)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
    FIXME("(%p)->(%s %p %p)\n", This, debugstr_w(dataMember), hierarchy, ppRecordset);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement2_put_classid(IHTMLObjectElement2 *iface, BSTR v)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
578 579 580 581 582 583 584 585 586 587 588
    HRESULT hres;

    static const WCHAR classidW[] = {'c','l','a','s','s','i','d',0};

    FIXME("(%p)->(%s) semi-stub\n", This, debugstr_w(v));

    hres = elem_string_attr_setter(&This->plugin_container.element, classidW, v);
    if(FAILED(hres))
        return hres;

    if(This->plugin_container.plugin_host) {
589
        FIXME("Host already associated.\n");
590 591 592 593 594 595 596 597 598 599 600
        return E_NOTIMPL;
    }

    /*
     * NOTE:
     * If the element is not yet in DOM tree, we should embed it as soon as it's added.
     * However, Gecko for some reason decides not to create NP plugin in this case,
     * so this won't work.
     */

    return create_plugin_host(This->plugin_container.element.node.doc, &This->plugin_container);
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
}

static HRESULT WINAPI HTMLObjectElement2_get_classid(IHTMLObjectElement2 *iface, BSTR *p)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement2_put_data(IHTMLObjectElement2 *iface, BSTR v)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLObjectElement2_get_data(IHTMLObjectElement2 *iface, BSTR *p)
{
    HTMLObjectElement *This = impl_from_IHTMLObjectElement2(iface);
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

static const IHTMLObjectElement2Vtbl HTMLObjectElement2Vtbl = {
    HTMLObjectElement2_QueryInterface,
    HTMLObjectElement2_AddRef,
    HTMLObjectElement2_Release,
    HTMLObjectElement2_GetTypeInfoCount,
    HTMLObjectElement2_GetTypeInfo,
    HTMLObjectElement2_GetIDsOfNames,
    HTMLObjectElement2_Invoke,
    HTMLObjectElement2_namedRecordset,
    HTMLObjectElement2_put_classid,
    HTMLObjectElement2_get_classid,
    HTMLObjectElement2_put_data,
    HTMLObjectElement2_get_data
};

639 640 641 642
static inline HTMLObjectElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
{
    return CONTAINING_RECORD(iface, HTMLObjectElement, plugin_container.element.node);
}
643 644 645

static HRESULT HTMLObjectElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
{
646
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);
647

648 649
    TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);

650
    if(IsEqualGUID(&IID_IUnknown, riid)) {
651
        *ppv = &This->IHTMLObjectElement_iface;
652
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
653
        *ppv = &This->IHTMLObjectElement_iface;
654
    }else if(IsEqualGUID(&IID_IHTMLObjectElement, riid)) {
655
        *ppv = &This->IHTMLObjectElement_iface;
656 657
    }else if(IsEqualGUID(&IID_IHTMLObjectElement2, riid)) {
        *ppv = &This->IHTMLObjectElement2_iface;
658
    }else if(IsEqualGUID(&IID_HTMLPluginContainer, riid)) {
659
        /* Special pseudo-interface returning HTMLPluginContainse struct. */
660
        *ppv = &This->plugin_container;
661
        node_addref(&This->plugin_container.element.node);
662
        return S_OK;
663
    }else {
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
        HRESULT hres;

        hres = HTMLElement_QI(&This->plugin_container.element.node, riid, ppv);
        if(hres == E_NOINTERFACE && This->plugin_container.plugin_host && This->plugin_container.plugin_host->plugin_unk) {
            IUnknown *plugin_iface, *ret;

            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);
                IUnknown_Release(plugin_iface);
                if(FAILED(hres))
                    return hres;

                TRACE("returning plugin iface %p wrapped to %p\n", plugin_iface, ret);
                *ppv = ret;
                return S_OK;
            }
        }

        return hres;
684 685 686 687 688 689 690 691
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static void HTMLObjectElement_destructor(HTMLDOMNode *iface)
{
692
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);
693

694
    if(This->plugin_container.plugin_host)
695
        detach_plugin_host(This->plugin_container.plugin_host);
696

697
    HTMLElement_destructor(&This->plugin_container.element.node);
698 699
}

700 701
static HRESULT HTMLObjectElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
{
702
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);
703 704 705 706
    FIXME("(%p)->(%p)\n", This, p);
    return E_NOTIMPL;
}

707 708 709
static HRESULT HTMLObjectElement_get_dispid(HTMLDOMNode *iface, BSTR name,
        DWORD grfdex, DISPID *pid)
{
710
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);
711 712 713 714 715 716 717 718 719

    TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(name), grfdex, pid);

    return get_plugin_dispid(&This->plugin_container, name, pid);
}

static HRESULT HTMLObjectElement_invoke(HTMLDOMNode *iface, DISPID id, LCID lcid,
        WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
720
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);
721 722 723 724 725 726

    TRACE("(%p)->(%d)\n", This, id);

    return invoke_plugin_prop(&This->plugin_container, id, lcid, flags, params, res, ei);
}

727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
static void HTMLObjectElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
{
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);

    if(This->nsobject)
        note_cc_edge((nsISupports*)This->nsobject, "This->nsobject", cb);
}

static void HTMLObjectElement_unlink(HTMLDOMNode *iface)
{
    HTMLObjectElement *This = impl_from_HTMLDOMNode(iface);

    if(This->nsobject) {
        nsIDOMHTMLObjectElement *nsobject = This->nsobject;

        This->nsobject = NULL;
        nsIDOMHTMLObjectElement_Release(nsobject);
    }
}

747
static const NodeImplVtbl HTMLObjectElementImplVtbl = {
748
    &CLSID_HTMLObjectElement,
749
    HTMLObjectElement_QI,
750
    HTMLObjectElement_destructor,
751
    HTMLElement_cpc,
752
    HTMLElement_clone,
753
    HTMLElement_handle_event,
754
    HTMLElement_get_attr_col,
755 756 757 758 759
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
760 761
    HTMLObjectElement_get_readystate,
    HTMLObjectElement_get_dispid,
762 763 764 765
    HTMLObjectElement_invoke,
    NULL,
    HTMLObjectElement_traverse,
    HTMLObjectElement_unlink
766 767
};

768
static const tid_t HTMLObjectElement_iface_tids[] = {
769
    IHTMLObjectElement2_tid,
770 771
    IHTMLObjectElement_tid,
    HTMLELEMENT_TIDS,
772 773 774 775 776
    0
};
static dispex_static_data_t HTMLObjectElement_dispex = {
    NULL,
    DispHTMLObjectElement_tid,
777 778
    HTMLObjectElement_iface_tids,
    HTMLElement_init_dispex_info
779 780
};

781
HRESULT HTMLObjectElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
782
{
783
    HTMLObjectElement *ret;
784
    nsresult nsres;
785

786 787 788 789
    ret = heap_alloc_zero(sizeof(*ret));
    if(!ret)
        return E_OUTOFMEMORY;

790
    ret->IHTMLObjectElement_iface.lpVtbl = &HTMLObjectElementVtbl;
791
    ret->IHTMLObjectElement2_iface.lpVtbl = &HTMLObjectElement2Vtbl;
792
    ret->plugin_container.element.node.vtbl = &HTMLObjectElementImplVtbl;
793

794 795
    HTMLElement_Init(&ret->plugin_container.element, doc, nselem, &HTMLObjectElement_dispex);

796
    nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLObjectElement, (void**)&ret->nsobject);
797
    assert(nsres == NS_OK);
798

799
    *elem = &ret->plugin_container.element;
800
    return S_OK;
801
}