-- v3: mshtml: Handle cNames > 1 in GetIDsOfNames properly. mshtml: Forward IDispatchEx to the document node. mshtml: Forward toString to the document node. mshtml: Expose IEventTarget on HTMLDocumentObj and forward it to the doc node.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/oleobj.c | 61 + dlls/mshtml/tests/doc_with_prop.html | 3 + dlls/mshtml/tests/doc_with_prop_ie9.html | 4 + dlls/mshtml/tests/events.c | 1505 +++++++++++++++++++--- dlls/mshtml/tests/rsrc.rc | 6 + 6 files changed, 1399 insertions(+), 181 deletions(-) create mode 100644 dlls/mshtml/tests/doc_with_prop.html create mode 100644 dlls/mshtml/tests/doc_with_prop_ie9.html
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 7df5c5e8b30..e7f5481b886 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -677,6 +677,7 @@ struct HTMLDocumentObj { IObjectSafety IObjectSafety_iface; IServiceProvider IServiceProvider_iface; ITargetContainer ITargetContainer_iface; + IEventTarget IEventTarget_iface;
IWindowForBindingUI IWindowForBindingUI_iface;
diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c index de6fd028218..5c7673b1649 100644 --- a/dlls/mshtml/oleobj.c +++ b/dlls/mshtml/oleobj.c @@ -3238,6 +3238,58 @@ static const IDocumentRangeVtbl DocObjDocumentRangeVtbl = { DocObjDocumentRange_createRange };
+/********************************************************** + * IEventTarget implementation + */ +static inline HTMLDocumentObj *impl_from_IEventTarget(IEventTarget *iface) +{ + return CONTAINING_RECORD(iface, HTMLDocumentObj, IEventTarget_iface); +} + +HTMLDOCUMENTOBJ_IDISPATCH_METHODS(EventTarget) + +static HRESULT WINAPI DocObjEventTarget_addEventListener(IEventTarget *iface, BSTR type, IDispatch *listener, + VARIANT_BOOL capture) +{ + HTMLDocumentObj *This = impl_from_IEventTarget(iface); + + if(!This->doc_node) + return E_UNEXPECTED; + return IEventTarget_addEventListener(&This->doc_node->node.event_target.IEventTarget_iface, type, listener, capture); +} + +static HRESULT WINAPI DocObjEventTarget_removeEventListener(IEventTarget *iface, BSTR type, IDispatch *listener, + VARIANT_BOOL capture) +{ + HTMLDocumentObj *This = impl_from_IEventTarget(iface); + + if(!This->doc_node) + return E_UNEXPECTED; + return IEventTarget_removeEventListener(&This->doc_node->node.event_target.IEventTarget_iface, type, listener, capture); +} + +static HRESULT WINAPI DocObjEventTarget_dispatchEvent(IEventTarget *iface, IDOMEvent *event_iface, VARIANT_BOOL *result) +{ + HTMLDocumentObj *This = impl_from_IEventTarget(iface); + + if(!This->doc_node) + return E_UNEXPECTED; + return IEventTarget_dispatchEvent(&This->doc_node->node.event_target.IEventTarget_iface, event_iface, result); +} + +static const IEventTargetVtbl DocObjEventTargetVtbl = { + DocObjEventTarget_QueryInterface, + DocObjEventTarget_AddRef, + DocObjEventTarget_Release, + DocObjEventTarget_GetTypeInfoCount, + DocObjEventTarget_GetTypeInfo, + DocObjEventTarget_GetIDsOfNames, + DocObjEventTarget_Invoke, + DocObjEventTarget_addEventListener, + DocObjEventTarget_removeEventListener, + DocObjEventTarget_dispatchEvent +}; + static inline HTMLDocumentObj *impl_from_IUnknown(IUnknown *iface) { return CONTAINING_RECORD(iface, HTMLDocumentObj, IUnknown_inner); @@ -3339,6 +3391,14 @@ static HRESULT WINAPI HTMLDocumentObj_QueryInterface(IUnknown *iface, REFIID rii *ppv = &This->ITargetContainer_iface; }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) { *ppv = &This->cp_container.IConnectionPointContainer_iface; + }else if(IsEqualGUID(&IID_IEventTarget, riid)) { + /* IEventTarget is conditionally exposed. This breaks COM rules when + it changes its compat mode, but it is how native works (see tests). */ + if(!This->doc_node || dispex_compat_mode(&This->doc_node->node.event_target.dispex) < COMPAT_MODE_IE9) { + *ppv = NULL; + return E_NOINTERFACE; + } + *ppv = &This->IEventTarget_iface; }else if(IsEqualGUID(&CLSID_CMarkup, riid)) { FIXME("(%p)->(CLSID_CMarkup %p)\n", This, ppv); *ppv = NULL; @@ -3734,6 +3794,7 @@ static HRESULT create_document_object(BOOL is_mhtml, IUnknown *outer, REFIID rii doc->IMarkupContainer_iface.lpVtbl = &DocObjMarkupContainerVtbl; doc->IDisplayServices_iface.lpVtbl = &DocObjDisplayServicesVtbl; doc->IDocumentRange_iface.lpVtbl = &DocObjDocumentRangeVtbl; + doc->IEventTarget_iface.lpVtbl = &DocObjEventTargetVtbl;
doc->outer_unk = outer ? outer : &doc->IUnknown_inner;
diff --git a/dlls/mshtml/tests/doc_with_prop.html b/dlls/mshtml/tests/doc_with_prop.html new file mode 100644 index 00000000000..4a81661bbdf --- /dev/null +++ b/dlls/mshtml/tests/doc_with_prop.html @@ -0,0 +1,3 @@ +<html> +<script type="text/javascript">document.prop = 137;</script> +</html> diff --git a/dlls/mshtml/tests/doc_with_prop_ie9.html b/dlls/mshtml/tests/doc_with_prop_ie9.html new file mode 100644 index 00000000000..ba1f5305fe1 --- /dev/null +++ b/dlls/mshtml/tests/doc_with_prop_ie9.html @@ -0,0 +1,4 @@ +<html><head> +<meta http-equiv="x-ua-compatible" content="IE=9" /> +<script type="text/javascript">document.prop = 137;</script> +</head></html> diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 8175205b830..ab20d088840 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -28,8 +28,11 @@ #include "ole2.h" #include "mshtml.h" #include "mshtmdid.h" +#include "mshtmhst.h" #include "docobj.h" #include "hlink.h" +#include "wininet.h" +#include "shdeprecated.h" #include "dispex.h"
#define DEFINE_EXPECT(func) \ @@ -60,6 +63,7 @@ #define CLEAR_CALLED(func) \ expect_ ## func = called_ ## func = FALSE
+DEFINE_EXPECT(docobj_onclick); DEFINE_EXPECT(document_onclick); DEFINE_EXPECT(body_onclick); DEFINE_EXPECT(doc_onclick_attached); @@ -144,6 +148,8 @@ static const char input_doc_str[] = static const char iframe_doc_str[] = "<html><body><iframe id="ifr">Testing</iframe></body></html>";
+static void navigate(IHTMLDocument2*,const WCHAR*); + static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2) { IUnknown *unk1, *unk2; @@ -965,6 +971,15 @@ static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown }; \ static IDispatchEx event ## _obj = { &event ## FuncVtbl };
+static HRESULT WINAPI docobj_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + CHECK_EXPECT(docobj_onclick); + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(docobj_onclick); + static HRESULT WINAPI document_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { @@ -2729,6 +2744,81 @@ static void test_iframe_connections(IHTMLDocument2 *doc) IHTMLDocument2_Release(iframes_doc); }
+static void test_doc_obj(IHTMLDocument2 *doc) +{ + IEventTarget *event_target; + IHTMLDocument6 *doc6; + IHTMLElement *body; + HRESULT hres; + VARIANT res; + BSTR bstr; + + event_target = (void*)0xdeadbeef; + hres = IHTMLDocument2_QueryInterface(doc, &IID_IEventTarget, (void**)&event_target); + if(document_mode < 9) { + ok(hres == E_NOINTERFACE, "hres = %08lx, expected E_NOINTERFACE\n", hres); + ok(!event_target, "event_target != NULL\n"); + }else { + IHTMLDocument2 *tmp; + + ok(hres == S_OK, "hres = %08lx, expected S_OK\n", hres); + ok(!!event_target, "event_target = NULL\n"); + + bstr = SysAllocString(L"click"); + IEventTarget_addEventListener(event_target, bstr, (IDispatch*)&docobj_onclick_obj, TRUE); + ok(hres == S_OK, "addEventListener failed: %08lx\n", hres); + SysFreeString(bstr); + + hres = IEventTarget_QueryInterface(event_target, &IID_IHTMLDocument2, (void**)&tmp); + ok(hres == S_OK, "Could not get IHTMLDocument2: %08lx\n", hres); + IEventTarget_Release(event_target); + + ok(doc == tmp, "IHTMLDocument2 from IEventTarget not same as original\n"); + IHTMLDocument2_Release(tmp); + + body = doc_get_body(doc); + SET_EXPECT(docobj_onclick); + hres = IHTMLElement_click(body); + ok(hres == S_OK, "click failed: %08lx\n", hres); + IHTMLElement_Release(body); + + pump_msgs(&called_docobj_onclick); + CHECK_CALLED(docobj_onclick); + } + + /* Navigate to a different document mode page, checking using the same doc obj. + Test that it breaks COM rules, since IEventTarget is conditionally exposed. + All the events registered on the old doc node are also removed. */ + navigate(doc, document_mode < 9 ? L"doc_with_prop_ie9.html" : L"doc_with_prop.html"); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument6, (void**)&doc6); + ok(hres == S_OK, "Could not get IHTMLDocument6: %08lx\n", hres); + + hres = IHTMLDocument6_get_documentMode(doc6, &res); + ok(hres == S_OK, "get_documentMode failed: %08lx\n", hres); + ok(V_VT(&res) == VT_R4, "V_VT(documentMode) = %u\n", V_VT(&res)); + ok(V_R4(&res) == (document_mode < 9 ? 9.0f : 5.0f), "V_R4(documentMode) = %f\n", V_R4(&res)); + IHTMLDocument6_Release(doc6); + document_mode = V_R4(&res); + + event_target = (void*)0xdeadbeef; + hres = IHTMLDocument2_QueryInterface(doc, &IID_IEventTarget, (void**)&event_target); + if(document_mode < 9) { + ok(hres == E_NOINTERFACE, "hres = %08lx, expected E_NOINTERFACE\n", hres); + ok(!event_target, "event_target != NULL\n"); + + body = doc_get_body(doc); + hres = IHTMLElement_click(body); + ok(hres == S_OK, "click failed: %08lx\n", hres); + IHTMLElement_Release(body); + pump_msgs(NULL); + }else { + ok(hres == S_OK, "hres = %08lx, expected S_OK\n", hres); + ok(!!event_target, "event_target = NULL\n"); + IEventTarget_Release(event_target); + } +} + static void test_create_event(IHTMLDocument2 *doc) { IDOMKeyboardEvent *keyboard_event; @@ -2996,6 +3086,8 @@ static HRESULT WINAPI window2_onstorage(IDispatchEx *iface, DISPID id, LCID lcid EVENT_HANDLER_FUNC_OBJ(window2_onstorage);
static HRESULT QueryInterface(REFIID,void**); +static HRESULT browserservice_qi(REFIID,void**); +static HRESULT wb_qi(REFIID,void**);
static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv) { @@ -3321,9 +3413,11 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document); ok(hres == S_OK, "could not get IOleDocument: %08lx\n", hres);
- hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view); + if(!view) { + hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view); + ok(hres == S_OK, "CreateView failed: %08lx\n", hres); + } IOleDocument_Release(document); - ok(hres == S_OK, "CreateView failed: %08lx\n", hres);
hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite); ok(hres == S_OK, "SetInPlaceSite failed: %08lx\n", hres); @@ -3349,259 +3443,1219 @@ static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
-static HRESULT QueryInterface(REFIID riid, void **ppv) -{ - *ppv = NULL; - - if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid)) - *ppv = &ClientSite; - else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) - *ppv = &DocumentSite; - else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid)) - *ppv = &InPlaceSite; - - return *ppv ? S_OK : E_NOINTERFACE; -} - -static IHTMLDocument2 *notif_doc; -static BOOL doc_complete; - -static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, - REFIID riid, void**ppv) +static HRESULT WINAPI TravelLog_QueryInterface(ITravelLog *iface, REFIID riid, void **ppv) { - if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) { + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITravelLog, riid)) *ppv = iface; - return S_OK; + else { + *ppv = NULL; + return E_NOINTERFACE; } - - ok(0, "unexpected call\n"); - return E_NOINTERFACE; + return S_OK; }
-static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface) +static ULONG WINAPI TravelLog_AddRef(ITravelLog *iface) { return 2; }
-static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface) +static ULONG WINAPI TravelLog_Release(ITravelLog *iface) { return 1; }
-static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID) +static HRESULT WINAPI TravelLog_AddEntry(ITravelLog *iface, IUnknown *punk, BOOL fIsLocalAnchor) { - if(dispID == DISPID_READYSTATE){ - BSTR state; - HRESULT hres; - - hres = IHTMLDocument2_get_readyState(notif_doc, &state); - ok(hres == S_OK, "get_readyState failed: %08lx\n", hres); - - if(!lstrcmpW(state, L"complete")) - doc_complete = TRUE; - - SysFreeString(state); - } + return E_NOTIMPL; +}
- return S_OK; +static HRESULT WINAPI TravelLog_UpdateEntry(ITravelLog *iface, IUnknown *punk, BOOL fIsLocalAnchor) +{ + return E_NOTIMPL; }
-static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID) +static HRESULT WINAPI TravelLog_UpdateExternal(ITravelLog *iface, IUnknown *punk, IUnknown *punkHLBrowseContext) { - ok(0, "unexpected call\n"); return E_NOTIMPL; }
-static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = { - PropertyNotifySink_QueryInterface, - PropertyNotifySink_AddRef, - PropertyNotifySink_Release, - PropertyNotifySink_OnChanged, - PropertyNotifySink_OnRequestEdit -}; +static HRESULT WINAPI TravelLog_Travel(ITravelLog *iface, IUnknown *punk, int iOffset) +{ + return E_NOTIMPL; +}
-static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl }; +static HRESULT WINAPI TravelLog_GetTravelEntry(ITravelLog *iface, IUnknown *punk, int iOffset, ITravelEntry **ppte) +{ + return E_NOTIMPL; +}
-typedef struct { - IInternetProtocolEx IInternetProtocolEx_iface; - IWinInetHttpInfo IWinInetHttpInfo_iface; +static HRESULT WINAPI TravelLog_FindTravelEntry(ITravelLog *iface, IUnknown *punk, LPCITEMIDLIST pidl, ITravelEntry **ppte) +{ + return E_NOTIMPL; +}
- LONG ref; +static HRESULT WINAPI TravelLog_GetTooltipText(ITravelLog *iface, IUnknown *punk, int iOffset, int idsTemplate, LPWSTR pwzText, DWORD cchText) +{ + return E_NOTIMPL; +}
- IInternetProtocolSink *sink; - IUri *uri; +static HRESULT WINAPI TravelLog_InsertMenuEntries(ITravelLog *iface, IUnknown *punk, HMENU hmenu, int nPos, int idFirst, int idLast, DWORD dwFlags) +{ + return E_NOTIMPL; +}
- ULONG size; - const char *data; - const char *ptr; -} ProtocolHandler; +static HRESULT WINAPI TravelLog_Clone(ITravelLog *iface, ITravelLog **pptl) +{ + return E_NOTIMPL; +}
-static DWORD WINAPI async_switch_proc(void *arg) +static DWORD WINAPI TravelLog_CountEntries(ITravelLog *iface, IUnknown *punk) { - PROTOCOLDATA protocol_data = { PI_FORCE_ASYNC }; - ProtocolHandler *protocol_handler = arg; - IInternetProtocolSink_Switch(protocol_handler->sink, &protocol_data); return 0; }
-static inline ProtocolHandler *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) +static HRESULT WINAPI TravelLog_Revert(ITravelLog *iface) { - return CONTAINING_RECORD(iface, ProtocolHandler, IInternetProtocolEx_iface); + return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) -{ - ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); +static const ITravelLogVtbl TravelLogVtbl = { + TravelLog_QueryInterface, + TravelLog_AddRef, + TravelLog_Release, + TravelLog_AddEntry, + TravelLog_UpdateEntry, + TravelLog_UpdateExternal, + TravelLog_Travel, + TravelLog_GetTravelEntry, + TravelLog_FindTravelEntry, + TravelLog_GetTooltipText, + TravelLog_InsertMenuEntries, + TravelLog_Clone, + TravelLog_CountEntries, + TravelLog_Revert +};
- if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid) || IsEqualGUID(&IID_IInternetProtocolEx, riid)) { - *ppv = &This->IInternetProtocolEx_iface; - }else if(IsEqualGUID(&IID_IWinInetInfo, riid) || IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { - *ppv = &This->IWinInetHttpInfo_iface; - }else { - *ppv = NULL; - return E_NOINTERFACE; - } +static ITravelLog TravelLog = { &TravelLogVtbl };
- IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; +static HRESULT WINAPI BrowserService_QueryInterface(IBrowserService *iface, REFIID riid, void **ppv) +{ + return browserservice_qi(riid, ppv); }
-static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface) +static ULONG WINAPI BrowserService_AddRef(IBrowserService* This) { - ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); - return InterlockedIncrement(&This->ref); + return 2; }
-static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface) +static ULONG WINAPI BrowserService_Release(IBrowserService* This) { - ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); - LONG ref = InterlockedDecrement(&This->ref); - - if(!ref) { - if(This->sink) - IInternetProtocolSink_Release(This->sink); - if(This->uri) - IUri_Release(This->uri); - free(This); - } - - return ref; + return 1; }
-static HRESULT WINAPI Protocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, - IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) +static HRESULT WINAPI BrowserService_GetParentSite(IBrowserService* This, IOleInPlaceSite **ppipsite) { - ok(0, "unexpected call\n"); return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData) +static HRESULT WINAPI BrowserService_SetTitle(IBrowserService* This, IShellView *psv, LPCWSTR pszName) { - ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); - IServiceProvider *service_provider; - IHttpNegotiate *http_negotiate; - WCHAR *addl_headers = NULL; - HRESULT hres; - BSTR bstr; - - hres = IInternetProtocolSink_QueryInterface(This->sink, &IID_IServiceProvider, (void**)&service_provider); - ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); - - hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate, &IID_IHttpNegotiate, (void**)&http_negotiate); - IServiceProvider_Release(service_provider); - ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08lx\n", hres); - - hres = IUri_GetDisplayUri(This->uri, &bstr); - ok(hres == S_OK, "Failed to get display uri: %08lx\n", hres); - hres = IHttpNegotiate_BeginningTransaction(http_negotiate, bstr, L"", 0, &addl_headers); - ok(hres == S_OK, "BeginningTransaction failed: %08lx\n", hres); - CoTaskMemFree(addl_headers); - SysFreeString(bstr); - - bstr = SysAllocString(L"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); - hres = IHttpNegotiate_OnResponse(http_negotiate, 200, bstr, NULL, NULL); - ok(hres == S_OK, "OnResponse failed: %08lx\n", hres); - IHttpNegotiate_Release(http_negotiate); - SysFreeString(bstr); + return E_NOTIMPL; +}
- hres = IInternetProtocolSink_ReportData(This->sink, BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION, - This->size, This->size); - ok(hres == S_OK, "ReportData failed: %08lx\n", hres); +static HRESULT WINAPI BrowserService_GetTitle(IBrowserService* This, IShellView *psv, LPWSTR pszName, DWORD cchName) +{ + return E_NOTIMPL; +}
- hres = IInternetProtocolSink_ReportResult(This->sink, S_OK, 0, NULL); - ok(hres == S_OK, "ReportResult failed: %08lx\n", hres); +static HRESULT WINAPI BrowserService_GetOleObject(IBrowserService* This, IOleObject **ppobjv) +{ + return E_NOTIMPL; +}
- IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); +static HRESULT WINAPI BrowserService_GetTravelLog(IBrowserService* This, ITravelLog **pptl) +{ + *pptl = &TravelLog; return S_OK; }
-static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason, DWORD dwOptions) +static HRESULT WINAPI BrowserService_ShowControlWindow(IBrowserService* This, UINT id, BOOL fShow) { - trace("Abort(%08lx %lx)\n", hrReason, dwOptions); return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions) +static HRESULT WINAPI BrowserService_IsControlWindowShown(IBrowserService* This, UINT id, BOOL *pfShown) { - return S_OK; + return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface) +static HRESULT WINAPI BrowserService_IEGetDisplayName(IBrowserService* This, PCIDLIST_ABSOLUTE pidl, LPWSTR pwszName, UINT uFlags) { - ok(0, "unexpected call\n"); return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface) +static HRESULT WINAPI BrowserService_IEParseDisplayName(IBrowserService* This, UINT uiCP, LPCWSTR pwszPath, PIDLIST_ABSOLUTE *ppidlOut) { - ok(0, "unexpected call\n"); return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_Read(IInternetProtocolEx *iface, void *pv, ULONG cb, ULONG *pcbRead) +static HRESULT WINAPI BrowserService_DisplayParseError(IBrowserService* This, HRESULT hres, LPCWSTR pwszPath) { - ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); - ULONG read; + return E_NOTIMPL; +}
- read = This->size - (This->ptr - This->data); - if(read > cb) - read = cb; +static HRESULT WINAPI BrowserService_NavigateToPidl(IBrowserService* This, PCIDLIST_ABSOLUTE pidl, DWORD grfHLNF) +{ + return E_NOTIMPL; +}
- if(read) { - memcpy(pv, This->ptr, read); - This->ptr += read; - } +static HRESULT WINAPI BrowserService_SetNavigateState(IBrowserService* This, BNSTATE bnstate) +{ + return E_NOTIMPL; +}
- *pcbRead = read; - return (This->ptr != This->data + This->size) ? S_OK : S_FALSE; +static HRESULT WINAPI BrowserService_GetNavigateState(IBrowserService* This, BNSTATE *pbnstate) +{ + return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, - ULARGE_INTEGER *plibNewPosition) +static HRESULT WINAPI BrowserService_NotifyRedirect(IBrowserService* This, IShellView *psv, PCIDLIST_ABSOLUTE pidl, BOOL *pfDidBrowse) { - ok(0, "unexpected call\n"); return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions) +static HRESULT WINAPI BrowserService_UpdateWindowList(IBrowserService* This) { - return S_OK; + return E_NOTIMPL; }
-static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocolEx *iface) +static HRESULT WINAPI BrowserService_UpdateBackForwardState(IBrowserService* This) { return S_OK; }
-static const char *protocol_doc_str; - -static HRESULT WINAPI ProtocolEx_StartEx(IInternetProtocolEx *iface, IUri *uri, IInternetProtocolSink *pOIProtSink, - IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE *dwReserved) +static HRESULT WINAPI BrowserService_SetFlags(IBrowserService* This, DWORD dwFlags, DWORD dwFlagMask) { - ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + return E_NOTIMPL; +}
- This->data = protocol_doc_str; - This->size = strlen(This->data); +static HRESULT WINAPI BrowserService_GetFlags(IBrowserService* This, DWORD *pdwFlags) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_CanNavigateNow(IBrowserService* This) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_GetPidl(IBrowserService* This, PIDLIST_ABSOLUTE *ppidl) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_SetReferrer(IBrowserService* This, PCIDLIST_ABSOLUTE pidl) +{ + return E_NOTIMPL; +} + +static DWORD WINAPI BrowserService_GetBrowserIndex(IBrowserService* This) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_GetBrowserByIndex(IBrowserService* This, DWORD dwID, IUnknown **ppunk) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_GetHistoryObject(IBrowserService* This, IOleObject **ppole, IStream **pstm, IBindCtx **ppbc) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_SetHistoryObject(IBrowserService* This, IOleObject *pole, BOOL fIsLocalAnchor) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_CacheOLEServer(IBrowserService* This, IOleObject *pole) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_GetSetCodePage(IBrowserService* This, VARIANT *pvarIn, VARIANT *pvarOut) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_OnHttpEquiv(IBrowserService* This, IShellView *psv, BOOL fDone, VARIANT *pvarargIn, VARIANT *pvarargOut) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_GetPalette(IBrowserService* This, HPALETTE *hpal) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI BrowserService_RegisterWindow(IBrowserService* This, BOOL fForceRegister, int swc) +{ + return E_NOTIMPL; +} + +static IBrowserServiceVtbl BrowserServiceVtbl = { + BrowserService_QueryInterface, + BrowserService_AddRef, + BrowserService_Release, + BrowserService_GetParentSite, + BrowserService_SetTitle, + BrowserService_GetTitle, + BrowserService_GetOleObject, + BrowserService_GetTravelLog, + BrowserService_ShowControlWindow, + BrowserService_IsControlWindowShown, + BrowserService_IEGetDisplayName, + BrowserService_IEParseDisplayName, + BrowserService_DisplayParseError, + BrowserService_NavigateToPidl, + BrowserService_SetNavigateState, + BrowserService_GetNavigateState, + BrowserService_NotifyRedirect, + BrowserService_UpdateWindowList, + BrowserService_UpdateBackForwardState, + BrowserService_SetFlags, + BrowserService_GetFlags, + BrowserService_CanNavigateNow, + BrowserService_GetPidl, + BrowserService_SetReferrer, + BrowserService_GetBrowserIndex, + BrowserService_GetBrowserByIndex, + BrowserService_GetHistoryObject, + BrowserService_SetHistoryObject, + BrowserService_CacheOLEServer, + BrowserService_GetSetCodePage, + BrowserService_OnHttpEquiv, + BrowserService_GetPalette, + BrowserService_RegisterWindow +}; + +static IBrowserService BrowserService = { &BrowserServiceVtbl }; + +static HRESULT WINAPI ShellBrowser_QueryInterface(IShellBrowser *iface, REFIID riid, void **ppv) +{ + return browserservice_qi(riid, ppv); +} + +static ULONG WINAPI ShellBrowser_AddRef(IShellBrowser *iface) +{ + return 2; +} + +static ULONG WINAPI ShellBrowser_Release(IShellBrowser *iface) +{ + return 1; +} + +static HRESULT WINAPI ShellBrowser_GetWindow(IShellBrowser *iface, HWND *phwnd) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_ContextSensitiveHelp(IShellBrowser *iface, BOOL fEnterMode) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_InsertMenusSB(IShellBrowser *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_SetMenuSB(IShellBrowser *iface, HMENU hmenuShared, HOLEMENU holemenuReserved, HWND hwndActiveObject) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_RemoveMenusSB(IShellBrowser *iface, HMENU hmenuShared) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_SetStatusTextSB(IShellBrowser *iface, LPCOLESTR pszStatusText) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_EnableModelessSB(IShellBrowser *iface, BOOL fEnable) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_TranslateAcceleratorSB(IShellBrowser *iface, MSG *pmsg, WORD wID) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_BrowseObject(IShellBrowser *iface, LPCITEMIDLIST pidl, UINT wFlags) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_GetViewStateStream(IShellBrowser *iface, DWORD grfMode, IStream **ppStrm) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_GetControlWindow(IShellBrowser *iface, UINT id, HWND *phwnd) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_SendControlMsg(IShellBrowser *iface, UINT id, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pret) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_QueryActiveShellView(IShellBrowser *iface, IShellView **ppshv) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_OnViewWindowActive(IShellBrowser* iface, IShellView *pshv) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI ShellBrowser_SetToolbarItems(IShellBrowser *iface, LPTBBUTTONSB lpButtons, UINT nButtons, UINT uFlags) +{ + return E_NOTIMPL; +} + +static const IShellBrowserVtbl ShellBrowserVtbl = { + ShellBrowser_QueryInterface, + ShellBrowser_AddRef, + ShellBrowser_Release, + ShellBrowser_GetWindow, + ShellBrowser_ContextSensitiveHelp, + ShellBrowser_InsertMenusSB, + ShellBrowser_SetMenuSB, + ShellBrowser_RemoveMenusSB, + ShellBrowser_SetStatusTextSB, + ShellBrowser_EnableModelessSB, + ShellBrowser_TranslateAcceleratorSB, + ShellBrowser_BrowseObject, + ShellBrowser_GetViewStateStream, + ShellBrowser_GetControlWindow, + ShellBrowser_SendControlMsg, + ShellBrowser_QueryActiveShellView, + ShellBrowser_OnViewWindowActive, + ShellBrowser_SetToolbarItems +}; + +static IShellBrowser ShellBrowser = { &ShellBrowserVtbl }; + +static HRESULT browserservice_qi(REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IShellBrowser, riid)) + *ppv = &ShellBrowser; + else if(IsEqualGUID(&IID_IBrowserService, riid)) + *ppv = &BrowserService; + else { + *ppv = NULL; + return E_NOINTERFACE; + } + return S_OK; +} + +static HRESULT WINAPI WebBrowser_QueryInterface(IWebBrowser2 *iface, REFIID riid, void **ppv) +{ + return wb_qi(riid, ppv); +} + +static ULONG WINAPI WebBrowser_AddRef(IWebBrowser2 *iface) +{ + return 2; +} + +static ULONG WINAPI WebBrowser_Release(IWebBrowser2 *iface) +{ + return 1; +} + +static HRESULT WINAPI WebBrowser_GetTypeInfoCount(IWebBrowser2 *iface, UINT *pctinfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GetTypeInfo(IWebBrowser2 *iface, UINT iTInfo, LCID lcid, LPTYPEINFO *ppTInfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GetIDsOfNames(IWebBrowser2 *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Invoke(IWebBrowser2 *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExepInfo, UINT *puArgErr) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GoBack(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GoForward(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GoHome(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GoSearch(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Navigate(IWebBrowser2 *iface, BSTR szUrl, VARIANT *Flags, VARIANT *TargetFrameName, + VARIANT *PostData, VARIANT *Headers) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Refresh(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Refresh2(IWebBrowser2 *iface, VARIANT *Level) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Stop(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Application(IWebBrowser2 *iface, IDispatch **ppDisp) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Parent(IWebBrowser2 *iface, IDispatch **ppDisp) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Container(IWebBrowser2 *iface, IDispatch **ppDisp) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Document(IWebBrowser2 *iface, IDispatch **ppDisp) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_TopLevelContainer(IWebBrowser2 *iface, VARIANT_BOOL *pBool) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Type(IWebBrowser2 *iface, BSTR *Type) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Left(IWebBrowser2 *iface, LONG *pl) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Left(IWebBrowser2 *iface, LONG Left) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Top(IWebBrowser2 *iface, LONG *pl) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Top(IWebBrowser2 *iface, LONG Top) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Width(IWebBrowser2 *iface, LONG *pl) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Width(IWebBrowser2 *iface, LONG Width) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Height(IWebBrowser2 *iface, LONG *pl) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Height(IWebBrowser2 *iface, LONG Height) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_LocationName(IWebBrowser2 *iface, BSTR *LocationName) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_LocationURL(IWebBrowser2 *iface, BSTR *LocationURL) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Busy(IWebBrowser2 *iface, VARIANT_BOOL *pBool) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Quit(IWebBrowser2 *iface) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_ClientToWindow(IWebBrowser2 *iface, int *pcx, int *pcy) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_PutProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT vtValue) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_GetProperty(IWebBrowser2 *iface, BSTR szProperty, VARIANT *pvtValue) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Name(IWebBrowser2 *iface, BSTR *Name) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_HWND(IWebBrowser2 *iface, SHANDLE_PTR *pHWND) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_FullName(IWebBrowser2 *iface, BSTR *FullName) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Path(IWebBrowser2 *iface, BSTR *Path) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Visible(IWebBrowser2 *iface, VARIANT_BOOL *pBool) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Visible(IWebBrowser2 *iface, VARIANT_BOOL Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL *pBool) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_StatusBar(IWebBrowser2 *iface, VARIANT_BOOL Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_StatusText(IWebBrowser2 *iface, BSTR *StatusText) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_StatusText(IWebBrowser2 *iface, BSTR StatusText) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_ToolBar(IWebBrowser2 *iface, int *Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_ToolBar(IWebBrowser2 *iface, int Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL *Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_MenuBar(IWebBrowser2 *iface, VARIANT_BOOL Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL *pbFullScreen) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_FullScreen(IWebBrowser2 *iface, VARIANT_BOOL bFullScreen) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_Navigate2(IWebBrowser2 *iface, VARIANT *URL, VARIANT *Flags, + VARIANT *TargetFrameName, VARIANT *PostData, VARIANT *Headers) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_QueryStatusWB(IWebBrowser2 *iface, OLECMDID cmdID, OLECMDF *pcmdf) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_ExecWB(IWebBrowser2 *iface, OLECMDID cmdID, + OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_ShowBrowserBar(IWebBrowser2 *iface, VARIANT *pvaClsid, + VARIANT *pvarShow, VARIANT *pvarSize) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_ReadyState(IWebBrowser2 *iface, READYSTATE *lpReadyState) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Offline(IWebBrowser2 *iface, VARIANT_BOOL *pbOffline) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Offline(IWebBrowser2 *iface, VARIANT_BOOL bOffline) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Silent(IWebBrowser2 *iface, VARIANT_BOOL *pbSilent) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Silent(IWebBrowser2 *iface, VARIANT_BOOL bSilent) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_RegisterAsBrowser(IWebBrowser2 *iface, + VARIANT_BOOL *pbRegister) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_RegisterAsBrowser(IWebBrowser2 *iface, + VARIANT_BOOL bRegister) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_RegisterAsDropTarget(IWebBrowser2 *iface, + VARIANT_BOOL *pbRegister) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_RegisterAsDropTarget(IWebBrowser2 *iface, + VARIANT_BOOL bRegister) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL *pbRegister) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_TheaterMode(IWebBrowser2 *iface, VARIANT_BOOL bRegister) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL *Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_AddressBar(IWebBrowser2 *iface, VARIANT_BOOL Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_get_Resizable(IWebBrowser2 *iface, VARIANT_BOOL *Value) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI WebBrowser_put_Resizable(IWebBrowser2 *iface, VARIANT_BOOL Value) +{ + return E_NOTIMPL; +} + +static const IWebBrowser2Vtbl WebBrowser2Vtbl = +{ + WebBrowser_QueryInterface, + WebBrowser_AddRef, + WebBrowser_Release, + WebBrowser_GetTypeInfoCount, + WebBrowser_GetTypeInfo, + WebBrowser_GetIDsOfNames, + WebBrowser_Invoke, + WebBrowser_GoBack, + WebBrowser_GoForward, + WebBrowser_GoHome, + WebBrowser_GoSearch, + WebBrowser_Navigate, + WebBrowser_Refresh, + WebBrowser_Refresh2, + WebBrowser_Stop, + WebBrowser_get_Application, + WebBrowser_get_Parent, + WebBrowser_get_Container, + WebBrowser_get_Document, + WebBrowser_get_TopLevelContainer, + WebBrowser_get_Type, + WebBrowser_get_Left, + WebBrowser_put_Left, + WebBrowser_get_Top, + WebBrowser_put_Top, + WebBrowser_get_Width, + WebBrowser_put_Width, + WebBrowser_get_Height, + WebBrowser_put_Height, + WebBrowser_get_LocationName, + WebBrowser_get_LocationURL, + WebBrowser_get_Busy, + WebBrowser_Quit, + WebBrowser_ClientToWindow, + WebBrowser_PutProperty, + WebBrowser_GetProperty, + WebBrowser_get_Name, + WebBrowser_get_HWND, + WebBrowser_get_FullName, + WebBrowser_get_Path, + WebBrowser_get_Visible, + WebBrowser_put_Visible, + WebBrowser_get_StatusBar, + WebBrowser_put_StatusBar, + WebBrowser_get_StatusText, + WebBrowser_put_StatusText, + WebBrowser_get_ToolBar, + WebBrowser_put_ToolBar, + WebBrowser_get_MenuBar, + WebBrowser_put_MenuBar, + WebBrowser_get_FullScreen, + WebBrowser_put_FullScreen, + WebBrowser_Navigate2, + WebBrowser_QueryStatusWB, + WebBrowser_ExecWB, + WebBrowser_ShowBrowserBar, + WebBrowser_get_ReadyState, + WebBrowser_get_Offline, + WebBrowser_put_Offline, + WebBrowser_get_Silent, + WebBrowser_put_Silent, + WebBrowser_get_RegisterAsBrowser, + WebBrowser_put_RegisterAsBrowser, + WebBrowser_get_RegisterAsDropTarget, + WebBrowser_put_RegisterAsDropTarget, + WebBrowser_get_TheaterMode, + WebBrowser_put_TheaterMode, + WebBrowser_get_AddressBar, + WebBrowser_put_AddressBar, + WebBrowser_get_Resizable, + WebBrowser_put_Resizable +}; + +static IWebBrowser2 WebBrowser2 = { &WebBrowser2Vtbl }; + +static HRESULT WINAPI WebBrowserPriv_QueryInterface(IWebBrowserPriv *iface, REFIID riid, void **ppv) +{ + return wb_qi(riid, ppv); +} + +static ULONG WINAPI WebBrowserPriv_AddRef(IWebBrowserPriv *iface) +{ + return 2; +} + +static ULONG WINAPI WebBrowserPriv_Release(IWebBrowserPriv *iface) +{ + return 1; +} + +static HRESULT WINAPI WebBrowserPriv_NavigateWithBindCtx(IWebBrowserPriv *iface, VARIANT *uri, VARIANT *flags, + VARIANT *target_frame, VARIANT *post_data, VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment) +{ + return S_OK; +} + +static HRESULT WINAPI WebBrowserPriv_OnClose(IWebBrowserPriv *iface) +{ + return E_NOTIMPL; +} + +static const IWebBrowserPrivVtbl WebBrowserPrivVtbl = { + WebBrowserPriv_QueryInterface, + WebBrowserPriv_AddRef, + WebBrowserPriv_Release, + WebBrowserPriv_NavigateWithBindCtx, + WebBrowserPriv_OnClose +}; + +static IWebBrowserPriv WebBrowserPriv = { &WebBrowserPrivVtbl }; + +static HRESULT wb_qi(REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IWebBrowser, riid) || + IsEqualGUID(&IID_IWebBrowserApp, riid) || IsEqualGUID(&IID_IWebBrowser2, riid)) + *ppv = &WebBrowser2; + else if(IsEqualGUID(riid, &IID_IWebBrowserPriv)) + *ppv = &WebBrowserPriv; + else { + *ppv = NULL; + return E_NOINTERFACE; + } + return S_OK; +} + +static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) +{ + return QueryInterface(riid, ppv); +} + +static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface) +{ + return 2; +} + +static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface) +{ + return 1; +} + +static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IShellBrowser, guidService)) { + ok(IsEqualGUID(&IID_IBrowserService, riid), "unexpected riid\n"); + *ppv = &BrowserService; + return S_OK; + } + + if(IsEqualGUID(&IID_IWebBrowserApp, guidService)) { + ok(IsEqualGUID(&IID_IWebBrowser2, riid), "unexpected riid\n"); + *ppv = &WebBrowser2; + return S_OK; + } + + return E_NOINTERFACE; +} + +static const IServiceProviderVtbl ServiceProviderVtbl = { + ServiceProvider_QueryInterface, + ServiceProvider_AddRef, + ServiceProvider_Release, + ServiceProvider_QueryService +}; + +static IServiceProvider ServiceProvider = { &ServiceProviderVtbl }; + +static HRESULT QueryInterface(REFIID riid, void **ppv) +{ + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid)) + *ppv = &ClientSite; + else if(IsEqualGUID(&IID_IOleDocumentSite, riid)) + *ppv = &DocumentSite; + else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid)) + *ppv = &InPlaceSite; + else if(IsEqualGUID(&IID_IServiceProvider, riid)) + *ppv = &ServiceProvider; + + return *ppv ? S_OK : E_NOINTERFACE; +} + +static IHTMLDocument2 *notif_doc; +static BOOL doc_complete; + +static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface, + REFIID riid, void**ppv) +{ + if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) { + *ppv = iface; + return S_OK; + } + + ok(0, "unexpected call\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface) +{ + return 2; +} + +static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface) +{ + return 1; +} + +static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID) +{ + if(dispID == DISPID_READYSTATE){ + BSTR state; + HRESULT hres; + + hres = IHTMLDocument2_get_readyState(notif_doc, &state); + ok(hres == S_OK, "get_readyState failed: %08lx\n", hres); + + if(!lstrcmpW(state, L"complete")) + doc_complete = TRUE; + + SysFreeString(state); + } + + return S_OK; +} + +static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = { + PropertyNotifySink_QueryInterface, + PropertyNotifySink_AddRef, + PropertyNotifySink_Release, + PropertyNotifySink_OnChanged, + PropertyNotifySink_OnRequestEdit +}; + +static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl }; + +typedef struct { + IInternetProtocolEx IInternetProtocolEx_iface; + IWinInetHttpInfo IWinInetHttpInfo_iface; + + LONG ref; + + IInternetProtocolSink *sink; + IUri *uri; + + ULONG size; + const char *data; + const char *ptr; +} ProtocolHandler; + +static DWORD WINAPI async_switch_proc(void *arg) +{ + PROTOCOLDATA protocol_data = { PI_FORCE_ASYNC }; + ProtocolHandler *protocol_handler = arg; + IInternetProtocolSink_Switch(protocol_handler->sink, &protocol_data); + return 0; +} + +static inline ProtocolHandler *impl_from_IInternetProtocolEx(IInternetProtocolEx *iface) +{ + return CONTAINING_RECORD(iface, ProtocolHandler, IInternetProtocolEx_iface); +} + +static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) +{ + ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid) || IsEqualGUID(&IID_IInternetProtocolEx, riid)) { + *ppv = &This->IInternetProtocolEx_iface; + }else if(IsEqualGUID(&IID_IWinInetInfo, riid) || IsEqualGUID(&IID_IWinInetHttpInfo, riid)) { + *ppv = &This->IWinInetHttpInfo_iface; + }else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI Protocol_AddRef(IInternetProtocolEx *iface) +{ + ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI Protocol_Release(IInternetProtocolEx *iface) +{ + ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + LONG ref = InterlockedDecrement(&This->ref); + + if(!ref) { + if(This->sink) + IInternetProtocolSink_Release(This->sink); + if(This->uri) + IUri_Release(This->uri); + free(This); + } + + return ref; +} + +static HRESULT WINAPI Protocol_Start(IInternetProtocolEx *iface, LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, + IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Protocol_Continue(IInternetProtocolEx *iface, PROTOCOLDATA *pProtocolData) +{ + ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + IServiceProvider *service_provider; + IHttpNegotiate *http_negotiate; + WCHAR *addl_headers = NULL; + HRESULT hres; + BSTR bstr; + + hres = IInternetProtocolSink_QueryInterface(This->sink, &IID_IServiceProvider, (void**)&service_provider); + ok(hres == S_OK, "Could not get IServiceProvider iface: %08lx\n", hres); + + hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate, &IID_IHttpNegotiate, (void**)&http_negotiate); + IServiceProvider_Release(service_provider); + ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08lx\n", hres); + + hres = IUri_GetDisplayUri(This->uri, &bstr); + ok(hres == S_OK, "Failed to get display uri: %08lx\n", hres); + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, bstr, L"", 0, &addl_headers); + ok(hres == S_OK, "BeginningTransaction failed: %08lx\n", hres); + CoTaskMemFree(addl_headers); + SysFreeString(bstr); + + bstr = SysAllocString(L"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); + hres = IHttpNegotiate_OnResponse(http_negotiate, 200, bstr, NULL, NULL); + ok(hres == S_OK, "OnResponse failed: %08lx\n", hres); + IHttpNegotiate_Release(http_negotiate); + SysFreeString(bstr); + + hres = IInternetProtocolSink_ReportData(This->sink, BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION, + This->size, This->size); + ok(hres == S_OK, "ReportData failed: %08lx\n", hres); + + hres = IInternetProtocolSink_ReportResult(This->sink, S_OK, 0, NULL); + ok(hres == S_OK, "ReportResult failed: %08lx\n", hres); + + IInternetProtocolEx_Release(&This->IInternetProtocolEx_iface); + return S_OK; +} + +static HRESULT WINAPI Protocol_Abort(IInternetProtocolEx *iface, HRESULT hrReason, DWORD dwOptions) +{ + trace("Abort(%08lx %lx)\n", hrReason, dwOptions); + return E_NOTIMPL; +} + +static HRESULT WINAPI Protocol_Terminate(IInternetProtocolEx *iface, DWORD dwOptions) +{ + return S_OK; +} + +static HRESULT WINAPI Protocol_Suspend(IInternetProtocolEx *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Protocol_Resume(IInternetProtocolEx *iface) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Protocol_Read(IInternetProtocolEx *iface, void *pv, ULONG cb, ULONG *pcbRead) +{ + ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + ULONG read; + + read = This->size - (This->ptr - This->data); + if(read > cb) + read = cb; + + if(read) { + memcpy(pv, This->ptr, read); + This->ptr += read; + } + + *pcbRead = read; + return (This->ptr != This->data + This->size) ? S_OK : S_FALSE; +} + +static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER *plibNewPosition) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI Protocol_LockRequest(IInternetProtocolEx *iface, DWORD dwOptions) +{ + return S_OK; +} + +static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocolEx *iface) +{ + return S_OK; +} + +static const char *protocol_doc_str; + +static HRESULT WINAPI ProtocolEx_StartEx(IInternetProtocolEx *iface, IUri *uri, IInternetProtocolSink *pOIProtSink, + IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE *dwReserved) +{ + ProtocolHandler *This = impl_from_IInternetProtocolEx(iface); + + This->data = protocol_doc_str; + This->size = strlen(This->data);
IInternetProtocolSink_AddRef(This->sink = pOIProtSink); IUri_AddRef(This->uri = uri); @@ -3725,24 +4779,12 @@ static IClassFactory protocol_cf = { &ProtocolCFVtbl };
static void doc_load_string(IHTMLDocument2 *doc, const char *str) { - IInternetSession *internet_session; IPersistStreamInit *init; IStream *stream; HRESULT hres; HGLOBAL mem; SIZE_T len;
- if(protocol_doc_str) { - hres = CoInternetGetSession(0, &internet_session, 0); - ok(hres == S_OK, "CoInternetGetSession failed: %08lx\n", hres); - - hres = IInternetSession_UnregisterNameSpace(internet_session, &protocol_cf, L"http"); - ok(hres == S_OK, "RegisterNameSpace failed: %08lx\n", hres); - - IInternetSession_Release(internet_session); - protocol_doc_str = NULL; - } - notif_doc = doc;
doc_complete = FALSE; @@ -3760,6 +4802,51 @@ static void doc_load_string(IHTMLDocument2 *doc, const char *str) IStream_Release(stream); }
+static void doc_load_res(IHTMLDocument2 *doc, const char *file) +{ + static const WCHAR res[] = { 'r','e','s',':','/','/' }; + WCHAR url[INTERNET_MAX_URL_LENGTH]; + IPersistMoniker *persist; + IHlinkTarget *hlink; + IBindCtx *bind; + IMoniker *mon; + HRESULT hres; + DWORD len; + BSTR bstr; + + wcscpy(url, SZ_HTML_CLIENTSITE_OBJECTPARAM); + CreateBindCtx(0, &bind); + IBindCtx_RegisterObjectParam(bind, url, (IUnknown*)&ClientSite); + + notif_doc = doc; + doc_complete = FALSE; + + memcpy(url, res, sizeof(res)); + len = 6 + GetModuleFileNameW(NULL, url + ARRAY_SIZE(res), ARRAY_SIZE(url) - ARRAY_SIZE(res) - 1); + url[len++] = '/'; + MultiByteToWideChar(CP_ACP, 0, file, -1, url + len, ARRAY_SIZE(url) - len); + + bstr = SysAllocString(url); + hres = CreateURLMoniker(NULL, bstr, &mon); + SysFreeString(bstr); + ok(hres == S_OK, "CreateUrlMoniker failed: %08lx\n", hres); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker, (void**)&persist); + ok(hres == S_OK, "Could not get IPersistMoniker iface: %08lx\n", hres); + + hres = IPersistMoniker_Load(persist, FALSE, mon, bind, 0x12); + ok(hres == S_OK, "Load failed: %08lx\n", hres); + IPersistMoniker_Release(persist); + IBindCtx_Release(bind); + IMoniker_Release(mon); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHlinkTarget, (void**)&hlink); + ok(hres == S_OK, "Could not get IHlinkTarget iface: %08lx\n", hres); + hres = IHlinkTarget_Navigate(hlink, 0, NULL); + ok(hres == S_OK, "Navigate failed: %08lx\n", hres); + IHlinkTarget_Release(hlink); +} + static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise) { IConnectionPointContainer *container; @@ -3812,6 +4899,32 @@ static void set_client_site(IHTMLDocument2 *doc, BOOL set)
IOleObject_Release(oleobj); } + +static void navigate(IHTMLDocument2 *doc, const WCHAR *url) +{ + IHTMLLocation *location; + HRESULT hres; + BSTR bstr; + MSG msg; + + location = NULL; + hres = IHTMLDocument2_get_location(doc, &location); + ok(hres == S_OK, "get_location failed: %08lx\n", hres); + ok(location != NULL, "location == NULL\n"); + + doc_complete = FALSE; + bstr = SysAllocString(url); + hres = IHTMLLocation_replace(location, bstr); + ok(hres == S_OK, "replace failed: %08lx\n", hres); + IHTMLLocation_Release(location); + SysFreeString(bstr); + + while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } +} + static IHTMLDocument2 *create_document(void) { IHTMLDocument2 *doc; @@ -3880,8 +4993,9 @@ static IHTMLDocument2 *create_document_with_origin(const char *str)
typedef void (*testfunc_t)(IHTMLDocument2*);
-static void run_test(const char *str, testfunc_t test) +static void run_test_impl(const char *str, testfunc_t test, BOOL from_res) { + IInternetSession *internet_session; IHTMLDocument2 *doc; IHTMLElement *body = NULL; MSG msg; @@ -3891,7 +5005,23 @@ static void run_test(const char *str, testfunc_t test) if (!doc) return; set_client_site(doc, TRUE); - doc_load_string(doc, str); + + if(protocol_doc_str) { + hres = CoInternetGetSession(0, &internet_session, 0); + ok(hres == S_OK, "CoInternetGetSession failed: %08lx\n", hres); + + hres = IInternetSession_UnregisterNameSpace(internet_session, &protocol_cf, L"http"); + ok(hres == S_OK, "RegisterNameSpace failed: %08lx\n", hres); + + IInternetSession_Release(internet_session); + protocol_doc_str = NULL; + } + + if(from_res) + doc_load_res(doc, str); + else + doc_load_string(doc, str); + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
while(!doc_complete && GetMessageA(&msg, NULL, 0, 0)) { @@ -3935,6 +5065,16 @@ static void run_test(const char *str, testfunc_t test) IHTMLDocument2_Release(doc); }
+static void run_test(const char *str, testfunc_t test) +{ + return run_test_impl(str, test, FALSE); +} + +static void run_test_from_res(const char *res, testfunc_t test) +{ + return run_test_impl(res, test, TRUE); +} + static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { return DefWindowProcA(hwnd, msg, wParam, lParam); @@ -4252,8 +5392,11 @@ START_TEST(events) run_test(empty_doc_str, test_submit); run_test(empty_doc_ie9_str, test_submit); run_test(iframe_doc_str, test_iframe_connections); - if(is_ie9plus) + if(is_ie9plus) { + run_test_from_res("doc_with_prop.html", test_doc_obj); + run_test_from_res("doc_with_prop_ie9.html", test_doc_obj); run_test(empty_doc_ie9_str, test_create_event); + }
test_empty_document(); test_storage_events(empty_doc_str); diff --git a/dlls/mshtml/tests/rsrc.rc b/dlls/mshtml/tests/rsrc.rc index 25c81246b26..9bff32a78e9 100644 --- a/dlls/mshtml/tests/rsrc.rc +++ b/dlls/mshtml/tests/rsrc.rc @@ -73,6 +73,12 @@ blank2.html HTML "blank.html" /* @makedep: blank.html */ 123 HTML "blank.html"
+/* @makedep: doc_with_prop.html */ +doc_with_prop.html HTML "doc_with_prop.html" + +/* @makedep: doc_with_prop_ie9.html */ +doc_with_prop_ie9.html HTML "doc_with_prop_ie9.html" + /* For res: protocol test: */
/* @makedep: jstest.html */
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/oleobj.c | 11 +---------- dlls/mshtml/tests/events.c | 7 +++++++ 2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c index 5c7673b1649..7821abdb390 100644 --- a/dlls/mshtml/oleobj.c +++ b/dlls/mshtml/oleobj.c @@ -2384,16 +2384,7 @@ HTMLDOCUMENTOBJ_FWD_TO_NODE_1(HTMLDocument2, put_onbeforeupdate, VARIANT) HTMLDOCUMENTOBJ_FWD_TO_NODE_1(HTMLDocument2, get_onbeforeupdate, VARIANT*) HTMLDOCUMENTOBJ_FWD_TO_NODE_1(HTMLDocument2, put_onerrorupdate, VARIANT) HTMLDOCUMENTOBJ_FWD_TO_NODE_1(HTMLDocument2, get_onerrorupdate, VARIANT*) - -static HRESULT WINAPI DocObjHTMLDocument2_toString(IHTMLDocument2 *iface, BSTR *String) -{ - HTMLDocumentObj *This = impl_from_IHTMLDocument2(iface); - - TRACE("(%p)->(%p)\n", This, String); - - return dispex_to_string(&This->dispex, String); -} - +HTMLDOCUMENTOBJ_FWD_TO_NODE_1(HTMLDocument2, toString, BSTR*) HTMLDOCUMENTOBJ_FWD_TO_NODE_3(HTMLDocument2, createStyleSheet, BSTR,LONG,IHTMLStyleSheet**)
static const IHTMLDocument2Vtbl DocObjHTMLDocument2Vtbl = { diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index ab20d088840..82daa1dc07c 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2786,6 +2786,13 @@ static void test_doc_obj(IHTMLDocument2 *doc) CHECK_CALLED(docobj_onclick); }
+ bstr = NULL; + hres = IHTMLDocument2_toString(doc, &bstr); + ok(hres == S_OK, "toString failed: %08lx\n", hres); + todo_wine_if(document_mode >= 9) + ok(!wcscmp(bstr, (document_mode < 9 ? L"[object]" : L"[object Document]")), "toString returned %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + /* Navigate to a different document mode page, checking using the same doc obj. Test that it breaks COM rules, since IEventTarget is conditionally exposed. All the events registered on the old doc node are also removed. */
From: Gabriel Ivăncescu gabrielopcode@gmail.com
And get rid of the dispex since it's useless now.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 1 - dlls/mshtml/oleobj.c | 165 ++++++----------------------------- dlls/mshtml/tests/dom.c | 27 ++++++ dlls/mshtml/tests/events.c | 87 +++++++++++++++++- 4 files changed, 141 insertions(+), 139 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index e7f5481b886..e3971258b13 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -640,7 +640,6 @@ struct ConnectionPoint { };
struct HTMLDocumentObj { - DispatchEx dispex; IUnknown IUnknown_inner; IDispatchEx IDispatchEx_iface; ICustomDoc ICustomDoc_iface; diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c index 7821abdb390..54ce4e0a159 100644 --- a/dlls/mshtml/oleobj.c +++ b/dlls/mshtml/oleobj.c @@ -27,6 +27,7 @@ #include "ole2.h" #include "shlguid.h" #include "shdeprecated.h" +#include "mscoree.h" #include "mshtmdid.h" #include "idispids.h"
@@ -3410,8 +3411,12 @@ static HRESULT WINAPI HTMLDocumentObj_QueryInterface(IUnknown *iface, REFIID rii TRACE("(%p)->(IID_IStdMarshalInfo %p) returning NULL\n", This, ppv); *ppv = NULL; return E_NOINTERFACE; - }else if(dispex_query_interface(&This->dispex, riid, ppv)) { - return *ppv ? S_OK : E_NOINTERFACE; + }else if(IsEqualGUID(&IID_IDispatchJS, riid) || + IsEqualGUID(&IID_UndocumentedScriptIface, riid) || + IsEqualGUID(&IID_IMarshal, riid) || + IsEqualGUID(&IID_IManagedObject, riid)) { + *ppv = NULL; + return E_NOINTERFACE; }else { FIXME("Unimplemented interface %s\n", debugstr_mshtml_guid(riid)); *ppv = NULL; @@ -3472,7 +3477,6 @@ static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface)
remove_target_tasks(This->task_magic); ConnectionPointContainer_Destroy(&This->cp_container); - release_dispex(&This->dispex);
if(This->nscontainer) detach_gecko_browser(This->nscontainer); @@ -3490,123 +3494,50 @@ static const IUnknownVtbl HTMLDocumentObjVtbl = {
/********************************************************** * IDispatchEx implementation + * + * Forwarding this breaks Dispatch rules by potentially retrieving + * a different DISPID for the same name, if the node was changed + * while using the same doc obj, but it is how native works. */ static inline HTMLDocumentObj *impl_from_IDispatchEx(IDispatchEx *iface) { return CONTAINING_RECORD(iface, HTMLDocumentObj, IDispatchEx_iface); }
-static HRESULT WINAPI DocObjDispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IUnknown_QueryInterface(This->outer_unk, riid, ppv); -} - -static ULONG WINAPI DocObjDispatchEx_AddRef(IDispatchEx *iface) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IUnknown_AddRef(This->outer_unk); -} - -static ULONG WINAPI DocObjDispatchEx_Release(IDispatchEx *iface) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IUnknown_Release(This->outer_unk); -} - -static HRESULT WINAPI DocObjDispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI DocObjDispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid, - ITypeInfo **ppTInfo) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI DocObjDispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LPOLESTR *rgszNames, - UINT cNames, LCID lcid, DISPID *rgDispId) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); -} +HTMLDOCUMENTOBJ_IUNKNOWN_METHODS(DispatchEx) +HTMLDOCUMENTOBJ_FWD_TO_NODE_1(DispatchEx, GetTypeInfoCount, UINT*) +HTMLDOCUMENTOBJ_FWD_TO_NODE_3(DispatchEx, GetTypeInfo, UINT,LCID,ITypeInfo**) +HTMLDOCUMENTOBJ_FWD_TO_NODE_5(DispatchEx, GetIDsOfNames, REFIID,LPOLESTR*,UINT,LCID,DISPID*)
static HRESULT WINAPI DocObjDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_InvokeEx(&This->IDispatchEx_iface, dispIdMember, lcid, wFlags, pDispParams, + + if(!This->doc_node) + return E_UNEXPECTED; + return IDispatchEx_InvokeEx(&This->doc_node->IDispatchEx_iface, dispIdMember, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, NULL); }
-static HRESULT WINAPI DocObjDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetDispID(&This->dispex.IDispatchEx_iface, bstrName, grfdex, pid); -} +HTMLDOCUMENTOBJ_FWD_TO_NODE_3(DispatchEx, GetDispID, BSTR,DWORD,DISPID*)
static HRESULT WINAPI DocObjDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { HTMLDocumentObj *This = impl_from_IDispatchEx(iface);
- if(This->window) { - switch(id) { - case DISPID_READYSTATE: - TRACE("DISPID_READYSTATE\n"); - - if(!(wFlags & DISPATCH_PROPERTYGET)) - return E_INVALIDARG; - - V_VT(pvarRes) = VT_I4; - V_I4(pvarRes) = This->window->readystate; - return S_OK; - default: - break; - } - } - - return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); -} - -static HRESULT WINAPI DocObjDispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_DeleteMemberByName(&This->dispex.IDispatchEx_iface, bstrName, grfdex); -} - -static HRESULT WINAPI DocObjDispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_DeleteMemberByDispID(&This->dispex.IDispatchEx_iface, id); -} - -static HRESULT WINAPI DocObjDispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetMemberProperties(&This->dispex.IDispatchEx_iface, id, grfdexFetch, pgrfdex); -} - -static HRESULT WINAPI DocObjDispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetMemberName(&This->dispex.IDispatchEx_iface, id, pbstrName); -} - -static HRESULT WINAPI DocObjDispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetNextDispID(&This->dispex.IDispatchEx_iface, grfdex, id, pid); + if(!This->doc_node) + return E_UNEXPECTED; + return IDispatchEx_InvokeEx(&This->doc_node->IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); }
-static HRESULT WINAPI DocObjDispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk) -{ - HTMLDocumentObj *This = impl_from_IDispatchEx(iface); - return IDispatchEx_GetNameSpaceParent(&This->dispex.IDispatchEx_iface, ppunk); -} +HTMLDOCUMENTOBJ_FWD_TO_NODE_2(DispatchEx, DeleteMemberByName, BSTR,DWORD) +HTMLDOCUMENTOBJ_FWD_TO_NODE_1(DispatchEx, DeleteMemberByDispID, DISPID) +HTMLDOCUMENTOBJ_FWD_TO_NODE_3(DispatchEx, GetMemberProperties, DISPID,DWORD,DWORD*) +HTMLDOCUMENTOBJ_FWD_TO_NODE_2(DispatchEx, GetMemberName, DISPID,BSTR*) +HTMLDOCUMENTOBJ_FWD_TO_NODE_3(DispatchEx, GetNextDispID, DWORD,DISPID,DISPID*) +HTMLDOCUMENTOBJ_FWD_TO_NODE_1(DispatchEx, GetNameSpaceParent, IUnknown**)
static const IDispatchExVtbl DocObjDispatchExVtbl = { DocObjDispatchEx_QueryInterface, @@ -3712,43 +3643,6 @@ static const cpc_entry_t HTMLDocumentObj_cpc[] = { {NULL} };
-static HRESULT HTMLDocumentObj_location_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, VARIANT *res, - EXCEPINFO *ei, IServiceProvider *caller) -{ - HTMLDocumentObj *This = CONTAINING_RECORD(dispex, HTMLDocumentObj, dispex); - - if(!(flags & DISPATCH_PROPERTYPUT) || !This->window) - return S_FALSE; - - return IDispatchEx_InvokeEx(&This->window->base.IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION, - 0, flags, dp, res, ei, caller); -} - -static const tid_t HTMLDocumentObj_iface_tids[] = { - IHTMLDocument3_tid, - IHTMLDocument4_tid, - IHTMLDocument5_tid, - 0 -}; - -static void HTMLDocumentObj_init_dispex_info(dispex_data_t *info, compat_mode_t mode) -{ - static const dispex_hook_t document2_hooks[] = { - {DISPID_IHTMLDOCUMENT2_URL, NULL, L"URL"}, - {DISPID_IHTMLDOCUMENT2_LOCATION, HTMLDocumentObj_location_hook}, - {DISPID_UNKNOWN} - }; - dispex_info_add_interface(info, IHTMLDocument2_tid, document2_hooks); -} - -static dispex_static_data_t HTMLDocumentObj_dispex = { - L"HTMLDocumentObj", - NULL, - DispHTMLDocument_tid, - HTMLDocumentObj_iface_tids, - HTMLDocumentObj_init_dispex_info -}; - static HRESULT create_document_object(BOOL is_mhtml, IUnknown *outer, REFIID riid, void **ppv) { HTMLDocumentObj *doc; @@ -3789,7 +3683,6 @@ static HRESULT create_document_object(BOOL is_mhtml, IUnknown *outer, REFIID rii
doc->outer_unk = outer ? outer : &doc->IUnknown_inner;
- init_dispatch(&doc->dispex, (IUnknown*)&doc->ICustomDoc_iface, &HTMLDocumentObj_dispex, COMPAT_MODE_QUIRKS); ConnectionPointContainer_Init(&doc->cp_container, &doc->IUnknown_inner, HTMLDocumentObj_cpc); HTMLDocumentObj_Persist_Init(doc); HTMLDocumentObj_Service_Init(doc); diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 70b047ccbe1..c31de136cd8 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -9477,10 +9477,37 @@ static void test_elems(IHTMLDocument2 *doc) elem = get_doc_elem_by_id(doc, L"objid"); ok(elem != NULL, "elem == NULL\n"); if(elem) { + IDispatchEx *dispex = get_dispex_iface((IUnknown*)doc); + DISPPARAMS dp = { 0 }; + DISPID dispid; + VARIANT var; + BSTR name; + test_object_vspace((IUnknown*)elem, 100); test_object_name(elem, L"objname"); + + name = SysAllocString(L"objname"); + hres = IDispatchEx_GetDispID(dispex, name, fdexNameCaseSensitive, &dispid); + ok(hres == S_OK, "GetDispID(objname) returned: %08lx\n", hres); + SysFreeString(name); + + hres = IDispatchEx_Invoke(dispex, dispid, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &var, NULL, NULL); + ok(hres == S_OK, "Invoke(objname) failed: %08lx\n", hres); + ok(V_VT(&var) == VT_DISPATCH, "VT = %d\n", V_VT(&var)); + ok(V_DISPATCH(&var) != NULL, "objname = null\n"); + + elem2 = get_elem_iface((IUnknown*)V_DISPATCH(&var)); + IDispatch_Release(V_DISPATCH(&var)); + + test_object_vspace((IUnknown*)elem2, 100); + test_object_name(elem2, L"objname"); + todo_wine + ok(elem != elem2, "elem == elem2\n"); + IHTMLElement_Release(elem2); + set_object_name(elem, L"test"); set_object_name(elem, NULL); + IDispatchEx_Release(dispex); IHTMLElement_Release(elem); }
diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 82daa1dc07c..543e50ee5ae 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2746,11 +2746,14 @@ static void test_iframe_connections(IHTMLDocument2 *doc)
static void test_doc_obj(IHTMLDocument2 *doc) { + DISPID dispid, import_node_id, has_own_prop_id; IEventTarget *event_target; + DISPPARAMS dp = { 0 }; IHTMLDocument6 *doc6; + IDispatchEx *dispex; IHTMLElement *body; + VARIANT res, arg; HRESULT hres; - VARIANT res; BSTR bstr;
event_target = (void*)0xdeadbeef; @@ -2793,9 +2796,74 @@ static void test_doc_obj(IHTMLDocument2 *doc) ok(!wcscmp(bstr, (document_mode < 9 ? L"[object]" : L"[object Document]")), "toString returned %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr);
+ /* IHTMLDocument6 prop */ + bstr = SysAllocString(L"onstoragecommit"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); + ok(hres == S_OK, "GetIDsOfNames(onstoragecommit) returned: %08lx\n", hres); + SysFreeString(bstr); + + /* IHTMLDocument7 method */ + bstr = SysAllocString(L"importNode"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); + ok(hres == (document_mode < 9 ? DISP_E_UNKNOWNNAME : S_OK), "GetIDsOfNames(importNode) returned: %08lx\n", hres); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres); + + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameEnsure, &import_node_id); + ok(hres == S_OK, "GetDispID(importNode) returned: %08lx\n", hres); + if(document_mode >= 9) + ok(import_node_id == dispid, "GetDispID(importNode) != GetIDsOfNames(importNode)\n"); + IDispatchEx_Release(dispex); + SysFreeString(bstr); + + /* prop set via script on node */ + bstr = SysAllocString(L"prop"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); + ok(hres == S_OK, "GetIDsOfNames(prop) returned: %08lx\n", hres); + SysFreeString(bstr); + + hres = IHTMLDocument2_Invoke(doc, dispid, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &res, NULL, NULL); + ok(hres == S_OK, "Invoke(prop) failed: %08lx\n", hres); + ok(V_VT(&res) == VT_I4, "VT(prop) = %d\n", V_VT(&res)); + ok(V_I4(&res) == 137, "prop = %ld\n", V_I4(&res)); + + /* jscript prop on prototype chain */ + bstr = SysAllocString(L"hasOwnProperty"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &has_own_prop_id); + todo_wine_if(document_mode >= 9) + ok(hres == (document_mode < 9 ? DISP_E_UNKNOWNNAME : S_OK), "GetIDsOfNames(hasOwnProperty) returned: %08lx\n", hres); + SysFreeString(bstr); + + if(hres == S_OK) { + dp.cArgs = 1; + dp.rgvarg = &arg; + V_VT(&arg) = VT_BSTR; + V_BSTR(&arg) = SysAllocString(L"createElement"); + hres = IHTMLDocument2_Invoke(doc, has_own_prop_id, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, NULL, NULL); + ok(hres == S_OK, "Invoke(hasOwnProperty("createElement")) failed: %08lx\n", hres); + ok(V_VT(&res) == VT_BOOL, "VT = %d\n", V_VT(&res)); + todo_wine + ok(V_BOOL(&res) == VARIANT_FALSE, "hasOwnProperty("createElement") = %d\n", V_BOOL(&res)); + + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &V_BSTR(&arg), 1, 0, &dispid); + ok(hres == S_OK, "GetIDsOfNames(createElement) returned: %08lx\n", hres); + SysFreeString(V_BSTR(&arg)); + + V_BSTR(&arg) = SysAllocString(L"prop"); + hres = IHTMLDocument2_Invoke(doc, has_own_prop_id, &IID_NULL, 0, DISPATCH_METHOD, &dp, &res, NULL, NULL); + ok(hres == S_OK, "Invoke(hasOwnProperty("prop")) failed: %08lx\n", hres); + ok(V_VT(&res) == VT_BOOL, "VT = %d\n", V_VT(&res)); + ok(V_BOOL(&res) == VARIANT_TRUE, "hasOwnProperty("prop") = %d\n", V_BOOL(&res)); + SysFreeString(V_BSTR(&arg)); + } + /* Navigate to a different document mode page, checking using the same doc obj. Test that it breaks COM rules, since IEventTarget is conditionally exposed. - All the events registered on the old doc node are also removed. */ + All the events registered on the old doc node are also removed. + + DISPIDs are forwarded to the node, and thus it also breaks Dispatch rules, + where the same name will potentially receive a different DISPID. */ navigate(doc, document_mode < 9 ? L"doc_with_prop_ie9.html" : L"doc_with_prop.html");
hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument6, (void**)&doc6); @@ -2819,10 +2887,25 @@ static void test_doc_obj(IHTMLDocument2 *doc) ok(hres == S_OK, "click failed: %08lx\n", hres); IHTMLElement_Release(body); pump_msgs(NULL); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres); + + bstr = SysAllocString(L"importNode"); + hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameEnsure, &dispid); + ok(hres == S_OK, "GetDispID(importNode) returned: %08lx\n", hres); + ok(dispid != import_node_id, "importNode on new doc node == old importNode\n"); + IDispatchEx_Release(dispex); + SysFreeString(bstr); }else { ok(hres == S_OK, "hres = %08lx, expected S_OK\n", hres); ok(!!event_target, "event_target = NULL\n"); IEventTarget_Release(event_target); + + bstr = SysAllocString(L"importNode"); + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, &bstr, 1, 0, &dispid); + ok(hres == S_OK, "GetIDsOfNames(importNode) returned: %08lx\n", hres); + ok(dispid != import_node_id, "importNode on new doc node == old created importNode\n"); } }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Native ignores any cNames > 1 and doesn't even fill the dispids for them. Note that it was already wrong; the multiple dispids are supposed to correspond to the member's argument names, not extra dispids.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 13 ++-- dlls/mshtml/htmlwindow.c | 12 ++-- dlls/mshtml/tests/dom.c | 101 +++++++++++++++++++++++++++++ dlls/mshtml/tests/xmlhttprequest.c | 31 +++++++++ 4 files changed, 142 insertions(+), 15 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index d8aaf819f58..c70deb67209 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1636,19 +1636,16 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LCID lcid, DISPID *rgDispId) { DispatchEx *This = impl_from_IDispatchEx(iface); - UINT i; - HRESULT hres; + HRESULT hres = S_OK;
TRACE("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
- for(i=0; i < cNames; i++) { - hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i); - if(FAILED(hres)) - return hres; - } + /* Native ignores all cNames > 1, and doesn't even fill them */ + if(cNames) + hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId);
- return S_OK; + return hres; }
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 7014a4cd4b4..c2475afd1f6 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3476,19 +3476,17 @@ static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid LCID lcid, DISPID *rgDispId) { HTMLWindow *This = impl_from_IDispatchEx(iface); - UINT i; - HRESULT hres; + HRESULT hres = S_OK;
WARN("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
- for(i=0; i < cNames; i++) { + /* Native ignores all cNames > 1, and doesn't even fill them */ + if(cNames) { /* We shouldn't use script's IDispatchEx here, so we shouldn't use GetDispID */ - hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i); - if(FAILED(hres)) - return hres; + hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[0], 0, rgDispId); }
- return S_OK; + return hres; }
static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index c31de136cd8..4e6ad469b28 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -27,6 +27,7 @@ #include "ole2.h" #include "mshtml.h" #include "mshtmcid.h" +#include "mshtmdid.h" #include "mshtmhst.h" #include "docobj.h" #include "hlink.h" @@ -5288,6 +5289,98 @@ static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const WCHAR SysFreeString(tmp); }
+static void test_doc_GetIDsOfNames(IHTMLDocument2 *doc) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + bstr[0] = SysAllocString(L"createStyleSheet"); + bstr[1] = SysAllocString(L"bstrHref"); + bstr[2] = SysAllocString(L"lIndex"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLDocument2_GetIDsOfNames(doc, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLDOCUMENT2_CREATESTYLESHEET, "createStyleSheet dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "bstrHref dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "lIndex dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + +static void test_window_GetIDsOfNames(IHTMLWindow2 *window) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + bstr[0] = SysAllocString(L"showHelp"); + bstr[1] = SysAllocString(L"helpURL"); + bstr[2] = SysAllocString(L"helpArg"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLWindow2_GetIDsOfNames(window, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLWINDOW2_SHOWHELP, "showHelp dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "helpURL dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "helpArg dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + +static void test_elem_GetIDsOfNames(IHTMLElement *elem) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + /* IE9+ use something like js proxies even on native and have different dispids */ + if(compat_mode >= COMPAT_IE9) + return; + + bstr[0] = SysAllocString(L"insertAdjacentText"); + bstr[1] = SysAllocString(L"where"); + bstr[2] = SysAllocString(L"text"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLElement_GetIDsOfNames(elem, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLELEMENT_INSERTADJACENTTEXT, "insertAdjacentText dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "where dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "text dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + +static void test_attr_GetIDsOfNames(IHTMLDOMAttribute *attr) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + bstr[0] = SysAllocString(L"insertBefore"); + bstr[1] = SysAllocString(L"newChild"); + bstr[2] = SysAllocString(L"refChild"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLDOMAttribute_GetIDsOfNames(attr, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLDOMATTRIBUTE2_INSERTBEFORE, "insertBefore dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "newChild dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "refChild dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); +} + static void test_elem_bounding_client_rect(IUnknown *unk) { IHTMLRectCollection *rects; @@ -5462,6 +5555,7 @@ static IHTMLElement *get_elem_by_id(IHTMLDocument2 *doc, const WCHAR *id, BOOL e elem = get_elem_iface((IUnknown*)disp); IDispatch_Release(disp);
+ test_elem_GetIDsOfNames(elem); return elem; }
@@ -5482,6 +5576,8 @@ static IHTMLElement *get_doc_elem_by_id(IHTMLDocument2 *doc, const WCHAR *id)
IHTMLDocument3_Release(doc3);
+ if(elem) + test_elem_GetIDsOfNames(elem); return elem; }
@@ -6854,6 +6950,8 @@ static void test_doc_elem(IHTMLDocument2 *doc) HRESULT hres; BSTR bstr;
+ test_doc_GetIDsOfNames(doc); + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3); ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08lx\n", hres);
@@ -6875,6 +6973,7 @@ static void test_doc_elem(IHTMLDocument2 *doc) owner_doc = get_owner_doc((IUnknown*)elem); ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n"); IHTMLDocument2_Release(owner_doc); + test_doc_GetIDsOfNames(doc_node);
owner_doc = get_owner_doc((IUnknown*)doc_node); ok(!owner_doc, "owner_doc = %p\n", owner_doc); @@ -7158,6 +7257,7 @@ static void test_window(IHTMLDocument2 *doc) win_skip("IID_ITravelLogClient not supported\n");
test_disp((IUnknown*)window, &DIID_DispHTMLWindow2, &CLSID_HTMLWindow2, L"[object]"); + test_window_GetIDsOfNames(window);
hres = IHTMLWindow2_get_document(window, &doc2); ok(hres == S_OK, "get_document failed: %08lx\n", hres); @@ -9796,6 +9896,7 @@ static void test_attr(IHTMLDocument2 *doc, IHTMLElement *elem) test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode); test_attr_specified(attr, VARIANT_TRUE); test_attr_parent(attr); + test_attr_GetIDsOfNames(attr);
attr2 = get_elem_attr_node((IUnknown*)elem, L"id", TRUE); ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n"); diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c index 6aef9f5a35d..a3ec54ffef6 100644 --- a/dlls/mshtml/tests/xmlhttprequest.c +++ b/dlls/mshtml/tests/xmlhttprequest.c @@ -25,6 +25,7 @@ #include "winbase.h" #include "ole2.h" #include "mshtml.h" +#include "mshtmdid.h" #include "objsafe.h" #include "wine/test.h"
@@ -402,6 +403,35 @@ static void create_xmlhttprequest(IHTMLDocument2 *doc) ok(xhr != NULL, "xhr == NULL\n"); }
+static void test_GetIDsOfNames(IHTMLDocument2 *doc) +{ + DISPID dispids[3]; + HRESULT hres; + BSTR bstr[3]; + + create_xmlhttprequest(doc); + if(!xhr) + return; + + bstr[0] = SysAllocString(L"open"); + bstr[1] = SysAllocString(L"bstrMethod"); + bstr[2] = SysAllocString(L"varAsync"); + dispids[0] = 0; + dispids[1] = 0xdead; + dispids[2] = 0xbeef; + hres = IHTMLXMLHttpRequest_GetIDsOfNames(xhr, &IID_NULL, bstr, 3, 0, dispids); + ok(hres == S_OK, "GetIDsOfNames failed: %08lx\n", hres); + ok(dispids[0] == DISPID_IHTMLXMLHTTPREQUEST_OPEN, "open dispid = %ld\n", dispids[0]); + ok(dispids[1] == 0xdead, "bstrMethod dispid = %ld\n", dispids[1]); + ok(dispids[2] == 0xbeef, "varAsync dispid = %ld\n", dispids[2]); + SysFreeString(bstr[2]); + SysFreeString(bstr[1]); + SysFreeString(bstr[0]); + + IHTMLXMLHttpRequest_Release(xhr); + xhr = NULL; +} + static void test_header(const struct HEADER_TYPE expect[], int num) { int i; @@ -1100,6 +1130,7 @@ START_TEST(xmlhttprequest) content_type = SysAllocString(L"Content-Type"); doc = create_doc_from_url(start_url); if(doc) { + test_GetIDsOfNames(doc); test_sync_xhr(doc, xml_url, expect_response_text); test_sync_xhr(doc, large_page_url, NULL); test_async_xhr(doc, xml_url, expect_response_text);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126148
Your paranoid android.
=== w10pro64_ar (testbot log) ===
WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
=== debian11 (32 bit report) ===
crypt32: cert.c:4191: Test failed: success cert.c:4192: Test failed: got 00000000 cert.c:4193: Test failed: got 00000000
Jacek Caban (@jacek) commented about dlls/mshtml/oleobj.c:
- IEventTarget implementation
- */
+static inline HTMLDocumentObj *impl_from_IEventTarget(IEventTarget *iface) +{
- return CONTAINING_RECORD(iface, HTMLDocumentObj, IEventTarget_iface);
+}
+HTMLDOCUMENTOBJ_IDISPATCH_METHODS(EventTarget)
+static HRESULT WINAPI DocObjEventTarget_addEventListener(IEventTarget *iface, BSTR type, IDispatch *listener,
VARIANT_BOOL capture)
+{
- HTMLDocumentObj *This = impl_from_IEventTarget(iface);
- if(!This->doc_node)
return E_UNEXPECTED;
How doc_node can be NULL?
Please split adding new interfaces to tests into a separated patch.
Jacek Caban (@jacek) commented about dlls/mshtml/tests/events.c:
- IMoniker *mon;
- HRESULT hres;
- DWORD len;
- BSTR bstr;
- wcscpy(url, SZ_HTML_CLIENTSITE_OBJECTPARAM);
- CreateBindCtx(0, &bind);
- IBindCtx_RegisterObjectParam(bind, url, (IUnknown*)&ClientSite);
- notif_doc = doc;
- doc_complete = FALSE;
- memcpy(url, res, sizeof(res));
- len = 6 + GetModuleFileNameW(NULL, url + ARRAY_SIZE(res), ARRAY_SIZE(url) - ARRAY_SIZE(res) - 1);
- url[len++] = '/';
- MultiByteToWideChar(CP_ACP, 0, file, -1, url + len, ARRAY_SIZE(url) - len);
You could just pass file as Unicode string instead.
It was just for consistency with the other places where it's used. Should I drop the check? (I guess, in theory, it could happen that new node fails to allocate while keeping old IEventTarget around, but probably not worth in practice)
BTW I noticed something else, I probably should move the document_mode and window retrieval to navigate() to keep the globals synced as it's expected (in the tests).