ntdll: Implement RtlValidRelativeSecurityDescriptor.
[wine.git] / dlls / mshtml / xmlhttprequest.c
blobfdfa31f68a992c7496304683d7595744dfcbdfb5
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"
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36 static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str)
38 char *cstr = heap_strdupWtoU(bstr);
39 if(!cstr)
40 return E_OUTOFMEMORY;
41 nsACString_Init(str, cstr);
42 heap_free(cstr);
43 return S_OK;
46 static HRESULT variant_to_nsastr(VARIANT var, nsAString *ret)
48 switch(V_VT(&var)) {
49 case VT_NULL:
50 case VT_ERROR:
51 case VT_EMPTY:
52 nsAString_Init(ret, NULL);
53 return S_OK;
54 case VT_BSTR:
55 nsAString_InitDepend(ret, V_BSTR(&var));
56 return S_OK;
57 default:
58 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var));
59 return E_INVALIDARG;
63 static HRESULT return_nscstr(nsresult nsres, nsACString *nscstr, BSTR *p)
65 const char *str;
66 int len;
68 if(NS_FAILED(nsres)) {
69 ERR("failed: %08x\n", nsres);
70 nsACString_Finish(nscstr);
71 return E_FAIL;
74 nsACString_GetData(nscstr, &str);
76 if(*str) {
77 len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
78 *p = SysAllocStringLen(NULL, len);
79 if(!*p) {
80 nsACString_Finish(nscstr);
81 return E_OUTOFMEMORY;
83 MultiByteToWideChar(CP_UTF8, 0, str, -1, *p, len);
84 }else {
85 *p = NULL;
88 nsACString_Finish(nscstr);
89 return S_OK;
92 typedef struct XMLHttpReqEventListener XMLHttpReqEventListener;
94 typedef struct {
95 EventTarget event_target;
96 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
97 LONG ref;
98 nsIXMLHttpRequest *nsxhr;
99 XMLHttpReqEventListener *event_listener;
100 } HTMLXMLHttpRequest;
102 struct XMLHttpReqEventListener {
103 nsIDOMEventListener nsIDOMEventListener_iface;
104 LONG ref;
105 HTMLXMLHttpRequest *xhr;
108 static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
110 nsIDOMEventTarget *event_target;
111 nsAString str;
112 nsresult nsres;
114 static const WCHAR readystatechangeW[] =
115 {'o','n','r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
117 nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
118 assert(nsres == NS_OK);
120 nsAString_InitDepend(&str, readystatechangeW);
121 nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
122 nsAString_Finish(&str);
123 nsIDOMEventTarget_Release(event_target);
125 event_listener->xhr->event_listener = NULL;
126 event_listener->xhr = NULL;
127 nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
131 static inline XMLHttpReqEventListener *impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
133 return CONTAINING_RECORD(iface, XMLHttpReqEventListener, nsIDOMEventListener_iface);
136 static nsresult NSAPI XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener *iface,
137 nsIIDRef riid, void **result)
139 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
141 if(IsEqualGUID(&IID_nsISupports, riid)) {
142 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
143 *result = &This->nsIDOMEventListener_iface;
144 }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
145 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
146 *result = &This->nsIDOMEventListener_iface;
147 }else {
148 *result = NULL;
149 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
150 return NS_NOINTERFACE;
153 nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
154 return NS_OK;
157 static nsrefcnt NSAPI XMLHttpReqEventListener_AddRef(nsIDOMEventListener *iface)
159 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
160 LONG ref = InterlockedIncrement(&This->ref);
162 TRACE("(%p) ref=%d\n", This, ref);
164 return ref;
167 static nsrefcnt NSAPI XMLHttpReqEventListener_Release(nsIDOMEventListener *iface)
169 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
170 LONG ref = InterlockedDecrement(&This->ref);
172 TRACE("(%p) ref=%d\n", This, ref);
174 if(!ref) {
175 assert(!This->xhr);
176 heap_free(This);
179 return ref;
182 static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *event)
184 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
186 TRACE("(%p)\n", This);
188 if(!This->xhr)
189 return NS_OK;
191 call_event_handlers(NULL, NULL, &This->xhr->event_target, NULL, EVENTID_READYSTATECHANGE,
192 (IDispatch*)&This->xhr->IHTMLXMLHttpRequest_iface);
193 return NS_OK;
196 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl = {
197 XMLHttpReqEventListener_QueryInterface,
198 XMLHttpReqEventListener_AddRef,
199 XMLHttpReqEventListener_Release,
200 XMLHttpReqEventListener_HandleEvent
203 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
205 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
208 static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *iface, REFIID riid, void **ppv)
210 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
212 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
214 if(IsEqualGUID(&IID_IUnknown, riid)) {
215 *ppv = &This->IHTMLXMLHttpRequest_iface;
216 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
217 *ppv = &This->IHTMLXMLHttpRequest_iface;
218 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
219 *ppv = &This->IHTMLXMLHttpRequest_iface;
220 }else if(dispex_query_interface(&This->event_target.dispex, riid, ppv)) {
221 return *ppv ? S_OK : E_NOINTERFACE;
222 }else {
223 *ppv = NULL;
224 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
225 return E_NOINTERFACE;
228 IUnknown_AddRef((IUnknown*)*ppv);
229 return S_OK;
232 static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
234 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
235 LONG ref = InterlockedIncrement(&This->ref);
237 TRACE("(%p) ref=%d\n", This, ref);
239 return ref;
242 static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
244 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
245 LONG ref = InterlockedDecrement(&This->ref);
247 TRACE("(%p) ref=%d\n", This, ref);
249 if(!ref) {
250 if(This->event_listener)
251 detach_xhr_event_listener(This->event_listener);
252 release_dispex(&This->event_target.dispex);
253 nsIXMLHttpRequest_Release(This->nsxhr);
254 heap_free(This);
257 return ref;
260 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest *iface, UINT *pctinfo)
262 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
263 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
266 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest *iface, UINT iTInfo,
267 LCID lcid, ITypeInfo **ppTInfo)
269 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
271 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
274 static HRESULT WINAPI HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
275 LCID lcid, DISPID *rgDispId)
277 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
279 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
280 lcid, rgDispId);
283 static HRESULT WINAPI HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
284 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
286 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
288 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
289 pDispParams, pVarResult, pExcepInfo, puArgErr);
292 static HRESULT WINAPI HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest *iface, LONG *p)
294 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
295 UINT16 val;
296 nsresult nsres;
298 TRACE("(%p)->(%p)\n", This, p);
300 if(!p)
301 return E_POINTER;
302 nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &val);
303 if(NS_FAILED(nsres)) {
304 ERR("nsIXMLHttpRequest_GetReadyState failed: %08x\n", nsres);
305 return E_FAIL;
307 *p = val;
308 return S_OK;
311 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest *iface, VARIANT *p)
313 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
314 FIXME("(%p)->(%p)\n", This, p);
315 return E_NOTIMPL;
318 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *iface, BSTR *p)
320 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
321 nsAString nsstr;
322 nsresult nsres;
324 TRACE("(%p)->(%p)\n", This, p);
326 if(!p)
327 return E_POINTER;
329 nsAString_Init(&nsstr, NULL);
330 nsres = nsIXMLHttpRequest_GetResponseText(This->nsxhr, &nsstr);
331 return return_nsstr(nsres, &nsstr, p);
334 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
336 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
337 FIXME("(%p)->(%p)\n", This, p);
338 return E_NOTIMPL;
341 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)
343 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
344 DWORD val;
345 nsresult nsres;
346 TRACE("(%p)->(%p)\n", This, p);
348 if(!p)
349 return E_POINTER;
351 nsres = nsIXMLHttpRequest_GetStatus(This->nsxhr, &val);
352 if(NS_FAILED(nsres)) {
353 ERR("nsIXMLHttpRequest_GetStatus failed: %08x\n", nsres);
354 return E_FAIL;
356 *p = val;
357 if(val == 0)
358 return E_FAIL; /* WinAPI thinks this is an error */
360 return S_OK;
363 static HRESULT WINAPI HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest *iface, BSTR *p)
365 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
366 nsACString nscstr;
367 nsresult nsres;
368 HRESULT hres;
369 LONG state;
371 TRACE("(%p)->(%p)\n", This, p);
373 if(!p)
374 return E_POINTER;
376 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
377 if(FAILED(hres))
378 return hres;
380 if(state < 2) {
381 *p = NULL;
382 return E_FAIL;
385 nsACString_Init(&nscstr, NULL);
386 nsres = nsIXMLHttpRequest_GetStatusText(This->nsxhr, &nscstr);
387 return return_nscstr(nsres, &nscstr, p);
390 static HRESULT WINAPI HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT v)
392 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
394 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
396 return set_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, &v);
399 static HRESULT WINAPI HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT *p)
401 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
403 TRACE("(%p)->(%p)\n", This, p);
405 return get_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, p);
408 static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
410 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
411 nsresult nsres;
413 TRACE("(%p)->()\n", This);
415 nsres = nsIXMLHttpRequest_SlowAbort(This->nsxhr);
416 if(NS_FAILED(nsres)) {
417 ERR("nsIXMLHttpRequest_SlowAbort failed: %08x\n", nsres);
418 return E_FAIL;
421 return S_OK;
424 static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword)
426 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
427 nsACString method, url;
428 nsAString user, password;
429 nsresult nsres;
430 HRESULT hres;
432 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword));
434 if(V_VT(&varAsync) != VT_BOOL) {
435 FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync));
436 return E_FAIL;
439 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
440 * synchronous requests on the main thread have been deprecated due to the negative
441 * effects to the user experience.
443 if(!V_BOOL(&varAsync)) {
444 FIXME("Synchronous request is not supported yet\n");
445 return E_FAIL;
448 hres = variant_to_nsastr(varUser, &user);
449 if(FAILED(hres))
450 return hres;
451 hres = variant_to_nsastr(varPassword, &password);
452 if(FAILED(hres)) {
453 nsAString_Finish(&user);
454 return hres;
457 hres = bstr_to_nsacstr(bstrMethod, &method);
458 if(FAILED(hres)) {
459 nsAString_Finish(&user);
460 nsAString_Finish(&password);
461 return hres;
463 hres = bstr_to_nsacstr(bstrUrl, &url);
464 if(FAILED(hres)) {
465 nsAString_Finish(&user);
466 nsAString_Finish(&password);
467 nsACString_Finish(&method);
468 return hres;
471 nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE,
472 &user, &password, 0);
474 nsACString_Finish(&method);
475 nsACString_Finish(&url);
476 nsAString_Finish(&user);
477 nsAString_Finish(&password);
479 if(NS_FAILED(nsres)) {
480 ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres);
481 return E_FAIL;
484 return S_OK;
487 static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)
489 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
490 nsresult nsres;
492 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varBody));
494 switch(V_VT(&varBody)) {
495 case VT_NULL:
496 case VT_EMPTY:
497 case VT_ERROR:
498 break;
499 default:
500 FIXME("varBody(%s) unsupported\n", debugstr_variant(&varBody));
501 return E_FAIL;
504 nsres = nsIXMLHttpRequest_Send(This->nsxhr, NULL);
506 if(NS_FAILED(nsres)) {
507 ERR("nsIXMLHttpRequest_Send failed: %08x\n", nsres);
508 return E_FAIL;
511 return S_OK;
514 static HRESULT WINAPI HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest *iface, BSTR *p)
516 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
517 nsACString nscstr;
518 nsresult nsres;
519 HRESULT hres;
520 LONG state;
522 TRACE("(%p)->(%p)\n", This, p);
524 if(!p)
525 return E_POINTER;
527 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
528 if(FAILED(hres))
529 return hres;
531 if(state < 2) {
532 *p = NULL;
533 return E_FAIL;
536 nsACString_Init(&nscstr, NULL);
537 nsres = nsIXMLHttpRequest_GetAllResponseHeaders(This->nsxhr, &nscstr);
538 return return_nscstr(nsres, &nscstr, p);
541 static HRESULT WINAPI HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR *p)
543 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
544 nsACString header, ret;
545 char *cstr;
546 nsresult nsres;
547 HRESULT hres;
548 LONG state;
549 TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrHeader), p);
551 if(!p)
552 return E_POINTER;
553 if(!bstrHeader)
554 return E_INVALIDARG;
556 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
557 if(FAILED(hres))
558 return hres;
560 if(state < 2) {
561 *p = NULL;
562 return E_FAIL;
565 cstr = heap_strdupWtoU(bstrHeader);
566 nsACString_InitDepend(&header, cstr);
567 nsACString_Init(&ret, NULL);
569 nsres = nsIXMLHttpRequest_GetResponseHeader(This->nsxhr, &header, &ret);
571 nsACString_Finish(&header);
572 heap_free(cstr);
573 return return_nscstr(nsres, &ret, p);
576 static HRESULT WINAPI HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR bstrValue)
578 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
579 FIXME("(%p)->(%s %s)\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
580 return E_NOTIMPL;
583 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
584 HTMLXMLHttpRequest_QueryInterface,
585 HTMLXMLHttpRequest_AddRef,
586 HTMLXMLHttpRequest_Release,
587 HTMLXMLHttpRequest_GetTypeInfoCount,
588 HTMLXMLHttpRequest_GetTypeInfo,
589 HTMLXMLHttpRequest_GetIDsOfNames,
590 HTMLXMLHttpRequest_Invoke,
591 HTMLXMLHttpRequest_get_readyState,
592 HTMLXMLHttpRequest_get_responseBody,
593 HTMLXMLHttpRequest_get_responseText,
594 HTMLXMLHttpRequest_get_responseXML,
595 HTMLXMLHttpRequest_get_status,
596 HTMLXMLHttpRequest_get_statusText,
597 HTMLXMLHttpRequest_put_onreadystatechange,
598 HTMLXMLHttpRequest_get_onreadystatechange,
599 HTMLXMLHttpRequest_abort,
600 HTMLXMLHttpRequest_open,
601 HTMLXMLHttpRequest_send,
602 HTMLXMLHttpRequest_getAllResponseHeaders,
603 HTMLXMLHttpRequest_getResponseHeader,
604 HTMLXMLHttpRequest_setRequestHeader
607 static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
609 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
612 static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, int eid)
614 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
615 nsIDOMEventTarget *nstarget;
616 nsAString type_str;
617 nsresult nsres;
619 static const WCHAR readystatechangeW[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
621 TRACE("(%p)\n", This);
623 assert(eid == EVENTID_READYSTATECHANGE);
625 if(This->event_listener)
626 return;
628 This->event_listener = heap_alloc(sizeof(*This->event_listener));
629 if(!This->event_listener)
630 return;
632 This->event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
633 This->event_listener->ref = 1;
634 This->event_listener->xhr = This;
636 nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
637 assert(nsres == NS_OK);
639 nsAString_InitDepend(&type_str, readystatechangeW);
640 nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
641 nsAString_Finish(&type_str);
642 nsIDOMEventTarget_Release(nstarget);
643 if(NS_FAILED(nsres))
644 ERR("AddEventListener failed: %08x\n", nsres);
647 static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl = {
648 NULL,
649 NULL,
650 NULL,
651 NULL,
652 NULL,
653 HTMLXMLHttpRequest_bind_event
656 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
657 IHTMLXMLHttpRequest_tid,
660 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
661 &HTMLXMLHttpRequest_dispex_vtbl,
662 DispHTMLXMLHttpRequest_tid,
663 NULL,
664 HTMLXMLHttpRequest_iface_tids
668 /* IHTMLXMLHttpRequestFactory */
669 static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface)
671 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface);
674 static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory *iface, REFIID riid, void **ppv)
676 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
678 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
680 if(IsEqualGUID(&IID_IUnknown, riid)) {
681 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
682 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
683 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
684 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) {
685 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
686 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
687 return *ppv ? S_OK : E_NOINTERFACE;
688 }else {
689 *ppv = NULL;
690 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
691 return E_NOINTERFACE;
694 IUnknown_AddRef((IUnknown*)*ppv);
695 return S_OK;
698 static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface)
700 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
701 LONG ref = InterlockedIncrement(&This->ref);
703 TRACE("(%p) ref=%d\n", This, ref);
705 return ref;
708 static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface)
710 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
711 LONG ref = InterlockedDecrement(&This->ref);
713 TRACE("(%p) ref=%d\n", This, ref);
715 if(!ref) {
716 release_dispex(&This->dispex);
717 heap_free(This);
720 return ref;
723 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory *iface, UINT *pctinfo)
725 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
726 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
729 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory *iface, UINT iTInfo,
730 LCID lcid, ITypeInfo **ppTInfo)
732 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
734 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
737 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
738 LCID lcid, DISPID *rgDispId)
740 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
742 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
743 lcid, rgDispId);
746 static HRESULT WINAPI HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
747 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
749 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
751 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
752 pDispParams, pVarResult, pExcepInfo, puArgErr);
755 static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p)
757 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
758 HTMLXMLHttpRequest *ret;
759 nsIXMLHttpRequest *nsxhr;
761 TRACE("(%p)->(%p)\n", This, p);
763 nsxhr = create_nsxhr(This->window->base.outer_window->nswindow);
764 if(!nsxhr)
765 return E_FAIL;
767 ret = heap_alloc_zero(sizeof(*ret));
768 if(!ret) {
769 nsIXMLHttpRequest_Release(nsxhr);
770 return E_OUTOFMEMORY;
772 ret->nsxhr = nsxhr;
774 ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
775 init_dispex(&ret->event_target.dispex, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
776 &HTMLXMLHttpRequest_dispex);
777 ret->ref = 1;
779 *p = &ret->IHTMLXMLHttpRequest_iface;
780 return S_OK;
783 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = {
784 HTMLXMLHttpRequestFactory_QueryInterface,
785 HTMLXMLHttpRequestFactory_AddRef,
786 HTMLXMLHttpRequestFactory_Release,
787 HTMLXMLHttpRequestFactory_GetTypeInfoCount,
788 HTMLXMLHttpRequestFactory_GetTypeInfo,
789 HTMLXMLHttpRequestFactory_GetIDsOfNames,
790 HTMLXMLHttpRequestFactory_Invoke,
791 HTMLXMLHttpRequestFactory_create
794 static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = {
795 IHTMLXMLHttpRequestFactory_tid,
798 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
799 NULL,
800 IHTMLXMLHttpRequestFactory_tid,
801 NULL,
802 HTMLXMLHttpRequestFactory_iface_tids
805 HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr)
807 HTMLXMLHttpRequestFactory *ret;
809 ret = heap_alloc(sizeof(*ret));
810 if(!ret)
811 return E_OUTOFMEMORY;
813 ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl;
814 ret->ref = 1;
815 ret->window = window;
817 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface,
818 &HTMLXMLHttpRequestFactory_dispex);
820 *ret_ptr = ret;
821 return S_OK;