include: Be consistent in naming regarding MSF's block.
[wine.git] / dlls / mshtml / xmlhttprequest.c
blobb4269bbe8d18d588b3e2507b747d65930f8e1aee
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 static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str)
41 char *cstr = strdupWtoU(bstr);
42 if(!cstr)
43 return E_OUTOFMEMORY;
44 nsACString_Init(str, cstr);
45 free(cstr);
46 return S_OK;
49 static HRESULT variant_to_nsastr(VARIANT var, nsAString *ret)
51 switch(V_VT(&var)) {
52 case VT_NULL:
53 case VT_ERROR:
54 case VT_EMPTY:
55 nsAString_Init(ret, NULL);
56 return S_OK;
57 case VT_BSTR:
58 nsAString_InitDepend(ret, V_BSTR(&var));
59 return S_OK;
60 default:
61 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var));
62 return E_INVALIDARG;
66 static HRESULT return_nscstr(nsresult nsres, nsACString *nscstr, BSTR *p)
68 const char *str;
69 int len;
71 if(NS_FAILED(nsres)) {
72 ERR("failed: %08lx\n", nsres);
73 nsACString_Finish(nscstr);
74 return E_FAIL;
77 nsACString_GetData(nscstr, &str);
79 if(*str) {
80 len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
81 *p = SysAllocStringLen(NULL, len - 1);
82 if(!*p) {
83 nsACString_Finish(nscstr);
84 return E_OUTOFMEMORY;
86 MultiByteToWideChar(CP_UTF8, 0, str, -1, *p, len);
87 }else {
88 *p = NULL;
91 nsACString_Finish(nscstr);
92 return S_OK;
95 static const eventid_t events[] = {
96 EVENTID_READYSTATECHANGE,
97 EVENTID_LOAD,
98 EVENTID_LOADSTART,
99 EVENTID_LOADEND,
100 EVENTID_PROGRESS,
101 EVENTID_ABORT,
102 EVENTID_ERROR,
103 EVENTID_TIMEOUT,
106 typedef enum {
107 response_type_empty,
108 response_type_text,
109 response_type_doc,
110 response_type_arraybuf,
111 response_type_blob,
112 response_type_stream
113 } response_type_t;
115 static const struct {
116 const WCHAR *str;
117 const WCHAR *nsxhr_str;
118 } response_type_desc[] = {
119 [response_type_empty] = { L"", L"" },
120 [response_type_text] = { L"text", L"" },
121 [response_type_doc] = { L"document", L"" }, /* FIXME */
122 [response_type_arraybuf] = { L"arraybuffer", L"arraybuffer" },
123 [response_type_blob] = { L"blob", L"arraybuffer" },
124 [response_type_stream] = { L"ms-stream", L"arraybuffer" } /* FIXME */
127 typedef struct {
128 nsIDOMEventListener nsIDOMEventListener_iface;
129 LONG ref;
130 HTMLXMLHttpRequest *xhr;
131 DWORD events_mask;
132 } XMLHttpReqEventListener;
134 struct HTMLXMLHttpRequest {
135 EventTarget event_target;
136 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
137 IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface;
138 IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface;
139 IProvideClassInfo2 IProvideClassInfo2_iface;
140 LONG ref;
141 response_type_t response_type;
142 nsIXMLHttpRequest *nsxhr;
143 XMLHttpReqEventListener *event_listener;
146 static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
148 nsIDOMEventTarget *event_target;
149 DWORD events_mask, i;
150 nsAString str;
151 nsresult nsres;
153 nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
154 assert(nsres == NS_OK);
156 for(events_mask = event_listener->events_mask, i = 0; events_mask; events_mask >>= 1, i++) {
157 if(!(events_mask & 1))
158 continue;
159 nsAString_InitDepend(&str, get_event_name(events[i]));
160 nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
161 nsAString_Finish(&str);
162 assert(nsres == NS_OK);
165 nsIDOMEventTarget_Release(event_target);
167 event_listener->xhr->event_listener = NULL;
168 event_listener->xhr = NULL;
169 nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
173 static inline XMLHttpReqEventListener *impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
175 return CONTAINING_RECORD(iface, XMLHttpReqEventListener, nsIDOMEventListener_iface);
178 static nsresult NSAPI XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener *iface,
179 nsIIDRef riid, void **result)
181 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
183 if(IsEqualGUID(&IID_nsISupports, riid)) {
184 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
185 *result = &This->nsIDOMEventListener_iface;
186 }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
187 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
188 *result = &This->nsIDOMEventListener_iface;
189 }else {
190 *result = NULL;
191 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
192 return NS_NOINTERFACE;
195 nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
196 return NS_OK;
199 static nsrefcnt NSAPI XMLHttpReqEventListener_AddRef(nsIDOMEventListener *iface)
201 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
202 LONG ref = InterlockedIncrement(&This->ref);
204 TRACE("(%p) ref=%ld\n", This, ref);
206 return ref;
209 static nsrefcnt NSAPI XMLHttpReqEventListener_Release(nsIDOMEventListener *iface)
211 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
212 LONG ref = InterlockedDecrement(&This->ref);
214 TRACE("(%p) ref=%ld\n", This, ref);
216 if(!ref) {
217 assert(!This->xhr);
218 free(This);
221 return ref;
224 static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *nsevent)
226 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
227 DOMEvent *event;
228 HRESULT hres;
230 TRACE("(%p)\n", This);
232 if(!This->xhr)
233 return NS_OK;
235 hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&This->xhr->event_target.dispex), &event);
236 if(SUCCEEDED(hres) ){
237 dispatch_event(&This->xhr->event_target, event);
238 IDOMEvent_Release(&event->IDOMEvent_iface);
240 return NS_OK;
243 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl = {
244 XMLHttpReqEventListener_QueryInterface,
245 XMLHttpReqEventListener_AddRef,
246 XMLHttpReqEventListener_Release,
247 XMLHttpReqEventListener_HandleEvent
250 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
252 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
255 static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *iface, REFIID riid, void **ppv)
257 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
259 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
261 if(IsEqualGUID(&IID_IUnknown, riid)) {
262 *ppv = &This->IHTMLXMLHttpRequest_iface;
263 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
264 *ppv = &This->IHTMLXMLHttpRequest_iface;
265 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
266 *ppv = &This->IHTMLXMLHttpRequest_iface;
267 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest2, riid)) {
268 *ppv = &This->IHTMLXMLHttpRequest2_iface;
269 }else if(IsEqualGUID(&IID_IWineXMLHttpRequestPrivate, riid)) {
270 *ppv = &This->IWineXMLHttpRequestPrivate_iface;
271 }else if(IsEqualGUID(&IID_IProvideClassInfo, riid)) {
272 *ppv = &This->IProvideClassInfo2_iface;
273 }else if(IsEqualGUID(&IID_IProvideClassInfo2, riid)) {
274 *ppv = &This->IProvideClassInfo2_iface;
275 }else {
276 return EventTarget_QI(&This->event_target, riid, ppv);
279 IUnknown_AddRef((IUnknown*)*ppv);
280 return S_OK;
283 static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
285 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
286 LONG ref = InterlockedIncrement(&This->ref);
288 TRACE("(%p) ref=%ld\n", This, ref);
290 return ref;
293 static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
295 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
296 LONG ref = InterlockedDecrement(&This->ref);
298 TRACE("(%p) ref=%ld\n", This, ref);
300 if(!ref) {
301 if(This->event_listener)
302 detach_xhr_event_listener(This->event_listener);
303 release_event_target(&This->event_target);
304 release_dispex(&This->event_target.dispex);
305 nsIXMLHttpRequest_Release(This->nsxhr);
306 free(This);
309 return ref;
312 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest *iface, UINT *pctinfo)
314 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
315 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
318 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest *iface, UINT iTInfo,
319 LCID lcid, ITypeInfo **ppTInfo)
321 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
323 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
326 static HRESULT WINAPI HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
327 LCID lcid, DISPID *rgDispId)
329 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
331 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
332 lcid, rgDispId);
335 static HRESULT WINAPI HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
336 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
338 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
340 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
341 pDispParams, pVarResult, pExcepInfo, puArgErr);
344 static HRESULT WINAPI HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest *iface, LONG *p)
346 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
347 UINT16 val;
348 nsresult nsres;
350 TRACE("(%p)->(%p)\n", This, p);
352 if(!p)
353 return E_POINTER;
354 nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &val);
355 if(NS_FAILED(nsres)) {
356 ERR("nsIXMLHttpRequest_GetReadyState failed: %08lx\n", nsres);
357 return E_FAIL;
359 *p = val;
360 return S_OK;
363 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest *iface, VARIANT *p)
365 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
366 FIXME("(%p)->(%p)\n", This, p);
367 return E_NOTIMPL;
370 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *iface, BSTR *p)
372 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
373 nsAString nsstr;
374 nsresult nsres;
376 TRACE("(%p)->(%p)\n", This, p);
378 if(!p)
379 return E_POINTER;
381 nsAString_Init(&nsstr, NULL);
382 nsres = nsIXMLHttpRequest_GetResponseText(This->nsxhr, &nsstr);
383 return return_nsstr(nsres, &nsstr, p);
386 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
388 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
389 IXMLDOMDocument *xmldoc = NULL;
390 BSTR str;
391 HRESULT hres;
392 VARIANT_BOOL vbool;
393 IObjectSafety *safety;
395 TRACE("(%p)->(%p)\n", This, p);
397 if(dispex_compat_mode(&This->event_target.dispex) >= COMPAT_MODE_IE10) {
398 nsIDOMDocument *nsdoc;
399 nsresult nsres;
401 nsres = nsIXMLHttpRequest_GetResponseXML(This->nsxhr, &nsdoc);
402 if(NS_FAILED(nsres))
403 return map_nsresult(nsres);
404 if(!nsdoc) {
405 *p = NULL;
406 return S_OK;
408 nsIDOMDocument_Release(nsdoc);
411 hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc);
412 if(FAILED(hres)) {
413 ERR("CoCreateInstance failed: %08lx\n", hres);
414 return hres;
417 hres = IHTMLXMLHttpRequest_get_responseText(iface, &str);
418 if(FAILED(hres)) {
419 IXMLDOMDocument_Release(xmldoc);
420 ERR("get_responseText failed: %08lx\n", hres);
421 return hres;
424 hres = IXMLDOMDocument_loadXML(xmldoc, str, &vbool);
425 SysFreeString(str);
426 if(hres != S_OK || vbool != VARIANT_TRUE)
427 WARN("loadXML failed: %08lx, returning an empty xmldoc\n", hres);
429 hres = IXMLDOMDocument_QueryInterface(xmldoc, &IID_IObjectSafety, (void**)&safety);
430 assert(SUCCEEDED(hres));
431 hres = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
432 INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER,
433 INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER);
434 assert(SUCCEEDED(hres));
435 IObjectSafety_Release(safety);
437 *p = (IDispatch*)xmldoc;
438 return S_OK;
441 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)
443 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
444 UINT32 val;
445 nsresult nsres;
446 TRACE("(%p)->(%p)\n", This, p);
448 if(!p)
449 return E_POINTER;
451 nsres = nsIXMLHttpRequest_GetStatus(This->nsxhr, &val);
452 if(NS_FAILED(nsres)) {
453 ERR("nsIXMLHttpRequest_GetStatus failed: %08lx\n", nsres);
454 return E_FAIL;
456 *p = val;
457 if(val == 0)
458 return E_FAIL; /* WinAPI thinks this is an error */
460 return S_OK;
463 static HRESULT WINAPI HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest *iface, BSTR *p)
465 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
466 nsACString nscstr;
467 nsresult nsres;
468 HRESULT hres;
469 LONG state;
471 TRACE("(%p)->(%p)\n", This, p);
473 if(!p)
474 return E_POINTER;
476 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
477 if(FAILED(hres))
478 return hres;
480 if(state < 2) {
481 *p = NULL;
482 return E_FAIL;
485 nsACString_Init(&nscstr, NULL);
486 nsres = nsIXMLHttpRequest_GetStatusText(This->nsxhr, &nscstr);
487 return return_nscstr(nsres, &nscstr, p);
490 static HRESULT WINAPI HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT v)
492 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
494 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
496 return set_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, &v);
499 static HRESULT WINAPI HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT *p)
501 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
503 TRACE("(%p)->(%p)\n", This, p);
505 return get_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, p);
508 static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
510 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
511 nsresult nsres;
513 TRACE("(%p)->()\n", This);
515 nsres = nsIXMLHttpRequest_SlowAbort(This->nsxhr);
516 if(NS_FAILED(nsres)) {
517 ERR("nsIXMLHttpRequest_SlowAbort failed: %08lx\n", nsres);
518 return E_FAIL;
521 return S_OK;
524 static HRESULT HTMLXMLHttpRequest_open_hook(DispatchEx *dispex, WORD flags,
525 DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
527 /* If only two arguments were given, implicitly set async to false */
528 if((flags & DISPATCH_METHOD) && dp->cArgs == 2 && !dp->cNamedArgs) {
529 VARIANT args[5];
530 DISPPARAMS new_dp = {args, NULL, ARRAY_SIZE(args), 0};
531 V_VT(args) = VT_EMPTY;
532 V_VT(args+1) = VT_EMPTY;
533 V_VT(args+2) = VT_BOOL;
534 V_BOOL(args+2) = VARIANT_TRUE;
535 args[3] = dp->rgvarg[0];
536 args[4] = dp->rgvarg[1];
538 TRACE("implicit async\n");
540 return dispex_call_builtin(dispex, DISPID_IHTMLXMLHTTPREQUEST_OPEN, &new_dp, res, ei, caller);
543 return S_FALSE; /* fallback to default */
546 static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword)
548 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
549 nsACString method, url;
550 nsAString user, password;
551 nsresult nsres;
552 HRESULT hres;
554 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword));
556 if(V_VT(&varAsync) != VT_BOOL) {
557 LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
558 hres = VariantChangeTypeEx(&varAsync, &varAsync, lcid, 0, VT_BOOL);
559 if(FAILED(hres)) {
560 WARN("Failed to convert varAsync to BOOL: %#lx\n", hres);
561 return hres;
565 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
566 * synchronous requests on the main thread have been deprecated due to the negative
567 * effects to the user experience.
569 if(!V_BOOL(&varAsync)) {
570 FIXME("Synchronous request is not supported yet\n");
571 return E_FAIL;
574 hres = variant_to_nsastr(varUser, &user);
575 if(FAILED(hres))
576 return hres;
577 hres = variant_to_nsastr(varPassword, &password);
578 if(FAILED(hres)) {
579 nsAString_Finish(&user);
580 return hres;
583 hres = bstr_to_nsacstr(bstrMethod, &method);
584 if(FAILED(hres)) {
585 nsAString_Finish(&user);
586 nsAString_Finish(&password);
587 return hres;
589 hres = bstr_to_nsacstr(bstrUrl, &url);
590 if(FAILED(hres)) {
591 nsAString_Finish(&user);
592 nsAString_Finish(&password);
593 nsACString_Finish(&method);
594 return hres;
597 nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE,
598 &user, &password, 0);
600 nsACString_Finish(&method);
601 nsACString_Finish(&url);
602 nsAString_Finish(&user);
603 nsAString_Finish(&password);
605 if(NS_FAILED(nsres)) {
606 ERR("nsIXMLHttpRequest_Open failed: %08lx\n", nsres);
607 return E_FAIL;
610 return S_OK;
613 static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)
615 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
616 nsIWritableVariant *nsbody = NULL;
617 nsresult nsres = NS_OK;
619 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varBody));
621 switch(V_VT(&varBody)) {
622 case VT_NULL:
623 case VT_EMPTY:
624 case VT_ERROR:
625 break;
626 case VT_BSTR: {
627 nsAString nsstr;
629 nsbody = create_nsvariant();
630 if(!nsbody)
631 return E_OUTOFMEMORY;
633 nsAString_InitDepend(&nsstr, V_BSTR(&varBody));
634 nsres = nsIWritableVariant_SetAsAString(nsbody, &nsstr);
635 nsAString_Finish(&nsstr);
636 break;
638 default:
639 FIXME("unsupported body type %s\n", debugstr_variant(&varBody));
640 return E_NOTIMPL;
643 if(NS_SUCCEEDED(nsres))
644 nsres = nsIXMLHttpRequest_Send(This->nsxhr, (nsIVariant*)nsbody);
645 if(nsbody)
646 nsIWritableVariant_Release(nsbody);
647 if(NS_FAILED(nsres)) {
648 ERR("nsIXMLHttpRequest_Send failed: %08lx\n", nsres);
649 return E_FAIL;
652 return S_OK;
655 static HRESULT WINAPI HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest *iface, BSTR *p)
657 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
658 nsACString nscstr;
659 nsresult nsres;
660 HRESULT hres;
661 LONG state;
663 TRACE("(%p)->(%p)\n", This, p);
665 if(!p)
666 return E_POINTER;
668 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
669 if(FAILED(hres))
670 return hres;
672 if(state < 2) {
673 *p = NULL;
674 return E_FAIL;
677 nsACString_Init(&nscstr, NULL);
678 nsres = nsIXMLHttpRequest_GetAllResponseHeaders(This->nsxhr, &nscstr);
679 return return_nscstr(nsres, &nscstr, p);
682 static HRESULT WINAPI HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR *p)
684 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
685 nsACString header, ret;
686 char *cstr;
687 nsresult nsres;
688 HRESULT hres;
689 LONG state;
690 TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrHeader), p);
692 if(!p)
693 return E_POINTER;
694 if(!bstrHeader)
695 return E_INVALIDARG;
697 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
698 if(FAILED(hres))
699 return hres;
701 if(state < 2) {
702 *p = NULL;
703 return E_FAIL;
706 cstr = strdupWtoU(bstrHeader);
707 nsACString_InitDepend(&header, cstr);
708 nsACString_Init(&ret, NULL);
710 nsres = nsIXMLHttpRequest_GetResponseHeader(This->nsxhr, &header, &ret);
712 nsACString_Finish(&header);
713 free(cstr);
714 return return_nscstr(nsres, &ret, p);
717 static HRESULT WINAPI HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR bstrValue)
719 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
720 char *header_u, *value_u;
721 nsACString header, value;
722 nsresult nsres;
724 TRACE("(%p)->(%s %s)\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
726 header_u = strdupWtoU(bstrHeader);
727 if(bstrHeader && !header_u)
728 return E_OUTOFMEMORY;
730 value_u = strdupWtoU(bstrValue);
731 if(bstrValue && !value_u) {
732 free(header_u);
733 return E_OUTOFMEMORY;
736 nsACString_InitDepend(&header, header_u);
737 nsACString_InitDepend(&value, value_u);
738 nsres = nsIXMLHttpRequest_SetRequestHeader(This->nsxhr, &header, &value);
739 nsACString_Finish(&header);
740 nsACString_Finish(&value);
741 free(header_u);
742 free(value_u);
743 if(NS_FAILED(nsres)) {
744 ERR("SetRequestHeader failed: %08lx\n", nsres);
745 return E_FAIL;
748 return S_OK;
751 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
752 HTMLXMLHttpRequest_QueryInterface,
753 HTMLXMLHttpRequest_AddRef,
754 HTMLXMLHttpRequest_Release,
755 HTMLXMLHttpRequest_GetTypeInfoCount,
756 HTMLXMLHttpRequest_GetTypeInfo,
757 HTMLXMLHttpRequest_GetIDsOfNames,
758 HTMLXMLHttpRequest_Invoke,
759 HTMLXMLHttpRequest_get_readyState,
760 HTMLXMLHttpRequest_get_responseBody,
761 HTMLXMLHttpRequest_get_responseText,
762 HTMLXMLHttpRequest_get_responseXML,
763 HTMLXMLHttpRequest_get_status,
764 HTMLXMLHttpRequest_get_statusText,
765 HTMLXMLHttpRequest_put_onreadystatechange,
766 HTMLXMLHttpRequest_get_onreadystatechange,
767 HTMLXMLHttpRequest_abort,
768 HTMLXMLHttpRequest_open,
769 HTMLXMLHttpRequest_send,
770 HTMLXMLHttpRequest_getAllResponseHeaders,
771 HTMLXMLHttpRequest_getResponseHeader,
772 HTMLXMLHttpRequest_setRequestHeader
775 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest2(IHTMLXMLHttpRequest2 *iface)
777 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest2_iface);
780 static HRESULT WINAPI HTMLXMLHttpRequest2_QueryInterface(IHTMLXMLHttpRequest2 *iface, REFIID riid, void **ppv)
782 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
783 return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
786 static ULONG WINAPI HTMLXMLHttpRequest2_AddRef(IHTMLXMLHttpRequest2 *iface)
788 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
789 return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
792 static ULONG WINAPI HTMLXMLHttpRequest2_Release(IHTMLXMLHttpRequest2 *iface)
794 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
795 return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
798 static HRESULT WINAPI HTMLXMLHttpRequest2_GetTypeInfoCount(IHTMLXMLHttpRequest2 *iface, UINT *pctinfo)
800 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
801 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
804 static HRESULT WINAPI HTMLXMLHttpRequest2_GetTypeInfo(IHTMLXMLHttpRequest2 *iface, UINT iTInfo,
805 LCID lcid, ITypeInfo **ppTInfo)
807 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
808 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
811 static HRESULT WINAPI HTMLXMLHttpRequest2_GetIDsOfNames(IHTMLXMLHttpRequest2 *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
812 LCID lcid, DISPID *rgDispId)
814 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
815 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
816 lcid, rgDispId);
819 static HRESULT WINAPI HTMLXMLHttpRequest2_Invoke(IHTMLXMLHttpRequest2 *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
820 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
822 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
823 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
824 pDispParams, pVarResult, pExcepInfo, puArgErr);
827 static HRESULT WINAPI HTMLXMLHttpRequest2_put_timeout(IHTMLXMLHttpRequest2 *iface, LONG v)
829 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
831 TRACE("(%p)->(%ld)\n", This, v);
833 if(v < 0)
834 return E_INVALIDARG;
835 return map_nsresult(nsIXMLHttpRequest_SetTimeout(This->nsxhr, v));
838 static HRESULT WINAPI HTMLXMLHttpRequest2_get_timeout(IHTMLXMLHttpRequest2 *iface, LONG *p)
840 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
841 nsresult nsres;
842 UINT32 timeout;
844 TRACE("(%p)->(%p)\n", This, p);
846 if(!p)
847 return E_POINTER;
849 nsres = nsIXMLHttpRequest_GetTimeout(This->nsxhr, &timeout);
850 *p = timeout;
851 return map_nsresult(nsres);
854 static HRESULT WINAPI HTMLXMLHttpRequest2_put_ontimeout(IHTMLXMLHttpRequest2 *iface, VARIANT v)
856 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
858 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
860 return set_event_handler(&This->event_target, EVENTID_TIMEOUT, &v);
863 static HRESULT WINAPI HTMLXMLHttpRequest2_get_ontimeout(IHTMLXMLHttpRequest2 *iface, VARIANT *p)
865 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest2(iface);
867 TRACE("(%p)->(%p)\n", This, p);
869 return get_event_handler(&This->event_target, EVENTID_TIMEOUT, p);
872 static const IHTMLXMLHttpRequest2Vtbl HTMLXMLHttpRequest2Vtbl = {
873 HTMLXMLHttpRequest2_QueryInterface,
874 HTMLXMLHttpRequest2_AddRef,
875 HTMLXMLHttpRequest2_Release,
876 HTMLXMLHttpRequest2_GetTypeInfoCount,
877 HTMLXMLHttpRequest2_GetTypeInfo,
878 HTMLXMLHttpRequest2_GetIDsOfNames,
879 HTMLXMLHttpRequest2_Invoke,
880 HTMLXMLHttpRequest2_put_timeout,
881 HTMLXMLHttpRequest2_get_timeout,
882 HTMLXMLHttpRequest2_put_ontimeout,
883 HTMLXMLHttpRequest2_get_ontimeout
886 static inline HTMLXMLHttpRequest *impl_from_IWineXMLHttpRequestPrivate(IWineXMLHttpRequestPrivate *iface)
888 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IWineXMLHttpRequestPrivate_iface);
891 static HRESULT WINAPI HTMLXMLHttpRequest_private_QueryInterface(IWineXMLHttpRequestPrivate *iface, REFIID riid, void **ppv)
893 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
894 return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
897 static ULONG WINAPI HTMLXMLHttpRequest_private_AddRef(IWineXMLHttpRequestPrivate *iface)
899 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
900 return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
903 static ULONG WINAPI HTMLXMLHttpRequest_private_Release(IWineXMLHttpRequestPrivate *iface)
905 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
906 return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
909 static HRESULT WINAPI HTMLXMLHttpRequest_private_GetTypeInfoCount(IWineXMLHttpRequestPrivate *iface, UINT *pctinfo)
911 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
912 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
915 static HRESULT WINAPI HTMLXMLHttpRequest_private_GetTypeInfo(IWineXMLHttpRequestPrivate *iface, UINT iTInfo,
916 LCID lcid, ITypeInfo **ppTInfo)
918 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
919 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
922 static HRESULT WINAPI HTMLXMLHttpRequest_private_GetIDsOfNames(IWineXMLHttpRequestPrivate *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
923 LCID lcid, DISPID *rgDispId)
925 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
926 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
927 lcid, rgDispId);
930 static HRESULT WINAPI HTMLXMLHttpRequest_private_Invoke(IWineXMLHttpRequestPrivate *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
931 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
933 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
934 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
935 pDispParams, pVarResult, pExcepInfo, puArgErr);
938 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
940 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
941 HRESULT hres = S_OK;
942 nsresult nsres;
943 UINT16 state;
945 TRACE("(%p)->(%p)\n", This, p);
947 switch(This->response_type) {
948 case response_type_empty:
949 case response_type_text:
950 hres = IHTMLXMLHttpRequest_get_responseText(&This->IHTMLXMLHttpRequest_iface, &V_BSTR(p));
951 if(SUCCEEDED(hres))
952 V_VT(p) = VT_BSTR;
953 break;
955 case response_type_doc:
956 FIXME("response_type_doc\n");
957 return E_NOTIMPL;
959 case response_type_arraybuf:
960 case response_type_blob:
961 nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &state);
962 if(NS_FAILED(nsres) || state < 4) {
963 V_VT(p) = VT_EMPTY;
964 break;
966 if(This->response_type == response_type_arraybuf) {
967 FIXME("response_type_arraybuf\n");
968 return E_NOTIMPL;
970 FIXME("response_type_blob\n");
971 return E_NOTIMPL;
973 case response_type_stream:
974 FIXME("response_type_stream\n");
975 return E_NOTIMPL;
977 default:
978 assert(0);
981 return hres;
984 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_responseType(IWineXMLHttpRequestPrivate *iface, BSTR v)
986 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
987 nsAString nsstr;
988 nsresult nsres;
989 HRESULT hres;
990 unsigned i;
991 LONG state;
993 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
995 hres = IHTMLXMLHttpRequest_get_readyState(&This->IHTMLXMLHttpRequest_iface, &state);
996 if(FAILED(hres))
997 return hres;
999 if(state < 1 || state > 2) {
1000 /* FIXME: Return InvalidStateError */
1001 return E_FAIL;
1004 for(i = 0; i < ARRAY_SIZE(response_type_desc); i++)
1005 if(!wcscmp(v, response_type_desc[i].str))
1006 break;
1007 if(i >= ARRAY_SIZE(response_type_desc))
1008 return S_OK;
1010 nsAString_InitDepend(&nsstr, response_type_desc[i].nsxhr_str);
1011 nsres = nsIXMLHttpRequest_SetResponseType(This->nsxhr, &nsstr);
1012 nsAString_Finish(&nsstr);
1013 if(NS_FAILED(nsres))
1014 return map_nsresult(nsres);
1016 This->response_type = i;
1017 return S_OK;
1020 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_responseType(IWineXMLHttpRequestPrivate *iface, BSTR *p)
1022 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1024 TRACE("(%p)->(%p)\n", This, p);
1026 *p = SysAllocString(response_type_desc[This->response_type].str);
1027 return *p ? S_OK : E_OUTOFMEMORY;
1030 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_upload(IWineXMLHttpRequestPrivate *iface, IDispatch **p)
1032 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1034 FIXME("(%p)->(%p)\n", This, p);
1036 return E_NOTIMPL;
1039 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_withCredentials(IWineXMLHttpRequestPrivate *iface, VARIANT_BOOL v)
1041 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1043 TRACE("(%p)->(%x)\n", This, v);
1045 return map_nsresult(nsIXMLHttpRequest_SetWithCredentials(This->nsxhr, !!v));
1048 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_withCredentials(IWineXMLHttpRequestPrivate *iface, VARIANT_BOOL *p)
1050 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1051 nsresult nsres;
1052 cpp_bool b;
1054 TRACE("(%p)->(%p)\n", This, p);
1056 nsres = nsIXMLHttpRequest_GetWithCredentials(This->nsxhr, &b);
1057 if(NS_FAILED(nsres))
1058 return map_nsresult(nsres);
1059 *p = b ? VARIANT_TRUE : VARIANT_FALSE;
1060 return S_OK;
1063 static HRESULT WINAPI HTMLXMLHttpRequest_private_overrideMimeType(IWineXMLHttpRequestPrivate *iface, BSTR mimeType)
1065 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1066 static const WCHAR generic_type[] = L"application/octet-stream";
1067 const WCHAR *type = NULL;
1068 WCHAR *lowercase = NULL;
1069 nsAString nsstr;
1070 nsresult nsres;
1072 TRACE("(%p)->(%s)\n", This, debugstr_w(mimeType));
1074 if(mimeType) {
1075 if(mimeType[0]) {
1076 if(!(lowercase = wcsdup(mimeType)))
1077 return E_OUTOFMEMORY;
1078 _wcslwr(lowercase);
1079 type = lowercase;
1080 }else
1081 type = generic_type;
1084 nsAString_InitDepend(&nsstr, type);
1085 nsres = nsIXMLHttpRequest_SlowOverrideMimeType(This->nsxhr, &nsstr);
1086 nsAString_Finish(&nsstr);
1087 free(lowercase);
1088 return map_nsresult(nsres);
1091 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onerror(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1093 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1095 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1097 return set_event_handler(&This->event_target, EVENTID_ERROR, &v);
1100 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onerror(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1102 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1104 TRACE("(%p)->(%p)\n", This, p);
1106 return get_event_handler(&This->event_target, EVENTID_ERROR, p);
1109 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onabort(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1111 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1113 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1115 return set_event_handler(&This->event_target, EVENTID_ABORT, &v);
1118 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onabort(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1120 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1122 TRACE("(%p)->(%p)\n", This, p);
1124 return get_event_handler(&This->event_target, EVENTID_ABORT, p);
1127 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onprogress(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1129 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1131 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1133 return set_event_handler(&This->event_target, EVENTID_PROGRESS, &v);
1136 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onprogress(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1138 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1140 TRACE("(%p)->(%p)\n", This, p);
1142 return get_event_handler(&This->event_target, EVENTID_PROGRESS, p);
1145 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onloadstart(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1147 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1149 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1151 return set_event_handler(&This->event_target, EVENTID_LOADSTART, &v);
1154 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onloadstart(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1156 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1158 TRACE("(%p)->(%p)\n", This, p);
1160 return get_event_handler(&This->event_target, EVENTID_LOADSTART, p);
1163 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onloadend(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1165 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1167 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1169 return set_event_handler(&This->event_target, EVENTID_LOADEND, &v);
1172 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onloadend(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1174 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1176 TRACE("(%p)->(%p)\n", This, p);
1178 return get_event_handler(&This->event_target, EVENTID_LOADEND, p);
1181 static HRESULT WINAPI HTMLXMLHttpRequest_private_put_onload(IWineXMLHttpRequestPrivate *iface, VARIANT v)
1183 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1185 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1187 return set_event_handler(&This->event_target, EVENTID_LOAD, &v);
1190 static HRESULT WINAPI HTMLXMLHttpRequest_private_get_onload(IWineXMLHttpRequestPrivate *iface, VARIANT *p)
1192 HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
1194 TRACE("(%p)->(%p)\n", This, p);
1196 return get_event_handler(&This->event_target, EVENTID_LOAD, p);
1199 static const IWineXMLHttpRequestPrivateVtbl WineXMLHttpRequestPrivateVtbl = {
1200 HTMLXMLHttpRequest_private_QueryInterface,
1201 HTMLXMLHttpRequest_private_AddRef,
1202 HTMLXMLHttpRequest_private_Release,
1203 HTMLXMLHttpRequest_private_GetTypeInfoCount,
1204 HTMLXMLHttpRequest_private_GetTypeInfo,
1205 HTMLXMLHttpRequest_private_GetIDsOfNames,
1206 HTMLXMLHttpRequest_private_Invoke,
1207 HTMLXMLHttpRequest_private_get_response,
1208 HTMLXMLHttpRequest_private_put_responseType,
1209 HTMLXMLHttpRequest_private_get_responseType,
1210 HTMLXMLHttpRequest_private_get_upload,
1211 HTMLXMLHttpRequest_private_put_withCredentials,
1212 HTMLXMLHttpRequest_private_get_withCredentials,
1213 HTMLXMLHttpRequest_private_overrideMimeType,
1214 HTMLXMLHttpRequest_private_put_onerror,
1215 HTMLXMLHttpRequest_private_get_onerror,
1216 HTMLXMLHttpRequest_private_put_onabort,
1217 HTMLXMLHttpRequest_private_get_onabort,
1218 HTMLXMLHttpRequest_private_put_onprogress,
1219 HTMLXMLHttpRequest_private_get_onprogress,
1220 HTMLXMLHttpRequest_private_put_onloadstart,
1221 HTMLXMLHttpRequest_private_get_onloadstart,
1222 HTMLXMLHttpRequest_private_put_onloadend,
1223 HTMLXMLHttpRequest_private_get_onloadend,
1224 HTMLXMLHttpRequest_private_put_onload,
1225 HTMLXMLHttpRequest_private_get_onload
1228 static inline HTMLXMLHttpRequest *impl_from_IProvideClassInfo2(IProvideClassInfo2 *iface)
1230 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IProvideClassInfo2_iface);
1233 static HRESULT WINAPI ProvideClassInfo_QueryInterface(IProvideClassInfo2 *iface, REFIID riid, void **ppv)
1235 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1236 return IHTMLXMLHttpRequest_QueryInterface(&This->IHTMLXMLHttpRequest_iface, riid, ppv);
1239 static ULONG WINAPI ProvideClassInfo_AddRef(IProvideClassInfo2 *iface)
1241 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1242 return IHTMLXMLHttpRequest_AddRef(&This->IHTMLXMLHttpRequest_iface);
1245 static ULONG WINAPI ProvideClassInfo_Release(IProvideClassInfo2 *iface)
1247 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1248 return IHTMLXMLHttpRequest_Release(&This->IHTMLXMLHttpRequest_iface);
1251 static HRESULT WINAPI ProvideClassInfo_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI)
1253 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1254 TRACE("(%p)->(%p)\n", This, ppTI);
1255 return get_class_typeinfo(&CLSID_HTMLXMLHttpRequest, ppTI);
1258 static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID)
1260 HTMLXMLHttpRequest *This = impl_from_IProvideClassInfo2(iface);
1261 FIXME("(%p)->(%lu %p)\n", This, dwGuidKind, pGUID);
1262 return E_NOTIMPL;
1265 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl = {
1266 ProvideClassInfo_QueryInterface,
1267 ProvideClassInfo_AddRef,
1268 ProvideClassInfo_Release,
1269 ProvideClassInfo_GetClassInfo,
1270 ProvideClassInfo2_GetGUID,
1273 static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
1275 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
1278 static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex)
1280 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
1281 return (nsISupports*)This->nsxhr;
1284 static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid)
1286 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
1287 nsIDOMEventTarget *nstarget;
1288 nsAString type_str;
1289 const WCHAR *name;
1290 nsresult nsres;
1291 unsigned i;
1293 TRACE("(%p)\n", This);
1295 for(i = 0; i < ARRAY_SIZE(events); i++)
1296 if(eid == events[i])
1297 break;
1298 if(i >= ARRAY_SIZE(events))
1299 return;
1301 if(!This->event_listener) {
1302 This->event_listener = malloc(sizeof(*This->event_listener));
1303 if(!This->event_listener)
1304 return;
1306 This->event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
1307 This->event_listener->ref = 1;
1308 This->event_listener->xhr = This;
1309 This->event_listener->events_mask = 0;
1312 nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
1313 assert(nsres == NS_OK);
1315 name = get_event_name(events[i]);
1316 nsAString_InitDepend(&type_str, name);
1317 nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
1318 nsAString_Finish(&type_str);
1319 if(NS_FAILED(nsres))
1320 ERR("AddEventListener(%s) failed: %08lx\n", debugstr_w(name), nsres);
1322 nsIDOMEventTarget_Release(nstarget);
1324 This->event_listener->events_mask |= 1 << i;
1327 static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode)
1329 static const dispex_hook_t xhr_hooks[] = {
1330 {DISPID_IHTMLXMLHTTPREQUEST_OPEN, HTMLXMLHttpRequest_open_hook},
1331 {DISPID_UNKNOWN}
1333 static const dispex_hook_t private_hooks[] = {
1334 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSE},
1335 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE},
1336 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_UPLOAD},
1337 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_WITHCREDENTIALS},
1338 {DISPID_EVPROP_ONERROR},
1339 {DISPID_EVPROP_ONABORT},
1340 {DISPID_EVPROP_PROGRESS},
1341 {DISPID_EVPROP_LOADSTART},
1342 {DISPID_EVPROP_LOADEND},
1344 /* IE10 only */
1345 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE},
1346 {DISPID_UNKNOWN}
1348 const dispex_hook_t *const private_ie10_hooks = private_hooks + ARRAY_SIZE(private_hooks) - 2;
1350 EventTarget_init_dispex_info(info, compat_mode);
1351 dispex_info_add_interface(info, IHTMLXMLHttpRequest_tid, compat_mode >= COMPAT_MODE_IE10 ? xhr_hooks : NULL);
1352 dispex_info_add_interface(info, IWineXMLHttpRequestPrivate_tid,
1353 compat_mode < COMPAT_MODE_IE10 ? private_hooks :
1354 compat_mode < COMPAT_MODE_IE11 ? private_ie10_hooks : NULL);
1357 static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = {
1359 NULL,
1361 HTMLXMLHttpRequest_get_gecko_target,
1362 HTMLXMLHttpRequest_bind_event
1365 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
1366 IHTMLXMLHttpRequest2_tid,
1369 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
1370 L"XMLHttpRequest",
1371 &HTMLXMLHttpRequest_event_target_vtbl.dispex_vtbl,
1372 DispHTMLXMLHttpRequest_tid,
1373 HTMLXMLHttpRequest_iface_tids,
1374 HTMLXMLHttpRequest_init_dispex_info
1378 /* IHTMLXMLHttpRequestFactory */
1379 static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface)
1381 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface);
1384 static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory *iface, REFIID riid, void **ppv)
1386 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1388 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1390 if(IsEqualGUID(&IID_IUnknown, riid)) {
1391 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
1392 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1393 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
1394 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) {
1395 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
1396 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
1397 return *ppv ? S_OK : E_NOINTERFACE;
1398 }else {
1399 *ppv = NULL;
1400 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
1401 return E_NOINTERFACE;
1404 IUnknown_AddRef((IUnknown*)*ppv);
1405 return S_OK;
1408 static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface)
1410 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1411 LONG ref = InterlockedIncrement(&This->ref);
1413 TRACE("(%p) ref=%ld\n", This, ref);
1415 return ref;
1418 static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface)
1420 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1421 LONG ref = InterlockedDecrement(&This->ref);
1423 TRACE("(%p) ref=%ld\n", This, ref);
1425 if(!ref) {
1426 release_dispex(&This->dispex);
1427 free(This);
1430 return ref;
1433 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory *iface, UINT *pctinfo)
1435 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1436 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
1439 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory *iface, UINT iTInfo,
1440 LCID lcid, ITypeInfo **ppTInfo)
1442 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1444 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1447 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1448 LCID lcid, DISPID *rgDispId)
1450 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1452 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
1453 lcid, rgDispId);
1456 static HRESULT WINAPI HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
1457 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1459 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1461 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1462 pDispParams, pVarResult, pExcepInfo, puArgErr);
1465 static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p)
1467 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
1468 HTMLXMLHttpRequest *ret;
1469 nsIXMLHttpRequest *nsxhr;
1471 TRACE("(%p)->(%p)\n", This, p);
1473 nsxhr = create_nsxhr(This->window->base.outer_window->nswindow);
1474 if(!nsxhr)
1475 return E_FAIL;
1477 ret = calloc(1, sizeof(*ret));
1478 if(!ret) {
1479 nsIXMLHttpRequest_Release(nsxhr);
1480 return E_OUTOFMEMORY;
1482 ret->nsxhr = nsxhr;
1484 ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
1485 ret->IHTMLXMLHttpRequest2_iface.lpVtbl = &HTMLXMLHttpRequest2Vtbl;
1486 ret->IWineXMLHttpRequestPrivate_iface.lpVtbl = &WineXMLHttpRequestPrivateVtbl;
1487 ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl;
1488 EventTarget_Init(&ret->event_target, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
1489 &HTMLXMLHttpRequest_dispex, This->window->doc->document_mode);
1490 ret->ref = 1;
1492 *p = &ret->IHTMLXMLHttpRequest_iface;
1493 return S_OK;
1496 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = {
1497 HTMLXMLHttpRequestFactory_QueryInterface,
1498 HTMLXMLHttpRequestFactory_AddRef,
1499 HTMLXMLHttpRequestFactory_Release,
1500 HTMLXMLHttpRequestFactory_GetTypeInfoCount,
1501 HTMLXMLHttpRequestFactory_GetTypeInfo,
1502 HTMLXMLHttpRequestFactory_GetIDsOfNames,
1503 HTMLXMLHttpRequestFactory_Invoke,
1504 HTMLXMLHttpRequestFactory_create
1507 static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *iface)
1509 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex);
1512 static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WORD flags, DISPPARAMS *params,
1513 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1515 HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(iface);
1516 IHTMLXMLHttpRequest *xhr;
1517 HRESULT hres;
1519 TRACE("\n");
1521 if(flags != DISPATCH_CONSTRUCT) {
1522 FIXME("flags %x not supported\n", flags);
1523 return E_NOTIMPL;
1526 hres = IHTMLXMLHttpRequestFactory_create(&This->IHTMLXMLHttpRequestFactory_iface, &xhr);
1527 if(FAILED(hres))
1528 return hres;
1530 V_VT(res) = VT_DISPATCH;
1531 V_DISPATCH(res) = (IDispatch*)xhr;
1532 return S_OK;
1535 static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = {
1536 HTMLXMLHttpRequestFactory_value
1539 static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = {
1540 IHTMLXMLHttpRequestFactory_tid,
1543 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
1544 L"Function",
1545 &HTMLXMLHttpRequestFactory_dispex_vtbl,
1546 IHTMLXMLHttpRequestFactory_tid,
1547 HTMLXMLHttpRequestFactory_iface_tids
1550 HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr)
1552 HTMLXMLHttpRequestFactory *ret;
1554 ret = malloc(sizeof(*ret));
1555 if(!ret)
1556 return E_OUTOFMEMORY;
1558 ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl;
1559 ret->ref = 1;
1560 ret->window = window;
1562 init_dispatch(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface,
1563 &HTMLXMLHttpRequestFactory_dispex, dispex_compat_mode(&window->event_target.dispex));
1565 *ret_ptr = ret;
1566 return S_OK;