mshtml: Implement withCredentials for XMLHttpRequest.
[wine.git] / dlls / mshtml / xmlhttprequest.c
blob8fa91e9960bcd5f1632e645e40512298b0ee1c34
1 /*
2 * Copyright 2015 Zhenbo Li
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32 #include "mshtmdid.h"
33 #include "initguid.h"
34 #include "msxml6.h"
35 #include "objsafe.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
39 #define MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD MSHTML_DISPID_CUSTOM_MIN
41 static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str)
43 char *cstr = heap_strdupWtoU(bstr);
44 if(!cstr)
45 return E_OUTOFMEMORY;
46 nsACString_Init(str, cstr);
47 heap_free(cstr);
48 return S_OK;
51 static HRESULT variant_to_nsastr(VARIANT var, nsAString *ret)
53 switch(V_VT(&var)) {
54 case VT_NULL:
55 case VT_ERROR:
56 case VT_EMPTY:
57 nsAString_Init(ret, NULL);
58 return S_OK;
59 case VT_BSTR:
60 nsAString_InitDepend(ret, V_BSTR(&var));
61 return S_OK;
62 default:
63 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var));
64 return E_INVALIDARG;
68 static HRESULT return_nscstr(nsresult nsres, nsACString *nscstr, BSTR *p)
70 const char *str;
71 int len;
73 if(NS_FAILED(nsres)) {
74 ERR("failed: %08lx\n", nsres);
75 nsACString_Finish(nscstr);
76 return E_FAIL;
79 nsACString_GetData(nscstr, &str);
81 if(*str) {
82 len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
83 *p = SysAllocStringLen(NULL, len - 1);
84 if(!*p) {
85 nsACString_Finish(nscstr);
86 return E_OUTOFMEMORY;
88 MultiByteToWideChar(CP_UTF8, 0, str, -1, *p, len);
89 }else {
90 *p = NULL;
93 nsACString_Finish(nscstr);
94 return S_OK;
97 static const eventid_t events[] = {
98 EVENTID_READYSTATECHANGE,
99 EVENTID_LOAD,
100 EVENTID_LOADSTART,
101 EVENTID_LOADEND,
102 EVENTID_PROGRESS,
103 EVENTID_ABORT,
104 EVENTID_ERROR,
105 EVENTID_TIMEOUT,
108 typedef struct {
109 nsIDOMEventListener nsIDOMEventListener_iface;
110 LONG ref;
111 HTMLXMLHttpRequest *xhr;
112 DWORD events_mask;
113 } XMLHttpReqEventListener;
115 struct HTMLXMLHttpRequest {
116 EventTarget event_target;
117 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
118 IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface;
119 IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface;
120 IProvideClassInfo2 IProvideClassInfo2_iface;
121 LONG ref;
122 nsIXMLHttpRequest *nsxhr;
123 XMLHttpReqEventListener *event_listener;
126 static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
128 nsIDOMEventTarget *event_target;
129 DWORD events_mask, i;
130 nsAString str;
131 nsresult nsres;
133 nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
134 assert(nsres == NS_OK);
136 for(events_mask = event_listener->events_mask, i = 0; events_mask; events_mask >>= 1, i++) {
137 if(!(events_mask & 1))
138 continue;
139 nsAString_InitDepend(&str, get_event_name(events[i]));
140 nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
141 nsAString_Finish(&str);
142 assert(nsres == NS_OK);
145 nsIDOMEventTarget_Release(event_target);
147 event_listener->xhr->event_listener = NULL;
148 event_listener->xhr = NULL;
149 nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
153 static inline XMLHttpReqEventListener *impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
155 return CONTAINING_RECORD(iface, XMLHttpReqEventListener, nsIDOMEventListener_iface);
158 static nsresult NSAPI XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener *iface,
159 nsIIDRef riid, void **result)
161 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
163 if(IsEqualGUID(&IID_nsISupports, riid)) {
164 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
165 *result = &This->nsIDOMEventListener_iface;
166 }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
167 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
168 *result = &This->nsIDOMEventListener_iface;
169 }else {
170 *result = NULL;
171 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
172 return NS_NOINTERFACE;
175 nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
176 return NS_OK;
179 static nsrefcnt NSAPI XMLHttpReqEventListener_AddRef(nsIDOMEventListener *iface)
181 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
182 LONG ref = InterlockedIncrement(&This->ref);
184 TRACE("(%p) ref=%ld\n", This, ref);
186 return ref;
189 static nsrefcnt NSAPI XMLHttpReqEventListener_Release(nsIDOMEventListener *iface)
191 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
192 LONG ref = InterlockedDecrement(&This->ref);
194 TRACE("(%p) ref=%ld\n", This, ref);
196 if(!ref) {
197 assert(!This->xhr);
198 heap_free(This);
201 return ref;
204 static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *nsevent)
206 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
207 DOMEvent *event;
208 HRESULT hres;
210 TRACE("(%p)\n", This);
212 if(!This->xhr)
213 return NS_OK;
215 hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&This->xhr->event_target.dispex), &event);
216 if(SUCCEEDED(hres) ){
217 dispatch_event(&This->xhr->event_target, event);
218 IDOMEvent_Release(&event->IDOMEvent_iface);
220 return NS_OK;
223 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl = {
224 XMLHttpReqEventListener_QueryInterface,
225 XMLHttpReqEventListener_AddRef,
226 XMLHttpReqEventListener_Release,
227 XMLHttpReqEventListener_HandleEvent
230 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
232 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
235 static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *iface, REFIID riid, void **ppv)
237 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
239 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
241 if(IsEqualGUID(&IID_IUnknown, riid)) {
242 *ppv = &This->IHTMLXMLHttpRequest_iface;
243 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
244 *ppv = &This->IHTMLXMLHttpRequest_iface;
245 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
246 *ppv = &This->IHTMLXMLHttpRequest_iface;
247 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest2, riid)) {
248 *ppv = &This->IHTMLXMLHttpRequest2_iface;
249 }else if(IsEqualGUID(&IID_IWineXMLHttpRequestPrivate, riid)) {
250 *ppv = &This->IWineXMLHttpRequestPrivate_iface;
251 }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
252 *ppv = &This->IProvideClassInfo2_iface;
253 }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
254 *ppv = &This->IProvideClassInfo2_iface;
255 }else {
256 return EventTarget_QI(&This->event_target, riid, ppv);
259 IUnknown_AddRef((IUnknown*)*ppv);
260 return S_OK;
263 static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
265 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
266 LONG ref = InterlockedIncrement(&This->ref);
268 TRACE("(%p) ref=%ld\n", This, ref);
270 return ref;
273 static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
275 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
276 LONG ref = InterlockedDecrement(&This->ref);
278 TRACE("(%p) ref=%ld\n", This, ref);
280 if(!ref) {
281 if(This->event_listener)
282 detach_xhr_event_listener(This->event_listener);
283 release_event_target(&This->event_target);
284 release_dispex(&This->event_target.dispex);
285 nsIXMLHttpRequest_Release(This->nsxhr);
286 heap_free(This);
289 return ref;
292 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest *iface, UINT *pctinfo)
294 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
295 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
298 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest *iface, UINT iTInfo,
299 LCID lcid, ITypeInfo **ppTInfo)
301 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
303 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
306 static HRESULT WINAPI HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
307 LCID lcid, DISPID *rgDispId)
309 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
311 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
312 lcid, rgDispId);
315 static HRESULT WINAPI HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
316 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
318 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
320 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
321 pDispParams, pVarResult, pExcepInfo, puArgErr);
324 static HRESULT WINAPI HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest *iface, LONG *p)
326 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
327 UINT16 val;
328 nsresult nsres;
330 TRACE("(%p)->(%p)\n", This, p);
332 if(!p)
333 return E_POINTER;
334 nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &val);
335 if(NS_FAILED(nsres)) {
336 ERR("nsIXMLHttpRequest_GetReadyState failed: %08lx\n", nsres);
337 return E_FAIL;
339 *p = val;
340 return S_OK;
343 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest *iface, VARIANT *p)
345 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
346 FIXME("(%p)->(%p)\n", This, p);
347 return E_NOTIMPL;
350 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *iface, BSTR *p)
352 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
353 nsAString nsstr;
354 nsresult nsres;
356 TRACE("(%p)->(%p)\n", This, p);
358 if(!p)
359 return E_POINTER;
361 nsAString_Init(&nsstr, NULL);
362 nsres = nsIXMLHttpRequest_GetResponseText(This->nsxhr, &nsstr);
363 return return_nsstr(nsres, &nsstr, p);
366 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
368 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
369 IXMLDOMDocument *xmldoc = NULL;
370 BSTR str;
371 HRESULT hres;
372 VARIANT_BOOL vbool;
373 IObjectSafety *safety;
375 TRACE("(%p)->(%p)\n", This, p);
377 hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc);
378 if(FAILED(hres)) {
379 ERR("CoCreateInstance failed: %08lx\n", hres);
380 return hres;
383 hres = IHTMLXMLHttpRequest_get_responseText(iface, &str);
384 if(FAILED(hres)) {
385 IXMLDOMDocument_Release(xmldoc);
386 ERR("get_responseText failed: %08lx\n", hres);
387 return hres;
390 hres = IXMLDOMDocument_loadXML(xmldoc, str, &vbool);
391 SysFreeString(str);
392 if(hres != S_OK || vbool != VARIANT_TRUE)
393 WARN("loadXML failed: %08lx, returning an empty xmldoc\n", hres);
395 hres = IXMLDOMDocument_QueryInterface(xmldoc, &IID_IObjectSafety, (void**)&safety);
396 assert(SUCCEEDED(hres));
397 hres = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
398 INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER,
399 INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER);
400 assert(SUCCEEDED(hres));
401 IObjectSafety_Release(safety);
403 *p = (IDispatch*)xmldoc;
404 return S_OK;
407 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)
409 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
410 UINT32 val;
411 nsresult nsres;
412 TRACE("(%p)->(%p)\n", This, p);
414 if(!p)
415 return E_POINTER;
417 nsres = nsIXMLHttpRequest_GetStatus(This->nsxhr, &val);
418 if(NS_FAILED(nsres)) {
419 ERR("nsIXMLHttpRequest_GetStatus failed: %08lx\n", nsres);
420 return E_FAIL;
422 *p = val;
423 if(val == 0)
424 return E_FAIL; /* WinAPI thinks this is an error */
426 return S_OK;
429 static HRESULT WINAPI HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest *iface, BSTR *p)
431 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
432 nsACString nscstr;
433 nsresult nsres;
434 HRESULT hres;
435 LONG state;
437 TRACE("(%p)->(%p)\n", This, p);
439 if(!p)
440 return E_POINTER;
442 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
443 if(FAILED(hres))
444 return hres;
446 if(state < 2) {
447 *p = NULL;
448 return E_FAIL;
451 nsACString_Init(&nscstr, NULL);
452 nsres = nsIXMLHttpRequest_GetStatusText(This->nsxhr, &nscstr);
453 return return_nscstr(nsres, &nscstr, p);
456 static HRESULT WINAPI HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT v)
458 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
460 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
462 return set_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, &v);
465 static HRESULT WINAPI HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT *p)
467 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
469 TRACE("(%p)->(%p)\n", This, p);
471 return get_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, p);
474 static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
476 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
477 nsresult nsres;
479 TRACE("(%p)->()\n", This);
481 nsres = nsIXMLHttpRequest_SlowAbort(This->nsxhr);
482 if(NS_FAILED(nsres)) {
483 ERR("nsIXMLHttpRequest_SlowAbort failed: %08lx\n", nsres);
484 return E_FAIL;
487 return S_OK;
490 static HRESULT HTMLXMLHttpRequest_open_hook(DispatchEx *dispex, WORD flags,
491 DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
493 /* If only two arguments were given, implicitly set async to false */
494 if((flags & DISPATCH_METHOD) && dp->cArgs == 2 && !dp->cNamedArgs) {
495 VARIANT args[5];
496 DISPPARAMS new_dp = {args, NULL, ARRAY_SIZE(args), 0};
497 V_VT(args) = VT_EMPTY;
498 V_VT(args+1) = VT_EMPTY;
499 V_VT(args+2) = VT_BOOL;
500 V_BOOL(args+2) = VARIANT_TRUE;
501 args[3] = dp->rgvarg[0];
502 args[4] = dp->rgvarg[1];
504 TRACE("implicit async\n");
506 return dispex_call_builtin(dispex, DISPID_IHTMLXMLHTTPREQUEST_OPEN, &new_dp, res, ei, caller);
509 return S_FALSE; /* fallback to default */
512 static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword)
514 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
515 nsACString method, url;
516 nsAString user, password;
517 nsresult nsres;
518 HRESULT hres;
520 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword));
522 if(V_VT(&varAsync) != VT_BOOL) {
523 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
524 hres = VariantChangeTypeEx(&varAsync, &varAsync, lcid, 0, VT_BOOL);
525 if(FAILED(hres)) {
526 WARN("Failed to convert varAsync to BOOL: %#lx\n", hres);
527 return hres;
531 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
532 * synchronous requests on the main thread have been deprecated due to the negative
533 * effects to the user experience.
535 if(!V_BOOL(&varAsync)) {
536 FIXME("Synchronous request is not supported yet\n");
537 return E_FAIL;
540 hres = variant_to_nsastr(varUser, &user);
541 if(FAILED(hres))
542 return hres;
543 hres = variant_to_nsastr(varPassword, &password);
544 if(FAILED(hres)) {
545 nsAString_Finish(&user);
546 return hres;
549 hres = bstr_to_nsacstr(bstrMethod, &method);
550 if(FAILED(hres)) {
551 nsAString_Finish(&user);
552 nsAString_Finish(&password);
553 return hres;
555 hres = bstr_to_nsacstr(bstrUrl, &url);
556 if(FAILED(hres)) {
557 nsAString_Finish(&user);
558 nsAString_Finish(&password);
559 nsACString_Finish(&method);
560 return hres;
563 nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE,
564 &user, &password, 0);
566 nsACString_Finish(&method);
567 nsACString_Finish(&url);
568 nsAString_Finish(&user);
569 nsAString_Finish(&password);
571 if(NS_FAILED(nsres)) {
572 ERR("nsIXMLHttpRequest_Open failed: %08lx\n", nsres);
573 return E_FAIL;
576 return S_OK;
579 static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)
581 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
582 nsIWritableVariant *nsbody = NULL;
583 nsresult nsres = NS_OK;
585 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varBody));
587 switch(V_VT(&varBody)) {
588 case VT_NULL:
589 case VT_EMPTY:
590 case VT_ERROR:
591 break;
592 case VT_BSTR: {
593 nsAString nsstr;
595 nsbody = create_nsvariant();
596 if(!nsbody)
597 return E_OUTOFMEMORY;
599 nsAString_InitDepend(&nsstr, V_BSTR(&varBody));
600 nsres = nsIWritableVariant_SetAsAString(nsbody, &nsstr);
601 nsAString_Finish(&nsstr);
602 break;
604 default:
605 FIXME("unsupported body type %s\n", debugstr_variant(&varBody));
606 return E_NOTIMPL;
609 if(NS_SUCCEEDED(nsres))
610 nsres = nsIXMLHttpRequest_Send(This->nsxhr, (nsIVariant*)nsbody);
611 if(nsbody)
612 nsIWritableVariant_Release(nsbody);
613 if(NS_FAILED(nsres)) {
614 ERR("nsIXMLHttpRequest_Send failed: %08lx\n", nsres);
615 return E_FAIL;
618 return S_OK;
621 static HRESULT WINAPI HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest *iface, BSTR *p)
623 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
624 nsACString nscstr;
625 nsresult nsres;
626 HRESULT hres;
627 LONG state;
629 TRACE("(%p)->(%p)\n", This, p);
631 if(!p)
632 return E_POINTER;
634 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
635 if(FAILED(hres))
636 return hres;
638 if(state < 2) {
639 *p = NULL;
640 return E_FAIL;
643 nsACString_Init(&nscstr, NULL);
644 nsres = nsIXMLHttpRequest_GetAllResponseHeaders(This->nsxhr, &nscstr);
645 return return_nscstr(nsres, &nscstr, p);
648 static HRESULT WINAPI HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR *p)
650 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
651 nsACString header, ret;
652 char *cstr;
653 nsresult nsres;
654 HRESULT hres;
655 LONG state;
656 TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrHeader), p);
658 if(!p)
659 return E_POINTER;
660 if(!bstrHeader)
661 return E_INVALIDARG;
663 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
664 if(FAILED(hres))
665 return hres;
667 if(state < 2) {
668 *p = NULL;
669 return E_FAIL;
672 cstr = heap_strdupWtoU(bstrHeader);
673 nsACString_InitDepend(&header, cstr);
674 nsACString_Init(&ret, NULL);
676 nsres = nsIXMLHttpRequest_GetResponseHeader(This->nsxhr, &header, &ret);
678 nsACString_Finish(&header);
679 heap_free(cstr);
680 return return_nscstr(nsres, &ret, p);
683 static HRESULT WINAPI HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR bstrValue)
685 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
686 char *header_u, *value_u;
687 nsACString header, value;
688 nsresult nsres;
690 TRACE("(%p)->(%s %s)\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
692 header_u = heap_strdupWtoU(bstrHeader);
693 if(bstrHeader && !header_u)
694 return E_OUTOFMEMORY;
696 value_u = heap_strdupWtoU(bstrValue);
697 if(bstrValue && !value_u) {
698 heap_free(header_u);
699 return E_OUTOFMEMORY;
702 nsACString_InitDepend(&header, header_u);
703 nsACString_InitDepend(&value, value_u);
704 nsres = nsIXMLHttpRequest_SetRequestHeader(This->nsxhr, &header, &value);
705 nsACString_Finish(&header);
706 nsACString_Finish(&value);
707 heap_free(header_u);
708 heap_free(value_u);
709 if(NS_FAILED(nsres)) {
710 ERR("SetRequestHeader failed: %08lx\n", nsres);
711 return E_FAIL;
714 return S_OK;
717 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
718 HTMLXMLHttpRequest_QueryInterface,
719 HTMLXMLHttpRequest_AddRef,
720 HTMLXMLHttpRequest_Release,
721 HTMLXMLHttpRequest_GetTypeInfoCount,
722 HTMLXMLHttpRequest_GetTypeInfo,
723 HTMLXMLHttpRequest_GetIDsOfNames,
724 HTMLXMLHttpRequest_Invoke,
725 HTMLXMLHttpRequest_get_readyState,
726 HTMLXMLHttpRequest_get_responseBody,
727 HTMLXMLHttpRequest_get_responseText,
728 HTMLXMLHttpRequest_get_responseXML,
729 HTMLXMLHttpRequest_get_status,
730 HTMLXMLHttpRequest_get_statusText,
731 HTMLXMLHttpRequest_put_onreadystatechange,
732 HTMLXMLHttpRequest_get_onreadystatechange,
733 HTMLXMLHttpRequest_abort,
734 HTMLXMLHttpRequest_open,
735 HTMLXMLHttpRequest_send,
736 HTMLXMLHttpRequest_getAllResponseHeaders,
737 HTMLXMLHttpRequest_getResponseHeader,
738 HTMLXMLHttpRequest_setRequestHeader
741 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest2(IHTMLXMLHttpRequest2 *iface)
743 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest2_iface);
746 static HRESULT WINAPI HTMLXMLHttpRequest2_QueryInterface(IHTMLXMLHttpRequest2 *iface, REFIID riid, void **ppv)
748 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
749 return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
752 static ULONG WINAPI HTMLXMLHttpRequest2_AddRef(IHTMLXMLHttpRequest2 *iface)
754 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
755 return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
758 static ULONG WINAPI HTMLXMLHttpRequest2_Release(IHTMLXMLHttpRequest2 *iface)
760 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
761 return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
764 static HRESULT WINAPI HTMLXMLHttpRequest2_GetTypeInfoCount(IHTMLXMLHttpRequest2 *iface, UINT *pctinfo)
766 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
767 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
770 static HRESULT WINAPI HTMLXMLHttpRequest2_GetTypeInfo(IHTMLXMLHttpRequest2 *iface, UINT iTInfo,
771 LCID lcid, ITypeInfo **ppTInfo)
773 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
774 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
777 static HRESULT WINAPI HTMLXMLHttpRequest2_GetIDsOfNames(IHTMLXMLHttpRequest2 *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
778 LCID lcid, DISPID *rgDispId)
780 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
781 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
782 lcid, rgDispId);
785 static HRESULT WINAPI HTMLXMLHttpRequest2_Invoke(IHTMLXMLHttpRequest2 *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
786 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
788 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
789 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
790 pDispParams, pVarResult, pExcepInfo, puArgErr);
793 static HRESULT WINAPI HTMLXMLHttpRequest2_put_timeout(IHTMLXMLHttpRequest2 *iface, LONG v)
795 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
797 TRACE("(%p)->(%ld)\n", This, v);
799 if(v < 0)
800 return E_INVALIDARG;
801 return map_nsresult(nsIXMLHttpRequest_SetTimeout(This->nsxhr, v));
804 static HRESULT WINAPI HTMLXMLHttpRequest2_get_timeout(IHTMLXMLHttpRequest2 *iface, LONG *p)
806 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
807 nsresult nsres;
808 UINT32 timeout;
810 TRACE("(%p)->(%p)\n", This, p);
812 if(!p)
813 return E_POINTER;
815 nsres = nsIXMLHttpRequest_GetTimeout(This->nsxhr, &timeout);
816 *p = timeout;
817 return map_nsresult(nsres);
820 static HRESULT WINAPI HTMLXMLHttpRequest2_put_ontimeout(IHTMLXMLHttpRequest2 *iface, VARIANT v)
822 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
824 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
826 return set_event_handler(&This->event_target, EVENTID_TIMEOUT, &v);
829 static HRESULT WINAPI HTMLXMLHttpRequest2_get_ontimeout(IHTMLXMLHttpRequest2 *iface, VARIANT *p)
831 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
833 TRACE("(%p)->(%p)\n", This, p);
835 return get_event_handler(&This->event_target, EVENTID_TIMEOUT, p);
838 static const IHTMLXMLHttpRequest2Vtbl HTMLXMLHttpRequest2Vtbl = {
839 HTMLXMLHttpRequest2_QueryInterface,
840 HTMLXMLHttpRequest2_AddRef,
841 HTMLXMLHttpRequest2_Release,
842 HTMLXMLHttpRequest2_GetTypeInfoCount,
843 HTMLXMLHttpRequest2_GetTypeInfo,
844 HTMLXMLHttpRequest2_GetIDsOfNames,
845 HTMLXMLHttpRequest2_Invoke,
846 HTMLXMLHttpRequest2_put_timeout,
847 HTMLXMLHttpRequest2_get_timeout,
848 HTMLXMLHttpRequest2_put_ontimeout,
849 HTMLXMLHttpRequest2_get_ontimeout
852 static inline HTMLXMLHttpRequest *impl_from_IWineXMLHttpRequestPrivate(IWineXMLHttpRequestPrivate *iface)
854 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IWineXMLHttpRequestPrivate_iface);
857 static HRESULT WINAPI HTMLXMLHttpRequest_private_QueryInterface(IWineXMLHttpRequestPrivate *iface, REFIID riid, void **ppv)
859 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
860 return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
863 static ULONG WINAPI HTMLXMLHttpRequest_private_AddRef(IWineXMLHttpRequestPrivate *iface)
865 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
866 return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
869 static ULONG WINAPI HTMLXMLHttpRequest_private_Release(IWineXMLHttpRequestPrivate *iface)
871 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
872 return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
875 static HRESULT WINAPI HTMLXMLHttpRequest_private_GetTypeInfoCount(IWineXMLHttpRequestPrivate *iface, UINT *pctinfo)
877 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
878 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
881 static HRESULT WINAPI HTMLXMLHttpRequest_private_GetTypeInfo(IWineXMLHttpRequestPrivate *iface, UINT iTInfo,
882 LCID lcid, ITypeInfo **ppTInfo)
884 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
885 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
888 static HRESULT WINAPI HTMLXMLHttpRequest_private_GetIDsOfNames(IWineXMLHttpRequestPrivate *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
889 LCID lcid, DISPID *rgDispId)
891 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
892 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
893 lcid, rgDispId);
896 static HRESULT WINAPI HTMLXMLHttpRequest_private_Invoke(IWineXMLHttpRequestPrivate *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
897 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
899 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
900 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
901 pDispParams, pVarResult, pExcepInfo, puArgErr);
904 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
906 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
908 FIXME("(%p)->(%p)\n", This, p);
910 return E_NOTIMPL;
913 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_responseType(IWineXMLHttpRequestPrivate *iface, BSTR v)
915 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
917 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
919 return E_NOTIMPL;
922 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_responseType(IWineXMLHttpRequestPrivate *iface, BSTR *p)
924 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
926 FIXME("(%p)->(%p)\n", This, p);
928 return E_NOTIMPL;
931 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_upload(IWineXMLHttpRequestPrivate *iface, IDispatch **p)
933 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
935 FIXME("(%p)->(%p)\n", This, p);
937 return E_NOTIMPL;
940 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_withCredentials(IWineXMLHttpRequestPrivate *iface, VARIANT_BOOL v)
942 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
944 TRACE("(%p)->(%x)\n", This, v);
946 return map_nsresult(nsIXMLHttpRequest_SetWithCredentials(This->nsxhr, !!v));
949 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_withCredentials(IWineXMLHttpRequestPrivate *iface, VARIANT_BOOL *p)
951 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
952 nsresult nsres;
953 cpp_bool b;
955 TRACE("(%p)->(%p)\n", This, p);
957 nsres = nsIXMLHttpRequest_GetWithCredentials(This->nsxhr, &b);
958 if(NS_FAILED(nsres))
959 return map_nsresult(nsres);
960 *p = b ? VARIANT_TRUE : VARIANT_FALSE;
961 return S_OK;
964 static HRESULT WINAPI HTMLXMLHttpRequest_private_overrideMimeType(IWineXMLHttpRequestPrivate *iface, BSTR mimeType)
966 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
968 FIXME("(%p)->(%s)\n", This, debugstr_w(mimeType));
970 return E_NOTIMPL;
973 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onerror(IWineXMLHttpRequestPrivate *iface, VARIANT v)
975 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
977 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
979 return set_event_handler(&This->event_target, EVENTID_ERROR, &v);
982 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onerror(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
984 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
986 TRACE("(%p)->(%p)\n", This, p);
988 return get_event_handler(&This->event_target, EVENTID_ERROR, p);
991 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onabort(IWineXMLHttpRequestPrivate *iface, VARIANT v)
993 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
995 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
997 return set_event_handler(&This->event_target, EVENTID_ABORT, &v);
1000 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onabort(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1002 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1004 TRACE("(%p)->(%p)\n", This, p);
1006 return get_event_handler(&This->event_target, EVENTID_ABORT, p);
1009 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onprogress(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1011 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1013 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1015 return set_event_handler(&This->event_target, EVENTID_PROGRESS, &v);
1018 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onprogress(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1020 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1022 TRACE("(%p)->(%p)\n", This, p);
1024 return get_event_handler(&This->event_target, EVENTID_PROGRESS, p);
1027 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onloadstart(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1029 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1031 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1033 return set_event_handler(&This->event_target, EVENTID_LOADSTART, &v);
1036 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onloadstart(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1038 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1040 TRACE("(%p)->(%p)\n", This, p);
1042 return get_event_handler(&This->event_target, EVENTID_LOADSTART, p);
1045 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onloadend(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1047 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1049 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1051 return set_event_handler(&This->event_target, EVENTID_LOADEND, &v);
1054 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onloadend(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1056 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1058 TRACE("(%p)->(%p)\n", This, p);
1060 return get_event_handler(&This->event_target, EVENTID_LOADEND, p);
1063 static const IWineXMLHttpRequestPrivateVtbl WineXMLHttpRequestPrivateVtbl = {
1064 HTMLXMLHttpRequest_private_QueryInterface,
1065 HTMLXMLHttpRequest_private_AddRef,
1066 HTMLXMLHttpRequest_private_Release,
1067 HTMLXMLHttpRequest_private_GetTypeInfoCount,
1068 HTMLXMLHttpRequest_private_GetTypeInfo,
1069 HTMLXMLHttpRequest_private_GetIDsOfNames,
1070 HTMLXMLHttpRequest_private_Invoke,
1071 HTMLXMLHttpRequest_private_get_response,
1072 HTMLXMLHttpRequest_private_put_responseType,
1073 HTMLXMLHttpRequest_private_get_responseType,
1074 HTMLXMLHttpRequest_private_get_upload,
1075 HTMLXMLHttpRequest_private_put_withCredentials,
1076 HTMLXMLHttpRequest_private_get_withCredentials,
1077 HTMLXMLHttpRequest_private_overrideMimeType,
1078 HTMLXMLHttpRequest_private_put_onerror,
1079 HTMLXMLHttpRequest_private_get_onerror,
1080 HTMLXMLHttpRequest_private_put_onabort,
1081 HTMLXMLHttpRequest_private_get_onabort,
1082 HTMLXMLHttpRequest_private_put_onprogress,
1083 HTMLXMLHttpRequest_private_get_onprogress,
1084 HTMLXMLHttpRequest_private_put_onloadstart,
1085 HTMLXMLHttpRequest_private_get_onloadstart,
1086 HTMLXMLHttpRequest_private_put_onloadend,
1087 HTMLXMLHttpRequest_private_get_onloadend
1090 static inline HTMLXMLHttpRequest *impl_from_IProvideClassInfo2(IProvideClassInfo2 *iface)
1092 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IProvideClassInfo2_iface);
1095 static HRESULT WINAPI ProvideClassInfo_QueryInterface(IProvideClassInfo2 *iface, REFIID riid, void **ppv)
1097 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1098 return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
1101 static ULONG WINAPI ProvideClassInfo_AddRef(IProvideClassInfo2 *iface)
1103 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1104 return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
1107 static ULONG WINAPI ProvideClassInfo_Release(IProvideClassInfo2 *iface)
1109 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1110 return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
1113 static HRESULT WINAPI ProvideClassInfo_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI)
1115 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1116 TRACE("(%p)->(%p)\n", This, ppTI);
1117 return get_class_typeinfo(&CLSID_HTMLXMLHttpRequest, ppTI);
1120 static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID)
1122 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1123 FIXME("(%p)->(%lu %p)\n", This, dwGuidKind, pGUID);
1124 return E_NOTIMPL;
1127 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl = {
1128 ProvideClassInfo_QueryInterface,
1129 ProvideClassInfo_AddRef,
1130 ProvideClassInfo_Release,
1131 ProvideClassInfo_GetClassInfo,
1132 ProvideClassInfo2_GetGUID,
1135 static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
1137 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
1140 static HRESULT HTMLXMLHttpRequest_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
1142 /* onload event handler property is supported, but not exposed by any interface. We implement as a custom property. */
1143 if(!wcscmp(L"onload", name)) {
1144 *dispid = MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD;
1145 return S_OK;
1148 return DISP_E_UNKNOWNNAME;
1151 static HRESULT HTMLXMLHttpRequest_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
1152 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1154 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
1156 if(id == MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD) {
1157 switch(flags) {
1158 case DISPATCH_PROPERTYGET:
1159 TRACE("(%p) get onload\n", This);
1160 return get_event_handler(&This->event_target, EVENTID_LOAD, res);
1162 case DISPATCH_PROPERTYPUT:
1163 if(params->cArgs != 1 || (params->cNamedArgs == 1 && *params->rgdispidNamedArgs != DISPID_PROPERTYPUT)
1164 || params->cNamedArgs > 1) {
1165 FIXME("invalid args\n");
1166 return E_INVALIDARG;
1169 TRACE("(%p)->(%p) set onload\n", This, params->rgvarg);
1170 return set_event_handler(&This->event_target, EVENTID_LOAD, params->rgvarg);
1172 default:
1173 FIXME("Unimplemented flags %x\n", flags);
1174 return E_NOTIMPL;
1178 return DISP_E_UNKNOWNNAME;
1181 static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex)
1183 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
1184 return (nsISupports*)This->nsxhr;
1187 static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid)
1189 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
1190 nsIDOMEventTarget *nstarget;
1191 nsAString type_str;
1192 const WCHAR *name;
1193 nsresult nsres;
1194 unsigned i;
1196 TRACE("(%p)\n", This);
1198 for(i = 0; i < ARRAY_SIZE(events); i++)
1199 if(eid == events[i])
1200 break;
1201 if(i >= ARRAY_SIZE(events))
1202 return;
1204 if(!This->event_listener) {
1205 This->event_listener = heap_alloc(sizeof(*This->event_listener));
1206 if(!This->event_listener)
1207 return;
1209 This->event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
1210 This->event_listener->ref = 1;
1211 This->event_listener->xhr = This;
1212 This->event_listener->events_mask = 0;
1215 nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
1216 assert(nsres == NS_OK);
1218 name = get_event_name(events[i]);
1219 nsAString_InitDepend(&type_str, name);
1220 nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
1221 nsAString_Finish(&type_str);
1222 if(NS_FAILED(nsres))
1223 ERR("AddEventListener(%s) failed: %08lx\n", debugstr_w(name), nsres);
1225 nsIDOMEventTarget_Release(nstarget);
1227 This->event_listener->events_mask |= 1 << i;
1230 static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode)
1232 static const dispex_hook_t xhr_hooks[] = {
1233 {DISPID_IHTMLXMLHTTPREQUEST_OPEN, HTMLXMLHttpRequest_open_hook},
1234 {DISPID_UNKNOWN}
1236 static const dispex_hook_t private_ie10_hooks[] = {
1237 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE},
1238 {DISPID_UNKNOWN}
1241 EventTarget_init_dispex_info(info, compat_mode);
1242 dispex_info_add_interface(info, IHTMLXMLHttpRequest_tid, compat_mode >= COMPAT_MODE_IE10 ? xhr_hooks : NULL);
1243 if(compat_mode >= COMPAT_MODE_IE10)
1244 dispex_info_add_interface(info, IWineXMLHttpRequestPrivate_tid, compat_mode == COMPAT_MODE_IE10 ? private_ie10_hooks : NULL);
1247 static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = {
1249 NULL,
1250 HTMLXMLHttpRequest_get_dispid,
1251 HTMLXMLHttpRequest_invoke
1253 HTMLXMLHttpRequest_get_gecko_target,
1254 HTMLXMLHttpRequest_bind_event
1257 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
1258 IHTMLXMLHttpRequest2_tid,
1261 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
1262 L"XMLHttpRequest",
1263 &HTMLXMLHttpRequest_event_target_vtbl.dispex_vtbl,
1264 DispHTMLXMLHttpRequest_tid,
1265 HTMLXMLHttpRequest_iface_tids,
1266 HTMLXMLHttpRequest_init_dispex_info
1270 /* IHTMLXMLHttpRequestFactory */
1271 static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface)
1273 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface);
1276 static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory *iface, REFIID riid, void **ppv)
1278 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1280 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1282 if(IsEqualGUID(&IID_IUnknown, riid)) {
1283 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
1284 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1285 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
1286 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) {
1287 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
1288 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
1289 return *ppv ? S_OK : E_NOINTERFACE;
1290 }else {
1291 *ppv = NULL;
1292 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1293 return E_NOINTERFACE;
1296 IUnknown_AddRef((IUnknown*)*ppv);
1297 return S_OK;
1300 static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface)
1302 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1303 LONG ref = InterlockedIncrement(&This->ref);
1305 TRACE("(%p) ref=%ld\n", This, ref);
1307 return ref;
1310 static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface)
1312 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1313 LONG ref = InterlockedDecrement(&This->ref);
1315 TRACE("(%p) ref=%ld\n", This, ref);
1317 if(!ref) {
1318 release_dispex(&This->dispex);
1319 heap_free(This);
1322 return ref;
1325 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory *iface, UINT *pctinfo)
1327 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1328 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
1331 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory *iface, UINT iTInfo,
1332 LCID lcid, ITypeInfo **ppTInfo)
1334 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1336 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1339 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1340 LCID lcid, DISPID *rgDispId)
1342 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1344 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
1345 lcid, rgDispId);
1348 static HRESULT WINAPI HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1349 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1351 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1353 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1354 pDispParams, pVarResult, pExcepInfo, puArgErr);
1357 static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p)
1359 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1360 HTMLXMLHttpRequest *ret;
1361 nsIXMLHttpRequest *nsxhr;
1363 TRACE("(%p)->(%p)\n", This, p);
1365 nsxhr = create_nsxhr(This->window->base.outer_window->nswindow);
1366 if(!nsxhr)
1367 return E_FAIL;
1369 ret = heap_alloc_zero(sizeof(*ret));
1370 if(!ret) {
1371 nsIXMLHttpRequest_Release(nsxhr);
1372 return E_OUTOFMEMORY;
1374 ret->nsxhr = nsxhr;
1376 ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
1377 ret->IHTMLXMLHttpRequest2_iface.lpVtbl = &HTMLXMLHttpRequest2Vtbl;
1378 ret->IWineXMLHttpRequestPrivate_iface.lpVtbl = &WineXMLHttpRequestPrivateVtbl;
1379 ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl;
1380 EventTarget_Init(&ret->event_target, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
1381 &HTMLXMLHttpRequest_dispex, This->window->doc->document_mode);
1382 ret->ref = 1;
1384 *p = &ret->IHTMLXMLHttpRequest_iface;
1385 return S_OK;
1388 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = {
1389 HTMLXMLHttpRequestFactory_QueryInterface,
1390 HTMLXMLHttpRequestFactory_AddRef,
1391 HTMLXMLHttpRequestFactory_Release,
1392 HTMLXMLHttpRequestFactory_GetTypeInfoCount,
1393 HTMLXMLHttpRequestFactory_GetTypeInfo,
1394 HTMLXMLHttpRequestFactory_GetIDsOfNames,
1395 HTMLXMLHttpRequestFactory_Invoke,
1396 HTMLXMLHttpRequestFactory_create
1399 static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *iface)
1401 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex);
1404 static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WORD flags, DISPPARAMS *params,
1405 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1407 HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(iface);
1408 IHTMLXMLHttpRequest *xhr;
1409 HRESULT hres;
1411 TRACE("\n");
1413 if(flags != DISPATCH_CONSTRUCT) {
1414 FIXME("flags %x not supported\n", flags);
1415 return E_NOTIMPL;
1418 hres = IHTMLXMLHttpRequestFactory_create(&This->IHTMLXMLHttpRequestFactory_iface, &xhr);
1419 if(FAILED(hres))
1420 return hres;
1422 V_VT(res) = VT_DISPATCH;
1423 V_DISPATCH(res) = (IDispatch*)xhr;
1424 return S_OK;
1427 static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = {
1428 HTMLXMLHttpRequestFactory_value
1431 static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = {
1432 IHTMLXMLHttpRequestFactory_tid,
1435 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
1436 L"Function",
1437 &HTMLXMLHttpRequestFactory_dispex_vtbl,
1438 IHTMLXMLHttpRequestFactory_tid,
1439 HTMLXMLHttpRequestFactory_iface_tids
1442 HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr)
1444 HTMLXMLHttpRequestFactory *ret;
1446 ret = heap_alloc(sizeof(*ret));
1447 if(!ret)
1448 return E_OUTOFMEMORY;
1450 ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl;
1451 ret->ref = 1;
1452 ret->window = window;
1454 init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface,
1455 &HTMLXMLHttpRequestFactory_dispex, dispex_compat_mode(&window->event_target.dispex));
1457 *ret_ptr = ret;
1458 return S_OK;