[SHELL32] SHChangeNotify: Add drive, remove drive (#6782)
[reactos.git] / dll / win32 / mshtml / xmlhttprequest.c
1 /*
2 * Copyright 2015 Zhenbo Li
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "mshtml_private.h"
20
21 static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str)
22 {
23 char *cstr = heap_strdupWtoU(bstr);
24 if(!cstr)
25 return E_OUTOFMEMORY;
26 nsACString_Init(str, cstr);
27 heap_free(cstr);
28 return S_OK;
29 }
30
31 static HRESULT variant_to_nsastr(VARIANT var, nsAString *ret)
32 {
33 switch(V_VT(&var)) {
34 case VT_NULL:
35 case VT_ERROR:
36 case VT_EMPTY:
37 nsAString_Init(ret, NULL);
38 return S_OK;
39 case VT_BSTR:
40 nsAString_InitDepend(ret, V_BSTR(&var));
41 return S_OK;
42 default:
43 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var));
44 return E_INVALIDARG;
45 }
46 }
47
48 static HRESULT return_nscstr(nsresult nsres, nsACString *nscstr, BSTR *p)
49 {
50 const char *str;
51 int len;
52
53 if(NS_FAILED(nsres)) {
54 ERR("failed: %08x\n", nsres);
55 nsACString_Finish(nscstr);
56 return E_FAIL;
57 }
58
59 nsACString_GetData(nscstr, &str);
60
61 if(*str) {
62 len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
63 *p = SysAllocStringLen(NULL, len);
64 if(!*p) {
65 nsACString_Finish(nscstr);
66 return E_OUTOFMEMORY;
67 }
68 MultiByteToWideChar(CP_UTF8, 0, str, -1, *p, len);
69 }else {
70 *p = NULL;
71 }
72
73 nsACString_Finish(nscstr);
74 return S_OK;
75 }
76
77 typedef struct XMLHttpReqEventListener XMLHttpReqEventListener;
78
79 typedef struct {
80 EventTarget event_target;
81 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
82 LONG ref;
83 nsIXMLHttpRequest *nsxhr;
84 XMLHttpReqEventListener *event_listener;
85 } HTMLXMLHttpRequest;
86
87 struct XMLHttpReqEventListener {
88 nsIDOMEventListener nsIDOMEventListener_iface;
89 LONG ref;
90 HTMLXMLHttpRequest *xhr;
91 };
92
93 static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
94 {
95 nsIDOMEventTarget *event_target;
96 nsAString str;
97 nsresult nsres;
98
99 static const WCHAR readystatechangeW[] =
100 {'o','n','r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
101
102 nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
103 assert(nsres == NS_OK);
104
105 nsAString_InitDepend(&str, readystatechangeW);
106 nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
107 nsAString_Finish(&str);
108 nsIDOMEventTarget_Release(event_target);
109
110 event_listener->xhr->event_listener = NULL;
111 event_listener->xhr = NULL;
112 nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
113 }
114
115
116 static inline XMLHttpReqEventListener *impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
117 {
118 return CONTAINING_RECORD(iface, XMLHttpReqEventListener, nsIDOMEventListener_iface);
119 }
120
121 static nsresult NSAPI XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener *iface,
122 nsIIDRef riid, void **result)
123 {
124 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
125
126 if(IsEqualGUID(&IID_nsISupports, riid)) {
127 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
128 *result = &This->nsIDOMEventListener_iface;
129 }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
130 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
131 *result = &This->nsIDOMEventListener_iface;
132 }else {
133 *result = NULL;
134 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
135 return NS_NOINTERFACE;
136 }
137
138 nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
139 return NS_OK;
140 }
141
142 static nsrefcnt NSAPI XMLHttpReqEventListener_AddRef(nsIDOMEventListener *iface)
143 {
144 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
145 LONG ref = InterlockedIncrement(&This->ref);
146
147 TRACE("(%p) ref=%d\n", This, ref);
148
149 return ref;
150 }
151
152 static nsrefcnt NSAPI XMLHttpReqEventListener_Release(nsIDOMEventListener *iface)
153 {
154 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
155 LONG ref = InterlockedDecrement(&This->ref);
156
157 TRACE("(%p) ref=%d\n", This, ref);
158
159 if(!ref) {
160 assert(!This->xhr);
161 heap_free(This);
162 }
163
164 return ref;
165 }
166
167 static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *event)
168 {
169 XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
170
171 TRACE("(%p)\n", This);
172
173 if(!This->xhr)
174 return NS_OK;
175
176 call_event_handlers(NULL, NULL, &This->xhr->event_target, NULL, EVENTID_READYSTATECHANGE,
177 (IDispatch*)&This->xhr->IHTMLXMLHttpRequest_iface);
178 return NS_OK;
179 }
180
181 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl = {
182 XMLHttpReqEventListener_QueryInterface,
183 XMLHttpReqEventListener_AddRef,
184 XMLHttpReqEventListener_Release,
185 XMLHttpReqEventListener_HandleEvent
186 };
187
188 static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
189 {
190 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
191 }
192
193 static HRESULT WINAPI HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest *iface, REFIID riid, void **ppv)
194 {
195 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
196
197 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
198
199 if(IsEqualGUID(&IID_IUnknown, riid)) {
200 *ppv = &This->IHTMLXMLHttpRequest_iface;
201 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
202 *ppv = &This->IHTMLXMLHttpRequest_iface;
203 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest, riid)) {
204 *ppv = &This->IHTMLXMLHttpRequest_iface;
205 }else if(dispex_query_interface(&This->event_target.dispex, riid, ppv)) {
206 return *ppv ? S_OK : E_NOINTERFACE;
207 }else {
208 *ppv = NULL;
209 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
210 return E_NOINTERFACE;
211 }
212
213 IUnknown_AddRef((IUnknown*)*ppv);
214 return S_OK;
215 }
216
217 static ULONG WINAPI HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest *iface)
218 {
219 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
220 LONG ref = InterlockedIncrement(&This->ref);
221
222 TRACE("(%p) ref=%d\n", This, ref);
223
224 return ref;
225 }
226
227 static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
228 {
229 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
230 LONG ref = InterlockedDecrement(&This->ref);
231
232 TRACE("(%p) ref=%d\n", This, ref);
233
234 if(!ref) {
235 if(This->event_listener)
236 detach_xhr_event_listener(This->event_listener);
237 release_dispex(&This->event_target.dispex);
238 nsIXMLHttpRequest_Release(This->nsxhr);
239 heap_free(This);
240 }
241
242 return ref;
243 }
244
245 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest *iface, UINT *pctinfo)
246 {
247 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
248 return IDispatchEx_GetTypeInfoCount(&This->event_target.dispex.IDispatchEx_iface, pctinfo);
249 }
250
251 static HRESULT WINAPI HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest *iface, UINT iTInfo,
252 LCID lcid, ITypeInfo **ppTInfo)
253 {
254 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
255
256 return IDispatchEx_GetTypeInfo(&This->event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
257 }
258
259 static HRESULT WINAPI HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
260 LCID lcid, DISPID *rgDispId)
261 {
262 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
263
264 return IDispatchEx_GetIDsOfNames(&This->event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
265 lcid, rgDispId);
266 }
267
268 static HRESULT WINAPI HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
269 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
270 {
271 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
272
273 return IDispatchEx_Invoke(&This->event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
274 pDispParams, pVarResult, pExcepInfo, puArgErr);
275 }
276
277 static HRESULT WINAPI HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest *iface, LONG *p)
278 {
279 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
280 UINT16 val;
281 nsresult nsres;
282
283 TRACE("(%p)->(%p)\n", This, p);
284
285 if(!p)
286 return E_POINTER;
287 nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &val);
288 if(NS_FAILED(nsres)) {
289 ERR("nsIXMLHttpRequest_GetReadyState failed: %08x\n", nsres);
290 return E_FAIL;
291 }
292 *p = val;
293 return S_OK;
294 }
295
296 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest *iface, VARIANT *p)
297 {
298 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
299 FIXME("(%p)->(%p)\n", This, p);
300 return E_NOTIMPL;
301 }
302
303 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest *iface, BSTR *p)
304 {
305 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
306 nsAString nsstr;
307 nsresult nsres;
308
309 TRACE("(%p)->(%p)\n", This, p);
310
311 if(!p)
312 return E_POINTER;
313
314 nsAString_Init(&nsstr, NULL);
315 nsres = nsIXMLHttpRequest_GetResponseText(This->nsxhr, &nsstr);
316 return return_nsstr(nsres, &nsstr, p);
317 }
318
319 static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *iface, IDispatch **p)
320 {
321 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
322 FIXME("(%p)->(%p)\n", This, p);
323 return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest *iface, LONG *p)
327 {
328 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
329 DWORD val;
330 nsresult nsres;
331 TRACE("(%p)->(%p)\n", This, p);
332
333 if(!p)
334 return E_POINTER;
335
336 nsres = nsIXMLHttpRequest_GetStatus(This->nsxhr, &val);
337 if(NS_FAILED(nsres)) {
338 ERR("nsIXMLHttpRequest_GetStatus failed: %08x\n", nsres);
339 return E_FAIL;
340 }
341 *p = val;
342 if(val == 0)
343 return E_FAIL; /* WinAPI thinks this is an error */
344
345 return S_OK;
346 }
347
348 static HRESULT WINAPI HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest *iface, BSTR *p)
349 {
350 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
351 nsACString nscstr;
352 nsresult nsres;
353 HRESULT hres;
354 LONG state;
355
356 TRACE("(%p)->(%p)\n", This, p);
357
358 if(!p)
359 return E_POINTER;
360
361 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
362 if(FAILED(hres))
363 return hres;
364
365 if(state < 2) {
366 *p = NULL;
367 return E_FAIL;
368 }
369
370 nsACString_Init(&nscstr, NULL);
371 nsres = nsIXMLHttpRequest_GetStatusText(This->nsxhr, &nscstr);
372 return return_nscstr(nsres, &nscstr, p);
373 }
374
375 static HRESULT WINAPI HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT v)
376 {
377 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
378
379 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
380
381 return set_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, &v);
382 }
383
384 static HRESULT WINAPI HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest *iface, VARIANT *p)
385 {
386 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
387
388 TRACE("(%p)->(%p)\n", This, p);
389
390 return get_event_handler(&This->event_target, EVENTID_READYSTATECHANGE, p);
391 }
392
393 static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
394 {
395 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
396 nsresult nsres;
397
398 TRACE("(%p)->()\n", This);
399
400 nsres = nsIXMLHttpRequest_SlowAbort(This->nsxhr);
401 if(NS_FAILED(nsres)) {
402 ERR("nsIXMLHttpRequest_SlowAbort failed: %08x\n", nsres);
403 return E_FAIL;
404 }
405
406 return S_OK;
407 }
408
409 static HRESULT WINAPI HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest *iface, BSTR bstrMethod, BSTR bstrUrl, VARIANT varAsync, VARIANT varUser, VARIANT varPassword)
410 {
411 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
412 nsACString method, url;
413 nsAString user, password;
414 nsresult nsres;
415 HRESULT hres;
416
417 TRACE("(%p)->(%s %s %s %s %s)\n", This, debugstr_w(bstrMethod), debugstr_w(bstrUrl), debugstr_variant(&varAsync), debugstr_variant(&varUser), debugstr_variant(&varPassword));
418
419 if(V_VT(&varAsync) != VT_BOOL) {
420 FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync));
421 return E_FAIL;
422 }
423
424 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
425 * synchronous requests on the main thread have been deprecated due to the negative
426 * effects to the user experience.
427 */
428 if(!V_BOOL(&varAsync)) {
429 FIXME("Synchronous request is not supported yet\n");
430 return E_FAIL;
431 }
432
433 hres = variant_to_nsastr(varUser, &user);
434 if(FAILED(hres))
435 return hres;
436 hres = variant_to_nsastr(varPassword, &password);
437 if(FAILED(hres)) {
438 nsAString_Finish(&user);
439 return hres;
440 }
441
442 hres = bstr_to_nsacstr(bstrMethod, &method);
443 if(FAILED(hres)) {
444 nsAString_Finish(&user);
445 nsAString_Finish(&password);
446 return hres;
447 }
448 hres = bstr_to_nsacstr(bstrUrl, &url);
449 if(FAILED(hres)) {
450 nsAString_Finish(&user);
451 nsAString_Finish(&password);
452 nsACString_Finish(&method);
453 return hres;
454 }
455
456 nsres = nsIXMLHttpRequest_Open(This->nsxhr, &method, &url, TRUE,
457 &user, &password, 0);
458
459 nsACString_Finish(&method);
460 nsACString_Finish(&url);
461 nsAString_Finish(&user);
462 nsAString_Finish(&password);
463
464 if(NS_FAILED(nsres)) {
465 ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres);
466 return E_FAIL;
467 }
468
469 return S_OK;
470 }
471
472 static HRESULT WINAPI HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest *iface, VARIANT varBody)
473 {
474 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
475 nsresult nsres;
476
477 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varBody));
478
479 switch(V_VT(&varBody)) {
480 case VT_NULL:
481 case VT_EMPTY:
482 case VT_ERROR:
483 break;
484 default:
485 FIXME("varBody(%s) unsupported\n", debugstr_variant(&varBody));
486 return E_FAIL;
487 }
488
489 nsres = nsIXMLHttpRequest_Send(This->nsxhr, NULL);
490
491 if(NS_FAILED(nsres)) {
492 ERR("nsIXMLHttpRequest_Send failed: %08x\n", nsres);
493 return E_FAIL;
494 }
495
496 return S_OK;
497 }
498
499 static HRESULT WINAPI HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest *iface, BSTR *p)
500 {
501 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
502 nsACString nscstr;
503 nsresult nsres;
504 HRESULT hres;
505 LONG state;
506
507 TRACE("(%p)->(%p)\n", This, p);
508
509 if(!p)
510 return E_POINTER;
511
512 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
513 if(FAILED(hres))
514 return hres;
515
516 if(state < 2) {
517 *p = NULL;
518 return E_FAIL;
519 }
520
521 nsACString_Init(&nscstr, NULL);
522 nsres = nsIXMLHttpRequest_GetAllResponseHeaders(This->nsxhr, &nscstr);
523 return return_nscstr(nsres, &nscstr, p);
524 }
525
526 static HRESULT WINAPI HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR *p)
527 {
528 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
529 nsACString header, ret;
530 char *cstr;
531 nsresult nsres;
532 HRESULT hres;
533 LONG state;
534 TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrHeader), p);
535
536 if(!p)
537 return E_POINTER;
538 if(!bstrHeader)
539 return E_INVALIDARG;
540
541 hres = IHTMLXMLHttpRequest_get_readyState(iface, &state);
542 if(FAILED(hres))
543 return hres;
544
545 if(state < 2) {
546 *p = NULL;
547 return E_FAIL;
548 }
549
550 cstr = heap_strdupWtoU(bstrHeader);
551 nsACString_InitDepend(&header, cstr);
552 nsACString_Init(&ret, NULL);
553
554 nsres = nsIXMLHttpRequest_GetResponseHeader(This->nsxhr, &header, &ret);
555
556 nsACString_Finish(&header);
557 heap_free(cstr);
558 return return_nscstr(nsres, &ret, p);
559 }
560
561 static HRESULT WINAPI HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest *iface, BSTR bstrHeader, BSTR bstrValue)
562 {
563 HTMLXMLHttpRequest *This = impl_from_IHTMLXMLHttpRequest(iface);
564 FIXME("(%p)->(%s %s)\n", This, debugstr_w(bstrHeader), debugstr_w(bstrValue));
565 return E_NOTIMPL;
566 }
567
568 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl = {
569 HTMLXMLHttpRequest_QueryInterface,
570 HTMLXMLHttpRequest_AddRef,
571 HTMLXMLHttpRequest_Release,
572 HTMLXMLHttpRequest_GetTypeInfoCount,
573 HTMLXMLHttpRequest_GetTypeInfo,
574 HTMLXMLHttpRequest_GetIDsOfNames,
575 HTMLXMLHttpRequest_Invoke,
576 HTMLXMLHttpRequest_get_readyState,
577 HTMLXMLHttpRequest_get_responseBody,
578 HTMLXMLHttpRequest_get_responseText,
579 HTMLXMLHttpRequest_get_responseXML,
580 HTMLXMLHttpRequest_get_status,
581 HTMLXMLHttpRequest_get_statusText,
582 HTMLXMLHttpRequest_put_onreadystatechange,
583 HTMLXMLHttpRequest_get_onreadystatechange,
584 HTMLXMLHttpRequest_abort,
585 HTMLXMLHttpRequest_open,
586 HTMLXMLHttpRequest_send,
587 HTMLXMLHttpRequest_getAllResponseHeaders,
588 HTMLXMLHttpRequest_getResponseHeader,
589 HTMLXMLHttpRequest_setRequestHeader
590 };
591
592 static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
593 {
594 return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
595 }
596
597 static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, int eid)
598 {
599 HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
600 nsIDOMEventTarget *nstarget;
601 nsAString type_str;
602 nsresult nsres;
603
604 static const WCHAR readystatechangeW[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
605
606 TRACE("(%p)\n", This);
607
608 assert(eid == EVENTID_READYSTATECHANGE);
609
610 if(This->event_listener)
611 return;
612
613 This->event_listener = heap_alloc(sizeof(*This->event_listener));
614 if(!This->event_listener)
615 return;
616
617 This->event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
618 This->event_listener->ref = 1;
619 This->event_listener->xhr = This;
620
621 nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
622 assert(nsres == NS_OK);
623
624 nsAString_InitDepend(&type_str, readystatechangeW);
625 nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
626 nsAString_Finish(&type_str);
627 nsIDOMEventTarget_Release(nstarget);
628 if(NS_FAILED(nsres))
629 ERR("AddEventListener failed: %08x\n", nsres);
630 }
631
632 static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl = {
633 NULL,
634 NULL,
635 NULL,
636 NULL,
637 NULL,
638 HTMLXMLHttpRequest_bind_event
639 };
640
641 static const tid_t HTMLXMLHttpRequest_iface_tids[] = {
642 IHTMLXMLHttpRequest_tid,
643 0
644 };
645 static dispex_static_data_t HTMLXMLHttpRequest_dispex = {
646 &HTMLXMLHttpRequest_dispex_vtbl,
647 DispHTMLXMLHttpRequest_tid,
648 NULL,
649 HTMLXMLHttpRequest_iface_tids
650 };
651
652
653 /* IHTMLXMLHttpRequestFactory */
654 static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface)
655 {
656 return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface);
657 }
658
659 static HRESULT WINAPI HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory *iface, REFIID riid, void **ppv)
660 {
661 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
662
663 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
664
665 if(IsEqualGUID(&IID_IUnknown, riid)) {
666 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
667 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
668 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
669 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) {
670 *ppv = &This->IHTMLXMLHttpRequestFactory_iface;
671 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
672 return *ppv ? S_OK : E_NOINTERFACE;
673 }else {
674 *ppv = NULL;
675 WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
676 return E_NOINTERFACE;
677 }
678
679 IUnknown_AddRef((IUnknown*)*ppv);
680 return S_OK;
681 }
682
683 static ULONG WINAPI HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory *iface)
684 {
685 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
686 LONG ref = InterlockedIncrement(&This->ref);
687
688 TRACE("(%p) ref=%d\n", This, ref);
689
690 return ref;
691 }
692
693 static ULONG WINAPI HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory *iface)
694 {
695 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
696 LONG ref = InterlockedDecrement(&This->ref);
697
698 TRACE("(%p) ref=%d\n", This, ref);
699
700 if(!ref) {
701 release_dispex(&This->dispex);
702 heap_free(This);
703 }
704
705 return ref;
706 }
707
708 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory *iface, UINT *pctinfo)
709 {
710 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
711 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
712 }
713
714 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory *iface, UINT iTInfo,
715 LCID lcid, ITypeInfo **ppTInfo)
716 {
717 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
718
719 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
720 }
721
722 static HRESULT WINAPI HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames,
723 LCID lcid, DISPID *rgDispId)
724 {
725 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
726
727 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
728 lcid, rgDispId);
729 }
730
731 static HRESULT WINAPI HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
732 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
733 {
734 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
735
736 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
737 pDispParams, pVarResult, pExcepInfo, puArgErr);
738 }
739
740 static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p)
741 {
742 HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
743 HTMLXMLHttpRequest *ret;
744 nsIXMLHttpRequest *nsxhr;
745
746 TRACE("(%p)->(%p)\n", This, p);
747
748 nsxhr = create_nsxhr(This->window->base.outer_window->nswindow);
749 if(!nsxhr)
750 return E_FAIL;
751
752 ret = heap_alloc_zero(sizeof(*ret));
753 if(!ret) {
754 nsIXMLHttpRequest_Release(nsxhr);
755 return E_OUTOFMEMORY;
756 }
757 ret->nsxhr = nsxhr;
758
759 ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
760 init_dispex(&ret->event_target.dispex, (IUnknown*)&ret->IHTMLXMLHttpRequest_iface,
761 &HTMLXMLHttpRequest_dispex);
762 ret->ref = 1;
763
764 *p = &ret->IHTMLXMLHttpRequest_iface;
765 return S_OK;
766 }
767
768 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = {
769 HTMLXMLHttpRequestFactory_QueryInterface,
770 HTMLXMLHttpRequestFactory_AddRef,
771 HTMLXMLHttpRequestFactory_Release,
772 HTMLXMLHttpRequestFactory_GetTypeInfoCount,
773 HTMLXMLHttpRequestFactory_GetTypeInfo,
774 HTMLXMLHttpRequestFactory_GetIDsOfNames,
775 HTMLXMLHttpRequestFactory_Invoke,
776 HTMLXMLHttpRequestFactory_create
777 };
778
779 static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = {
780 IHTMLXMLHttpRequestFactory_tid,
781 0
782 };
783 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
784 NULL,
785 IHTMLXMLHttpRequestFactory_tid,
786 NULL,
787 HTMLXMLHttpRequestFactory_iface_tids
788 };
789
790 HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr)
791 {
792 HTMLXMLHttpRequestFactory *ret;
793
794 ret = heap_alloc(sizeof(*ret));
795 if(!ret)
796 return E_OUTOFMEMORY;
797
798 ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl;
799 ret->ref = 1;
800 ret->window = window;
801
802 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLXMLHttpRequestFactory_iface,
803 &HTMLXMLHttpRequestFactory_dispex);
804
805 *ret_ptr = ret;
806 return S_OK;
807 }