dwrite: Partially implement GetGlyphImageFormats().
[wine.git] / dlls / mshtml / xmlhttprequest.c
blob30389a4cde1f10b119dc53312143d92b9ecd5733
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>
20 #include <assert.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
29 #include "wine/debug.h"
31 #include "mshtml_private.h"
32 #include "htmlevent.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 = heap_strdupWtoU(bstr);
42 if(!cstr)
43 return E_OUTOFMEMORY;
44 nsACString_Init(str, cstr);
45 heap_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: %08x\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);
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 typedef struct {
96 nsIDOMEventListener nsIDOMEventListener_iface;
97 LONG ref;
98 HTMLXMLHttpRequest *xhr;
99 } XMLHttpReqEventListener;
101 struct HTMLXMLHttpRequest {
102 EventTarget event_target;
103 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
104 LONG ref;
105 nsIXMLHttpRequest *nsxhr;
106 XMLHttpReqEventListener *event_listener;
109 static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
111 nsIDOMEventTarget *event_target;
112 nsAString str;
113 nsresult nsres;
115 static const WCHAR readystatechangeW[] =
116 {'o','n','r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
118 nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
119 assert(nsres == NS_OK);
121 nsAString_InitDepend(&str, readystatechangeW);
122 nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
123 nsAString_Finish(&str);
124 nsIDOMEventTarget_Release(event_target);
126 event_listener->xhr->event_listener = NULL;
127 event_listener->xhr = NULL;
128 nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
132 static inline XMLHttpReqEventListener *impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
134 return CONTAINING_RECORD(iface, XMLHttpReqEventListener, nsIDOMEventListener_iface);
137 static nsresult NSAPI XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener *iface,
138 nsIIDRef riid, void **result)
140 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
142 if(IsEqualGUID(&IID_nsISupports, riid)) {
143 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
144 *result = &This->nsIDOMEventListener_iface;
145 }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
146 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
147 *result = &This->nsIDOMEventListener_iface;
148 }else {
149 *result = NULL;
150 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
151 return NS_NOINTERFACE;
154 nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
155 return NS_OK;
158 static nsrefcnt NSAPI XMLHttpReqEventListener_AddRef(nsIDOMEventListener *iface)
160 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
161 LONG ref = InterlockedIncrement(&This->ref);
163 TRACE("(%p) ref=%d\n", This, ref);
165 return ref;
168 static nsrefcnt NSAPI XMLHttpReqEventListener_Release(nsIDOMEventListener *iface)
170 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
171 LONG ref = InterlockedDecrement(&This->ref);
173 TRACE("(%p) ref=%d\n", This, ref);
175 if(!ref) {
176 assert(!This->xhr);
177 heap_free(This);
180 return ref;
183 static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *event)
185 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
187 TRACE("(%p)\n", This);
189 if(!This->xhr)
190 return NS_OK;
192 call_event_handlers(NULL, NULL, &This->xhr->event_target, NULL, EVENTID_READYSTATECHANGE,
193 (IDispatch*)&This->xhr->IHTMLXMLHttpRequest_iface);
194 return NS_OK;
197 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl = {
198 XMLHttpReqEventListener_QueryInterface,
199 XMLHttpReqEventListener_AddRef,
200 XMLHttpReqEventListener_Release,
201 XMLHttpReqEventListener_HandleEvent
204 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
206 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
209 static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *iface, REFIID riid, void **ppv)
211 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
213 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
215 if(IsEqualGUID(&IID_IUnknown, riid)) {
216 *ppv = &This->IHTMLXMLHttpRequest_iface;
217 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
218 *ppv = &This->IHTMLXMLHttpRequest_iface;
219 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
220 *ppv = &This->IHTMLXMLHttpRequest_iface;
221 }else if(dispex_query_interface(&This->event_target.dispex, riid, ppv)) {
222 return *ppv ? S_OK : E_NOINTERFACE;
223 }else {
224 *ppv = NULL;
225 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
226 return E_NOINTERFACE;
229 IUnknown_AddRef((IUnknown*)*ppv);
230 return S_OK;
233 static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
235 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
236 LONG ref = InterlockedIncrement(&This->ref);
238 TRACE("(%p) ref=%d\n", This, ref);
240 return ref;
243 static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
245 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
246 LONG ref = InterlockedDecrement(&This->ref);
248 TRACE("(%p) ref=%d\n", This, ref);
250 if(!ref) {
251 if(This->event_listener)
252 detach_xhr_event_listener(This->event_listener);
253 release_event_target(&This->event_target);
254 release_dispex(&This->event_target.dispex);
255 nsIXMLHttpRequest_Release(This->nsxhr);
256 heap_free(This);
259 return ref;
262 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest *iface, UINT *pctinfo)
264 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
265 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
268 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest *iface, UINT iTInfo,
269 LCID lcid, ITypeInfo **ppTInfo)
271 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
273 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
276 static HRESULT WINAPI HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
277 LCID lcid, DISPID *rgDispId)
279 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
281 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
282 lcid, rgDispId);
285 static HRESULT WINAPI HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
286 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
288 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
290 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
291 pDispParams, pVarResult, pExcepInfo, puArgErr);
294 static HRESULT WINAPI HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest *iface, LONG *p)
296 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
297 UINT16 val;
298 nsresult nsres;
300 TRACE("(%p)->(%p)\n", This, p);
302 if(!p)
303 return E_POINTER;
304 nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &val);
305 if(NS_FAILED(nsres)) {
306 ERR("nsIXMLHttpRequest_GetReadyState failed: %08x\n", nsres);
307 return E_FAIL;
309 *p = val;
310 return S_OK;
313 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest *iface, VARIANT *p)
315 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
316 FIXME("(%p)->(%p)\n", This, p);
317 return E_NOTIMPL;
320 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *iface, BSTR *p)
322 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
323 nsAString nsstr;
324 nsresult nsres;
326 TRACE("(%p)->(%p)\n", This, p);
328 if(!p)
329 return E_POINTER;
331 nsAString_Init(&nsstr, NULL);
332 nsres = nsIXMLHttpRequest_GetResponseText(This->nsxhr, &nsstr);
333 return return_nsstr(nsres, &nsstr, p);
336 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
338 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
339 IXMLDOMDocument *xmldoc = NULL;
340 BSTR str;
341 HRESULT hres;
342 VARIANT_BOOL vbool;
343 IObjectSafety *safety;
345 TRACE("(%p)->(%p)\n", This, p);
347 hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc);
348 if(FAILED(hres)) {
349 ERR("CoCreateInstance failed: %08x\n", hres);
350 return hres;
353 hres = IHTMLXMLHttpRequest_get_responseText(iface, &str);
354 if(FAILED(hres)) {
355 IXMLDOMDocument_Release(xmldoc);
356 ERR("get_responseText failed: %08x\n", hres);
357 return hres;
360 hres = IXMLDOMDocument_loadXML(xmldoc, str, &vbool);
361 SysFreeString(str);
362 if(hres != S_OK || vbool != VARIANT_TRUE)
363 WARN("loadXML failed: %08x, returning an empty xmldoc\n", hres);
365 hres = IXMLDOMDocument_QueryInterface(xmldoc, &IID_IObjectSafety, (void**)&safety);
366 assert(SUCCEEDED(hres));
367 hres = IObjectSafety_SetInterfaceSafetyOptions(safety, NULL,
368 INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER,
369 INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER);
370 assert(SUCCEEDED(hres));
371 IObjectSafety_Release(safety);
373 *p = (IDispatch*)xmldoc;
374 return S_OK;
377 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)
379 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
380 DWORD val;
381 nsresult nsres;
382 TRACE("(%p)->(%p)\n", This, p);
384 if(!p)
385 return E_POINTER;
387 nsres = nsIXMLHttpRequest_GetStatus(This->nsxhr, &val);
388 if(NS_FAILED(nsres)) {
389 ERR("nsIXMLHttpRequest_GetStatus failed: %08x\n", nsres);
390 return E_FAIL;
392 *p = val;
393 if(val == 0)
394 return E_FAIL; /* WinAPI thinks this is an error */
396 return S_OK;
399 static HRESULT WINAPI HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest *iface, BSTR *p)
401 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
402 nsACString nscstr;
403 nsresult nsres;
404 HRESULT hres;
405 LONG state;
407 TRACE("(%p)->(%p)\n", This, p);
409 if(!p)
410 return E_POINTER;
412 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
413 if(FAILED(hres))
414 return hres;
416 if(state < 2) {
417 *p = NULL;
418 return E_FAIL;
421 nsACString_Init(&nscstr, NULL);
422 nsres = nsIXMLHttpRequest_GetStatusText(This->nsxhr, &nscstr);
423 return return_nscstr(nsres, &nscstr, p);
426 static HRESULT WINAPI HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT v)
428 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
430 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
432 return set_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, &v);
435 static HRESULT WINAPI HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT *p)
437 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
439 TRACE("(%p)->(%p)\n", This, p);
441 return get_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, p);
444 static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
446 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
447 nsresult nsres;
449 TRACE("(%p)->()\n", This);
451 nsres = nsIXMLHttpRequest_SlowAbort(This->nsxhr);
452 if(NS_FAILED(nsres)) {
453 ERR("nsIXMLHttpRequest_SlowAbort failed: %08x\n", nsres);
454 return E_FAIL;
457 return S_OK;
460 static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword)
462 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
463 nsACString method, url;
464 nsAString user, password;
465 nsresult nsres;
466 HRESULT hres;
468 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword));
470 if(V_VT(&varAsync) != VT_BOOL) {
471 FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync));
472 return E_FAIL;
475 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
476 * synchronous requests on the main thread have been deprecated due to the negative
477 * effects to the user experience.
479 if(!V_BOOL(&varAsync)) {
480 FIXME("Synchronous request is not supported yet\n");
481 return E_FAIL;
484 hres = variant_to_nsastr(varUser, &user);
485 if(FAILED(hres))
486 return hres;
487 hres = variant_to_nsastr(varPassword, &password);
488 if(FAILED(hres)) {
489 nsAString_Finish(&user);
490 return hres;
493 hres = bstr_to_nsacstr(bstrMethod, &method);
494 if(FAILED(hres)) {
495 nsAString_Finish(&user);
496 nsAString_Finish(&password);
497 return hres;
499 hres = bstr_to_nsacstr(bstrUrl, &url);
500 if(FAILED(hres)) {
501 nsAString_Finish(&user);
502 nsAString_Finish(&password);
503 nsACString_Finish(&method);
504 return hres;
507 nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE,
508 &user, &password, 0);
510 nsACString_Finish(&method);
511 nsACString_Finish(&url);
512 nsAString_Finish(&user);
513 nsAString_Finish(&password);
515 if(NS_FAILED(nsres)) {
516 ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres);
517 return E_FAIL;
520 return S_OK;
523 static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)
525 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
526 nsIWritableVariant *nsbody = NULL;
527 nsresult nsres = NS_OK;
529 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varBody));
531 switch(V_VT(&varBody)) {
532 case VT_NULL:
533 case VT_EMPTY:
534 case VT_ERROR:
535 break;
536 case VT_BSTR: {
537 nsAString nsstr;
539 nsbody = create_nsvariant();
540 if(!nsbody)
541 return E_OUTOFMEMORY;
543 nsAString_InitDepend(&nsstr, V_BSTR(&varBody));
544 nsres = nsIWritableVariant_SetAsAString(nsbody, &nsstr);
545 nsAString_Finish(&nsstr);
546 break;
548 default:
549 FIXME("unsupported body type %s\n", debugstr_variant(&varBody));
550 return E_NOTIMPL;
553 if(NS_SUCCEEDED(nsres))
554 nsres = nsIXMLHttpRequest_Send(This->nsxhr, (nsIVariant*)nsbody);
555 if(nsbody)
556 nsIWritableVariant_Release(nsbody);
557 if(NS_FAILED(nsres)) {
558 ERR("nsIXMLHttpRequest_Send failed: %08x\n", nsres);
559 return E_FAIL;
562 return S_OK;
565 static HRESULT WINAPI HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest *iface, BSTR *p)
567 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
568 nsACString nscstr;
569 nsresult nsres;
570 HRESULT hres;
571 LONG state;
573 TRACE("(%p)->(%p)\n", This, p);
575 if(!p)
576 return E_POINTER;
578 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
579 if(FAILED(hres))
580 return hres;
582 if(state < 2) {
583 *p = NULL;
584 return E_FAIL;
587 nsACString_Init(&nscstr, NULL);
588 nsres = nsIXMLHttpRequest_GetAllResponseHeaders(This->nsxhr, &nscstr);
589 return return_nscstr(nsres, &nscstr, p);
592 static HRESULT WINAPI HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR *p)
594 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
595 nsACString header, ret;
596 char *cstr;
597 nsresult nsres;
598 HRESULT hres;
599 LONG state;
600 TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrHeader), p);
602 if(!p)
603 return E_POINTER;
604 if(!bstrHeader)
605 return E_INVALIDARG;
607 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
608 if(FAILED(hres))
609 return hres;
611 if(state < 2) {
612 *p = NULL;
613 return E_FAIL;
616 cstr = heap_strdupWtoU(bstrHeader);
617 nsACString_InitDepend(&header, cstr);
618 nsACString_Init(&ret, NULL);
620 nsres = nsIXMLHttpRequest_GetResponseHeader(This->nsxhr, &header, &ret);
622 nsACString_Finish(&header);
623 heap_free(cstr);
624 return return_nscstr(nsres, &ret, p);
627 static HRESULT WINAPI HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR bstrValue)
629 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
630 char *header_u, *value_u;
631 nsACString header, value;
632 nsresult nsres;
634 TRACE("(%p)->(%s %s)\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
636 header_u = heap_strdupWtoU(bstrHeader);
637 if(bstrHeader && !header_u)
638 return E_OUTOFMEMORY;
640 value_u = heap_strdupWtoU(bstrValue);
641 if(bstrValue && !value_u) {
642 heap_free(header_u);
643 return E_OUTOFMEMORY;
646 nsACString_InitDepend(&header, header_u);
647 nsACString_InitDepend(&value, value_u);
648 nsres = nsIXMLHttpRequest_SetRequestHeader(This->nsxhr, &header, &value);
649 nsACString_Finish(&header);
650 nsACString_Finish(&value);
651 heap_free(header_u);
652 heap_free(value_u);
653 if(NS_FAILED(nsres)) {
654 ERR("SetRequestHeader failed: %08x\n", nsres);
655 return E_FAIL;
658 return S_OK;
661 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
662 HTMLXMLHttpRequest_QueryInterface,
663 HTMLXMLHttpRequest_AddRef,
664 HTMLXMLHttpRequest_Release,
665 HTMLXMLHttpRequest_GetTypeInfoCount,
666 HTMLXMLHttpRequest_GetTypeInfo,
667 HTMLXMLHttpRequest_GetIDsOfNames,
668 HTMLXMLHttpRequest_Invoke,
669 HTMLXMLHttpRequest_get_readyState,
670 HTMLXMLHttpRequest_get_responseBody,
671 HTMLXMLHttpRequest_get_responseText,
672 HTMLXMLHttpRequest_get_responseXML,
673 HTMLXMLHttpRequest_get_status,
674 HTMLXMLHttpRequest_get_statusText,
675 HTMLXMLHttpRequest_put_onreadystatechange,
676 HTMLXMLHttpRequest_get_onreadystatechange,
677 HTMLXMLHttpRequest_abort,
678 HTMLXMLHttpRequest_open,
679 HTMLXMLHttpRequest_send,
680 HTMLXMLHttpRequest_getAllResponseHeaders,
681 HTMLXMLHttpRequest_getResponseHeader,
682 HTMLXMLHttpRequest_setRequestHeader
685 static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
687 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
690 static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, int eid)
692 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
693 nsIDOMEventTarget *nstarget;
694 nsAString type_str;
695 nsresult nsres;
697 static const WCHAR readystatechangeW[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
699 TRACE("(%p)\n", This);
701 assert(eid == EVENTID_READYSTATECHANGE);
703 if(This->event_listener)
704 return;
706 This->event_listener = heap_alloc(sizeof(*This->event_listener));
707 if(!This->event_listener)
708 return;
710 This->event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
711 This->event_listener->ref = 1;
712 This->event_listener->xhr = This;
714 nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
715 assert(nsres == NS_OK);
717 nsAString_InitDepend(&type_str, readystatechangeW);
718 nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
719 nsAString_Finish(&type_str);
720 nsIDOMEventTarget_Release(nstarget);
721 if(NS_FAILED(nsres))
722 ERR("AddEventListener failed: %08x\n", nsres);
725 static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl = {
726 NULL,
727 NULL,
728 NULL,
729 NULL,
730 NULL,
731 HTMLXMLHttpRequest_bind_event
734 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
735 IHTMLXMLHttpRequest_tid,
738 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
739 &HTMLXMLHttpRequest_dispex_vtbl,
740 DispHTMLXMLHttpRequest_tid,
741 HTMLXMLHttpRequest_iface_tids
745 /* IHTMLXMLHttpRequestFactory */
746 static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface)
748 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface);
751 static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory *iface, REFIID riid, void **ppv)
753 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
755 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
757 if(IsEqualGUID(&IID_IUnknown, riid)) {
758 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
759 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
760 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
761 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) {
762 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
763 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
764 return *ppv ? S_OK : E_NOINTERFACE;
765 }else {
766 *ppv = NULL;
767 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
768 return E_NOINTERFACE;
771 IUnknown_AddRef((IUnknown*)*ppv);
772 return S_OK;
775 static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface)
777 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
778 LONG ref = InterlockedIncrement(&This->ref);
780 TRACE("(%p) ref=%d\n", This, ref);
782 return ref;
785 static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface)
787 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
788 LONG ref = InterlockedDecrement(&This->ref);
790 TRACE("(%p) ref=%d\n", This, ref);
792 if(!ref) {
793 release_dispex(&This->dispex);
794 heap_free(This);
797 return ref;
800 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory *iface, UINT *pctinfo)
802 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
803 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
806 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory *iface, UINT iTInfo,
807 LCID lcid, ITypeInfo **ppTInfo)
809 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
811 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
814 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
815 LCID lcid, DISPID *rgDispId)
817 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
819 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
820 lcid, rgDispId);
823 static HRESULT WINAPI HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
824 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
826 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
828 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
829 pDispParams, pVarResult, pExcepInfo, puArgErr);
832 static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p)
834 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
835 HTMLXMLHttpRequest *ret;
836 nsIXMLHttpRequest *nsxhr;
838 TRACE("(%p)->(%p)\n", This, p);
840 nsxhr = create_nsxhr(This->window->base.outer_window->nswindow);
841 if(!nsxhr)
842 return E_FAIL;
844 ret = heap_alloc_zero(sizeof(*ret));
845 if(!ret) {
846 nsIXMLHttpRequest_Release(nsxhr);
847 return E_OUTOFMEMORY;
849 ret->nsxhr = nsxhr;
851 ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
852 init_event_target(&ret->event_target);
853 init_dispex(&ret->event_target.dispex, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
854 &HTMLXMLHttpRequest_dispex);
855 ret->ref = 1;
857 *p = &ret->IHTMLXMLHttpRequest_iface;
858 return S_OK;
861 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = {
862 HTMLXMLHttpRequestFactory_QueryInterface,
863 HTMLXMLHttpRequestFactory_AddRef,
864 HTMLXMLHttpRequestFactory_Release,
865 HTMLXMLHttpRequestFactory_GetTypeInfoCount,
866 HTMLXMLHttpRequestFactory_GetTypeInfo,
867 HTMLXMLHttpRequestFactory_GetIDsOfNames,
868 HTMLXMLHttpRequestFactory_Invoke,
869 HTMLXMLHttpRequestFactory_create
872 static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *iface)
874 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex);
877 static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WORD flags, DISPPARAMS *params,
878 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
880 HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(iface);
881 IHTMLXMLHttpRequest *xhr;
882 HRESULT hres;
884 TRACE("\n");
886 if(flags != DISPATCH_CONSTRUCT) {
887 FIXME("flags %x not supported\n", flags);
888 return E_NOTIMPL;
891 hres = IHTMLXMLHttpRequestFactory_create(&This->IHTMLXMLHttpRequestFactory_iface, &xhr);
892 if(FAILED(hres))
893 return hres;
895 V_VT(res) = VT_DISPATCH;
896 V_DISPATCH(res) = (IDispatch*)xhr;
897 return S_OK;
900 static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = {
901 HTMLXMLHttpRequestFactory_value
904 static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = {
905 IHTMLXMLHttpRequestFactory_tid,
908 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
909 &HTMLXMLHttpRequestFactory_dispex_vtbl,
910 IHTMLXMLHttpRequestFactory_tid,
911 HTMLXMLHttpRequestFactory_iface_tids
914 HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr)
916 HTMLXMLHttpRequestFactory *ret;
918 ret = heap_alloc(sizeof(*ret));
919 if(!ret)
920 return E_OUTOFMEMORY;
922 ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl;
923 ret->ref = 1;
924 ret->window = window;
926 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface,
927 &HTMLXMLHttpRequestFactory_dispex);
929 *ret_ptr = ret;
930 return S_OK;