07b20e477cee0769bb4afbb63555faa92cd25b30
[reactos.git] / reactos / dll / win32 / mshtml / nsio.c
1 /*
2 * Copyright 2006-2010 Jacek Caban for CodeWeavers
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 #define WIN32_NO_STATUS
20 #define _INC_WINDOWS
21
22 #include <config.h>
23
24 #include <stdarg.h>
25 #include <assert.h>
26
27 #define COBJMACROS
28
29 #include <windef.h>
30 #include <winbase.h>
31 //#include "winuser.h"
32 #include <winreg.h>
33 #include <ole2.h>
34 #include <shlguid.h>
35 #include <wininet.h>
36 #include <shlwapi.h>
37
38 #include <wine/debug.h>
39
40 #include "mshtml_private.h"
41 #include "binding.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
44
45 #define NS_IOSERVICE_CLASSNAME "nsIOService"
46 #define NS_IOSERVICE_CONTRACTID "@mozilla.org/network/io-service;1"
47
48 static const IID NS_IOSERVICE_CID =
49 {0x9ac9e770, 0x18bc, 0x11d3, {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
50 static const IID IID_nsWineURI =
51 {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};
52
53 static nsIIOService *nsio = NULL;
54 static nsINetUtil *net_util;
55
56 static const char *request_method_strings[] = {"GET", "PUT", "POST"};
57
58 struct nsWineURI {
59 nsIFileURL nsIFileURL_iface; /* For non-file URL objects, it's just nsIURL */
60 nsIStandardURL nsIStandardURL_iface;
61
62 LONG ref;
63
64 NSContainer *container;
65 windowref_t *window_ref;
66 nsChannelBSC *channel_bsc;
67 IUri *uri;
68 IUriBuilder *uri_builder;
69 char *origin_charset;
70 BOOL is_doc_uri;
71 BOOL is_mutable;
72 DWORD scheme;
73 };
74
75 static BOOL ensure_uri(nsWineURI *This)
76 {
77 HRESULT hres;
78
79 assert(This->uri || This->uri_builder);
80
81 if(!This->uri) {
82 hres = IUriBuilder_CreateUriSimple(This->uri_builder, 0, 0, &This->uri);
83 if(FAILED(hres)) {
84 WARN("CreateUriSimple failed: %08x\n", hres);
85 return FALSE;
86 }
87 }
88
89 return TRUE;
90 }
91
92 IUri *nsuri_get_uri(nsWineURI *nsuri)
93 {
94 if(!ensure_uri(nsuri))
95 return NULL;
96
97 IUri_AddRef(nsuri->uri);
98 return nsuri->uri;
99 }
100
101 IUri *get_uri_nofrag(IUri *uri)
102 {
103 IUriBuilder *uri_builder;
104 IUri *ret;
105 BOOL b;
106 HRESULT hres;
107
108 hres = IUri_HasProperty(uri, Uri_PROPERTY_FRAGMENT, &b);
109 if(SUCCEEDED(hres) && !b) {
110 IUri_AddRef(uri);
111 return uri;
112 }
113
114 hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
115 if(FAILED(hres))
116 return NULL;
117
118 hres = IUriBuilder_RemoveProperties(uri_builder, Uri_HAS_FRAGMENT);
119 if(SUCCEEDED(hres))
120 hres = IUriBuilder_CreateUriSimple(uri_builder, 0, 0, &ret);
121 IUriBuilder_Release(uri_builder);
122 if(FAILED(hres))
123 return NULL;
124
125 return ret;
126 }
127
128 static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2)
129 {
130 IUri *uri_nofrag1, *uri_nofrag2;
131 BOOL ret = FALSE;
132
133 uri_nofrag1 = get_uri_nofrag(uri1);
134 if(!uri_nofrag1)
135 return FALSE;
136
137 uri_nofrag2 = get_uri_nofrag(uri2);
138 if(uri_nofrag2) {
139 IUri_IsEqual(uri_nofrag1, uri_nofrag2, &ret);
140 IUri_Release(uri_nofrag2);
141 }
142
143 IUri_Release(uri_nofrag1);
144 return ret;
145 }
146
147 static nsresult create_nsuri(IUri*,HTMLOuterWindow*,NSContainer*,const char*,nsWineURI**);
148
149 static const char *debugstr_nsacstr(const nsACString *nsstr)
150 {
151 const char *data;
152
153 nsACString_GetData(nsstr, &data);
154 return debugstr_a(data);
155 }
156
157 static nsresult return_wstr_nsacstr(nsACString *ret_str, const WCHAR *str, int len)
158 {
159 char *stra;
160 int lena;
161
162 TRACE("returning %s\n", debugstr_wn(str, len));
163
164 if(!*str) {
165 nsACString_SetData(ret_str, "");
166 return NS_OK;
167 }
168
169 lena = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
170 stra = heap_alloc(lena+1);
171 if(!stra)
172 return NS_ERROR_OUT_OF_MEMORY;
173
174 WideCharToMultiByte(CP_UTF8, 0, str, len, stra, lena, NULL, NULL);
175 stra[lena] = 0;
176
177 nsACString_SetData(ret_str, stra);
178 heap_free(stra);
179 return NS_OK;
180 }
181
182 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
183 {
184 const WCHAR *ptr = nsuri;
185
186 static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
187
188 if(!strncmpW(nsuri, wine_prefixW, sizeof(wine_prefixW)/sizeof(WCHAR)))
189 ptr += sizeof(wine_prefixW)/sizeof(WCHAR);
190
191 if(*ptr || ret_empty) {
192 *ret = SysAllocString(ptr);
193 if(!*ret)
194 return E_OUTOFMEMORY;
195 }else {
196 *ret = NULL;
197 }
198
199 TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
200 return S_OK;
201 }
202
203 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, BSTR url)
204 {
205 IOleCommandTarget *cmdtrg = NULL;
206 HRESULT hres;
207
208 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
209 if(SUCCEEDED(hres)) {
210 VARIANT varUrl, varRes;
211
212 V_VT(&varUrl) = VT_BSTR;
213 V_BSTR(&varUrl) = url;
214 V_VT(&varRes) = VT_BOOL;
215
216 hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
217
218 IOleCommandTarget_Release(cmdtrg);
219
220 if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
221 TRACE("got VARIANT_FALSE, do not load\n");
222 return FALSE;
223 }
224 }
225
226 return TRUE;
227 }
228
229 static nsresult before_async_open(nsChannel *channel, NSContainer *container, BOOL *cancel)
230 {
231 HTMLDocumentObj *doc = container->doc;
232 BSTR display_uri;
233 HRESULT hres;
234
235 if(!doc->client) {
236 *cancel = TRUE;
237 return NS_OK;
238 }
239
240 hres = IUri_GetDisplayUri(channel->uri->uri, &display_uri);
241 if(FAILED(hres))
242 return NS_ERROR_FAILURE;
243
244 if(!exec_shldocvw_67(doc, display_uri)) {
245 SysFreeString(display_uri);
246 *cancel = FALSE;
247 return NS_OK;
248 }
249
250 hres = hlink_frame_navigate(&doc->basedoc, display_uri, channel, 0, cancel);
251 SysFreeString(display_uri);
252 if(FAILED(hres))
253 *cancel = TRUE;
254 return NS_OK;
255 }
256
257 HRESULT load_nsuri(HTMLOuterWindow *window, nsWineURI *uri, nsChannelBSC *channelbsc, DWORD flags)
258 {
259 nsIWebNavigation *web_navigation;
260 nsIDocShell *doc_shell;
261 HTMLDocumentNode *doc;
262 nsresult nsres;
263
264 nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
265 if(NS_FAILED(nsres)) {
266 ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
267 return E_FAIL;
268 }
269
270 nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
271 nsIWebNavigation_Release(web_navigation);
272 if(NS_FAILED(nsres)) {
273 ERR("Could not get nsIDocShell: %08x\n", nsres);
274 return E_FAIL;
275 }
276
277 uri->channel_bsc = channelbsc;
278 doc = window->base.inner_window->doc;
279 doc->skip_mutation_notif = TRUE;
280 nsres = nsIDocShell_LoadURI(doc_shell, (nsIURI*)&uri->nsIFileURL_iface, NULL, flags, FALSE);
281 if(doc == window->base.inner_window->doc)
282 doc->skip_mutation_notif = FALSE;
283 uri->channel_bsc = NULL;
284 nsIDocShell_Release(doc_shell);
285 if(NS_FAILED(nsres)) {
286 WARN("LoadURI failed: %08x\n", nsres);
287 return E_FAIL;
288 }
289
290 return S_OK;
291 }
292
293 static void set_uri_nscontainer(nsWineURI *This, NSContainer *nscontainer)
294 {
295 if(This->container) {
296 if(This->container == nscontainer)
297 return;
298 TRACE("Changing %p -> %p\n", This->container, nscontainer);
299 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
300 }
301
302 if(nscontainer)
303 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
304 This->container = nscontainer;
305 }
306
307 static void set_uri_window(nsWineURI *This, HTMLOuterWindow *window)
308 {
309 if(This->window_ref) {
310 if(This->window_ref->window == window)
311 return;
312 TRACE("Changing %p -> %p\n", This->window_ref->window, window);
313 windowref_release(This->window_ref);
314 }
315
316 if(window) {
317 windowref_addref(window->window_ref);
318 This->window_ref = window->window_ref;
319
320 if(window->doc_obj)
321 set_uri_nscontainer(This, window->doc_obj->nscontainer);
322 }else {
323 This->window_ref = NULL;
324 }
325 }
326
327 static inline BOOL is_http_channel(nsChannel *This)
328 {
329 return This->uri->scheme == URL_SCHEME_HTTP || This->uri->scheme == URL_SCHEME_HTTPS;
330 }
331
332 static http_header_t *find_http_header(struct list *headers, const WCHAR *name, int len)
333 {
334 http_header_t *iter;
335
336 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
337 if(!strcmpiW(iter->header, name))
338 return iter;
339 }
340
341 return NULL;
342 }
343
344 static nsresult get_channel_http_header(struct list *headers, const nsACString *header_name_str,
345 nsACString *_retval)
346 {
347 const char *header_namea;
348 http_header_t *header;
349 WCHAR *header_name;
350 char *data;
351
352 nsACString_GetData(header_name_str, &header_namea);
353 header_name = heap_strdupAtoW(header_namea);
354 if(!header_name)
355 return NS_ERROR_UNEXPECTED;
356
357 header = find_http_header(headers, header_name, strlenW(header_name));
358 heap_free(header_name);
359 if(!header)
360 return NS_ERROR_NOT_AVAILABLE;
361
362 data = heap_strdupWtoA(header->data);
363 if(!data)
364 return NS_ERROR_UNEXPECTED;
365
366 TRACE("%s -> %s\n", debugstr_a(header_namea), debugstr_a(data));
367 nsACString_SetData(_retval, data);
368 heap_free(data);
369 return NS_OK;
370 }
371
372 HRESULT set_http_header(struct list *headers, const WCHAR *name, int name_len,
373 const WCHAR *value, int value_len)
374 {
375 http_header_t *header;
376
377 TRACE("%s: %s\n", debugstr_wn(name, name_len), debugstr_wn(value, value_len));
378
379 header = find_http_header(headers, name, name_len);
380 if(header) {
381 WCHAR *new_data;
382
383 new_data = heap_strndupW(value, value_len);
384 if(!new_data)
385 return E_OUTOFMEMORY;
386
387 heap_free(header->data);
388 header->data = new_data;
389 }else {
390 header = heap_alloc(sizeof(http_header_t));
391 if(!header)
392 return E_OUTOFMEMORY;
393
394 header->header = heap_strndupW(name, name_len);
395 header->data = heap_strndupW(value, value_len);
396 if(!header->header || !header->data) {
397 heap_free(header->header);
398 heap_free(header->data);
399 heap_free(header);
400 return E_OUTOFMEMORY;
401 }
402
403 list_add_tail(headers, &header->entry);
404 }
405
406 return S_OK;
407 }
408
409 static nsresult set_channel_http_header(struct list *headers, const nsACString *name_str,
410 const nsACString *value_str)
411 {
412 const char *namea, *valuea;
413 WCHAR *name, *value;
414 HRESULT hres;
415
416 nsACString_GetData(name_str, &namea);
417 name = heap_strdupAtoW(namea);
418 if(!name)
419 return NS_ERROR_UNEXPECTED;
420
421 nsACString_GetData(value_str, &valuea);
422 value = heap_strdupAtoW(valuea);
423 if(!value) {
424 heap_free(name);
425 return NS_ERROR_UNEXPECTED;
426 }
427
428 hres = set_http_header(headers, name, strlenW(name), value, strlenW(value));
429
430 heap_free(name);
431 heap_free(value);
432 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_UNEXPECTED;
433 }
434
435 static nsresult visit_http_headers(struct list *headers, nsIHttpHeaderVisitor *visitor)
436 {
437 nsACString header_str, value_str;
438 char *header, *value;
439 http_header_t *iter;
440 nsresult nsres;
441
442 LIST_FOR_EACH_ENTRY(iter, headers, http_header_t, entry) {
443 header = heap_strdupWtoA(iter->header);
444 if(!header)
445 return NS_ERROR_OUT_OF_MEMORY;
446
447 value = heap_strdupWtoA(iter->data);
448 if(!value) {
449 heap_free(header);
450 return NS_ERROR_OUT_OF_MEMORY;
451 }
452
453 nsACString_InitDepend(&header_str, header);
454 nsACString_InitDepend(&value_str, value);
455 nsres = nsIHttpHeaderVisitor_VisitHeader(visitor, &header_str, &value_str);
456 nsACString_Finish(&header_str);
457 nsACString_Finish(&value_str);
458 heap_free(header);
459 heap_free(value);
460 if(NS_FAILED(nsres))
461 break;
462 }
463
464 return NS_OK;
465 }
466
467 static void free_http_headers(struct list *list)
468 {
469 http_header_t *iter, *iter_next;
470
471 LIST_FOR_EACH_ENTRY_SAFE(iter, iter_next, list, http_header_t, entry) {
472 list_remove(&iter->entry);
473 heap_free(iter->header);
474 heap_free(iter->data);
475 heap_free(iter);
476 }
477 }
478
479 static inline nsChannel *impl_from_nsIHttpChannel(nsIHttpChannel *iface)
480 {
481 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannel_iface);
482 }
483
484 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, void **result)
485 {
486 nsChannel *This = impl_from_nsIHttpChannel(iface);
487
488 if(IsEqualGUID(&IID_nsISupports, riid)) {
489 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
490 *result = &This->nsIHttpChannel_iface;
491 }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
492 TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
493 *result = &This->nsIHttpChannel_iface;
494 }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
495 TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
496 *result = &This->nsIHttpChannel_iface;
497 }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
498 TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
499 *result = is_http_channel(This) ? &This->nsIHttpChannel_iface : NULL;
500 }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
501 TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
502 *result = &This->nsIUploadChannel_iface;
503 }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
504 TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
505 *result = is_http_channel(This) ? &This->nsIHttpChannelInternal_iface : NULL;
506 }else {
507 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
508 *result = NULL;
509 }
510
511 if(*result) {
512 nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
513 return NS_OK;
514 }
515
516 return NS_NOINTERFACE;
517 }
518
519 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
520 {
521 nsChannel *This = impl_from_nsIHttpChannel(iface);
522 nsrefcnt ref = InterlockedIncrement(&This->ref);
523
524 TRACE("(%p) ref=%d\n", This, ref);
525
526 return ref;
527 }
528
529 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
530 {
531 nsChannel *This = impl_from_nsIHttpChannel(iface);
532 LONG ref = InterlockedDecrement(&This->ref);
533
534 if(!ref) {
535 nsIFileURL_Release(&This->uri->nsIFileURL_iface);
536 if(This->owner)
537 nsISupports_Release(This->owner);
538 if(This->post_data_stream)
539 nsIInputStream_Release(This->post_data_stream);
540 if(This->load_group)
541 nsILoadGroup_Release(This->load_group);
542 if(This->notif_callback)
543 nsIInterfaceRequestor_Release(This->notif_callback);
544 if(This->original_uri)
545 nsIURI_Release(This->original_uri);
546 if(This->referrer)
547 nsIURI_Release(This->referrer);
548
549 free_http_headers(&This->response_headers);
550 free_http_headers(&This->request_headers);
551
552 heap_free(This->content_type);
553 heap_free(This->charset);
554 heap_free(This);
555 }
556
557 return ref;
558 }
559
560 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
561 {
562 nsChannel *This = impl_from_nsIHttpChannel(iface);
563
564 TRACE("(%p)->(%p)\n", This, aName);
565
566 return nsIFileURL_GetSpec(&This->uri->nsIFileURL_iface, aName);
567 }
568
569 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, cpp_bool *_retval)
570 {
571 nsChannel *This = impl_from_nsIHttpChannel(iface);
572
573 FIXME("(%p)->(%p)\n", This, _retval);
574
575 return NS_ERROR_NOT_IMPLEMENTED;
576 }
577
578 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
579 {
580 nsChannel *This = impl_from_nsIHttpChannel(iface);
581
582 WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
583
584 return *aStatus = NS_OK;
585 }
586
587 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
588 {
589 nsChannel *This = impl_from_nsIHttpChannel(iface);
590
591 FIXME("(%p)->(%08x)\n", This, aStatus);
592
593 return NS_ERROR_NOT_IMPLEMENTED;
594 }
595
596 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
597 {
598 nsChannel *This = impl_from_nsIHttpChannel(iface);
599
600 FIXME("(%p)\n", This);
601
602 return NS_ERROR_NOT_IMPLEMENTED;
603 }
604
605 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
606 {
607 nsChannel *This = impl_from_nsIHttpChannel(iface);
608
609 FIXME("(%p)\n", This);
610
611 return NS_ERROR_NOT_IMPLEMENTED;
612 }
613
614 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
615 {
616 nsChannel *This = impl_from_nsIHttpChannel(iface);
617
618 TRACE("(%p)->(%p)\n", This, aLoadGroup);
619
620 if(This->load_group)
621 nsILoadGroup_AddRef(This->load_group);
622
623 *aLoadGroup = This->load_group;
624 return NS_OK;
625 }
626
627 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
628 {
629 nsChannel *This = impl_from_nsIHttpChannel(iface);
630
631 TRACE("(%p)->(%p)\n", This, aLoadGroup);
632
633 if(This->load_group)
634 nsILoadGroup_Release(This->load_group);
635 if(aLoadGroup)
636 nsILoadGroup_AddRef(aLoadGroup);
637 This->load_group = aLoadGroup;
638
639 return NS_OK;
640 }
641
642 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
643 {
644 nsChannel *This = impl_from_nsIHttpChannel(iface);
645
646 TRACE("(%p)->(%p)\n", This, aLoadFlags);
647
648 *aLoadFlags = This->load_flags;
649 return NS_OK;
650 }
651
652 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
653 {
654 nsChannel *This = impl_from_nsIHttpChannel(iface);
655
656 TRACE("(%p)->(%08x)\n", This, aLoadFlags);
657
658 This->load_flags = aLoadFlags;
659 return NS_OK;
660 }
661
662 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
663 {
664 nsChannel *This = impl_from_nsIHttpChannel(iface);
665
666 TRACE("(%p)->(%p)\n", This, aOriginalURI);
667
668 if(This->original_uri)
669 nsIURI_AddRef(This->original_uri);
670
671 *aOriginalURI = This->original_uri;
672 return NS_OK;
673 }
674
675 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
676 {
677 nsChannel *This = impl_from_nsIHttpChannel(iface);
678
679 TRACE("(%p)->(%p)\n", This, aOriginalURI);
680
681 if(This->original_uri)
682 nsIURI_Release(This->original_uri);
683
684 nsIURI_AddRef(aOriginalURI);
685 This->original_uri = aOriginalURI;
686 return NS_OK;
687 }
688
689 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
690 {
691 nsChannel *This = impl_from_nsIHttpChannel(iface);
692
693 TRACE("(%p)->(%p)\n", This, aURI);
694
695 nsIFileURL_AddRef(&This->uri->nsIFileURL_iface);
696 *aURI = (nsIURI*)This->uri;
697
698 return NS_OK;
699 }
700
701 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
702 {
703 nsChannel *This = impl_from_nsIHttpChannel(iface);
704
705 TRACE("(%p)->(%p)\n", This, aOwner);
706
707 if(This->owner)
708 nsISupports_AddRef(This->owner);
709 *aOwner = This->owner;
710
711 return NS_OK;
712 }
713
714 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
715 {
716 nsChannel *This = impl_from_nsIHttpChannel(iface);
717
718 TRACE("(%p)->(%p)\n", This, aOwner);
719
720 if(aOwner)
721 nsISupports_AddRef(aOwner);
722 if(This->owner)
723 nsISupports_Release(This->owner);
724 This->owner = aOwner;
725
726 return NS_OK;
727 }
728
729 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
730 nsIInterfaceRequestor **aNotificationCallbacks)
731 {
732 nsChannel *This = impl_from_nsIHttpChannel(iface);
733
734 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
735
736 if(This->notif_callback)
737 nsIInterfaceRequestor_AddRef(This->notif_callback);
738 *aNotificationCallbacks = This->notif_callback;
739
740 return NS_OK;
741 }
742
743 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
744 nsIInterfaceRequestor *aNotificationCallbacks)
745 {
746 nsChannel *This = impl_from_nsIHttpChannel(iface);
747
748 TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
749
750 if(This->notif_callback)
751 nsIInterfaceRequestor_Release(This->notif_callback);
752 if(aNotificationCallbacks)
753 nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
754
755 This->notif_callback = aNotificationCallbacks;
756
757 return NS_OK;
758 }
759
760 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
761 {
762 nsChannel *This = impl_from_nsIHttpChannel(iface);
763
764 TRACE("(%p)->(%p)\n", This, aSecurityInfo);
765
766 return NS_ERROR_NOT_IMPLEMENTED;
767 }
768
769 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
770 {
771 nsChannel *This = impl_from_nsIHttpChannel(iface);
772
773 TRACE("(%p)->(%p)\n", This, aContentType);
774
775 if(This->content_type) {
776 nsACString_SetData(aContentType, This->content_type);
777 return S_OK;
778 }
779
780 if(This->uri->is_doc_uri) {
781 WARN("Document channel with no MIME set. Assuming text/html\n");
782 nsACString_SetData(aContentType, "text/html");
783 return S_OK;
784 }
785
786 WARN("unknown type\n");
787 return NS_ERROR_FAILURE;
788 }
789
790 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
791 const nsACString *aContentType)
792 {
793 nsChannel *This = impl_from_nsIHttpChannel(iface);
794 const char *content_type;
795
796 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentType));
797
798 nsACString_GetData(aContentType, &content_type);
799 heap_free(This->content_type);
800 This->content_type = heap_strdupA(content_type);
801
802 return NS_OK;
803 }
804
805 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
806 nsACString *aContentCharset)
807 {
808 nsChannel *This = impl_from_nsIHttpChannel(iface);
809
810 TRACE("(%p)->(%p)\n", This, aContentCharset);
811
812 if(This->charset) {
813 nsACString_SetData(aContentCharset, This->charset);
814 return NS_OK;
815 }
816
817 nsACString_SetData(aContentCharset, "");
818 return NS_OK;
819 }
820
821 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
822 const nsACString *aContentCharset)
823 {
824 nsChannel *This = impl_from_nsIHttpChannel(iface);
825 const char *data;
826 char *charset;
827
828 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aContentCharset));
829
830 nsACString_GetData(aContentCharset, &data);
831 charset = heap_strdupA(data);
832 if(!charset)
833 return NS_ERROR_OUT_OF_MEMORY;
834
835 heap_free(This->charset);
836 This->charset = charset;
837 return NS_OK;
838 }
839
840 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, INT64 *aContentLength)
841 {
842 nsChannel *This = impl_from_nsIHttpChannel(iface);
843
844 FIXME("(%p)->(%p)\n", This, aContentLength);
845
846 return NS_ERROR_NOT_IMPLEMENTED;
847 }
848
849 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, INT64 aContentLength)
850 {
851 nsChannel *This = impl_from_nsIHttpChannel(iface);
852
853 FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(aContentLength));
854
855 return NS_ERROR_NOT_IMPLEMENTED;
856 }
857
858 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
859 {
860 nsChannel *This = impl_from_nsIHttpChannel(iface);
861
862 FIXME("(%p)->(%p)\n", This, _retval);
863
864 return NS_ERROR_NOT_IMPLEMENTED;
865 }
866
867 static HTMLOuterWindow *get_window_from_load_group(nsChannel *This)
868 {
869 HTMLOuterWindow *window;
870 nsIChannel *channel;
871 nsIRequest *req;
872 nsWineURI *wine_uri;
873 nsIURI *uri;
874 nsresult nsres;
875
876 nsres = nsILoadGroup_GetDefaultLoadRequest(This->load_group, &req);
877 if(NS_FAILED(nsres)) {
878 ERR("GetDefaultLoadRequest failed: %08x\n", nsres);
879 return NULL;
880 }
881
882 if(!req)
883 return NULL;
884
885 nsres = nsIRequest_QueryInterface(req, &IID_nsIChannel, (void**)&channel);
886 nsIRequest_Release(req);
887 if(NS_FAILED(nsres)) {
888 WARN("Could not get nsIChannel interface: %08x\n", nsres);
889 return NULL;
890 }
891
892 nsres = nsIChannel_GetURI(channel, &uri);
893 nsIChannel_Release(channel);
894 if(NS_FAILED(nsres)) {
895 ERR("GetURI failed: %08x\n", nsres);
896 return NULL;
897 }
898
899 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
900 nsIURI_Release(uri);
901 if(NS_FAILED(nsres)) {
902 TRACE("Could not get nsWineURI: %08x\n", nsres);
903 return NULL;
904 }
905
906 window = wine_uri->window_ref ? wine_uri->window_ref->window : NULL;
907 if(window)
908 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
909 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
910
911 return window;
912 }
913
914 static HTMLOuterWindow *get_channel_window(nsChannel *This)
915 {
916 nsIWebProgress *web_progress;
917 nsIDOMWindow *nswindow;
918 HTMLOuterWindow *window;
919 nsresult nsres;
920
921 if(This->load_group) {
922 nsIRequestObserver *req_observer;
923
924 nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
925 if(NS_FAILED(nsres) || !req_observer) {
926 ERR("GetGroupObserver failed: %08x\n", nsres);
927 return NULL;
928 }
929
930 nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
931 nsIRequestObserver_Release(req_observer);
932 if(NS_FAILED(nsres)) {
933 ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
934 return NULL;
935 }
936 }else if(This->notif_callback) {
937 nsres = nsIInterfaceRequestor_GetInterface(This->notif_callback, &IID_nsIWebProgress, (void**)&web_progress);
938 if(NS_FAILED(nsres)) {
939 ERR("GetInterface(IID_nsIWebProgress failed: %08x\n", nsres);
940 return NULL;
941 }
942 }else {
943 ERR("no load group nor notif callback\n");
944 return NULL;
945 }
946
947 nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
948 nsIWebProgress_Release(web_progress);
949 if(NS_FAILED(nsres) || !nswindow) {
950 ERR("GetDOMWindow failed: %08x\n", nsres);
951 return NULL;
952 }
953
954 window = nswindow_to_window(nswindow);
955 nsIDOMWindow_Release(nswindow);
956
957 if(window)
958 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
959 else
960 FIXME("NULL window for %p\n", nswindow);
961 return window;
962 }
963
964 typedef struct {
965 task_t header;
966 HTMLInnerWindow *window;
967 nsChannelBSC *bscallback;
968 } start_binding_task_t;
969
970 static void start_binding_proc(task_t *_task)
971 {
972 start_binding_task_t *task = (start_binding_task_t*)_task;
973
974 start_binding(task->window, (BSCallback*)task->bscallback, NULL);
975 }
976
977 static void start_binding_task_destr(task_t *_task)
978 {
979 start_binding_task_t *task = (start_binding_task_t*)_task;
980
981 IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface);
982 heap_free(task);
983 }
984
985 static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
986 nsISupports *context)
987 {
988 nsChannelBSC *bscallback;
989 IMoniker *mon = NULL;
990 HRESULT hres;
991
992 hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0);
993 if(FAILED(hres)) {
994 WARN("CreateURLMoniker failed: %08x\n", hres);
995 return NS_ERROR_UNEXPECTED;
996 }
997
998 if(is_doc_channel)
999 set_current_mon(window, mon, BINDING_NAVIGATED);
1000
1001 hres = create_channelbsc(mon, NULL, NULL, 0, is_doc_channel, &bscallback);
1002 IMoniker_Release(mon);
1003 if(FAILED(hres))
1004 return NS_ERROR_UNEXPECTED;
1005
1006 channelbsc_set_channel(bscallback, This, listener, context);
1007
1008 if(is_doc_channel) {
1009 hres = create_pending_window(window, bscallback);
1010 if(SUCCEEDED(hres))
1011 async_start_doc_binding(window, window->pending_window);
1012 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1013 if(FAILED(hres))
1014 return NS_ERROR_UNEXPECTED;
1015 }else {
1016 start_binding_task_t *task;
1017
1018 task = heap_alloc(sizeof(start_binding_task_t));
1019 if(!task) {
1020 IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface);
1021 return NS_ERROR_OUT_OF_MEMORY;
1022 }
1023
1024 task->window = window->base.inner_window;
1025 task->bscallback = bscallback;
1026 hres = push_task(&task->header, start_binding_proc, start_binding_task_destr, window->base.inner_window->task_magic);
1027 if(FAILED(hres))
1028 return NS_ERROR_OUT_OF_MEMORY;
1029 }
1030
1031 return NS_OK;
1032 }
1033
1034 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
1035 nsISupports *aContext)
1036 {
1037 nsChannel *This = impl_from_nsIHttpChannel(iface);
1038 HTMLOuterWindow *window = NULL;
1039 BOOL cancel = FALSE;
1040 nsresult nsres = NS_OK;
1041
1042 TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
1043
1044 if(!ensure_uri(This->uri))
1045 return NS_ERROR_FAILURE;
1046
1047 if(TRACE_ON(mshtml)) {
1048 HRESULT hres;
1049 BSTR uri_str;
1050
1051 hres = IUri_GetDisplayUri(This->uri->uri, &uri_str);
1052 if(SUCCEEDED(hres)) {
1053 TRACE("opening %s\n", debugstr_w(uri_str));
1054 SysFreeString(uri_str);
1055 }else {
1056 WARN("GetDisplayUri failed: %08x\n", hres);
1057 }
1058 }
1059
1060 if(This->uri->is_doc_uri) {
1061 window = get_channel_window(This);
1062 if(window) {
1063 set_uri_window(This->uri, window);
1064 }else if(This->uri->container) {
1065 BOOL b;
1066
1067 /* nscontainer->doc should be NULL which means navigation to a new window */
1068 if(This->uri->container->doc)
1069 FIXME("nscontainer->doc = %p\n", This->uri->container->doc);
1070
1071 nsres = before_async_open(This, This->uri->container, &b);
1072 if(NS_FAILED(nsres))
1073 return nsres;
1074 if(b)
1075 FIXME("Navigation not cancelled\n");
1076 return NS_ERROR_UNEXPECTED;
1077 }
1078 }
1079
1080 if(!window) {
1081 if(This->uri->window_ref && This->uri->window_ref->window) {
1082 window = This->uri->window_ref->window;
1083 IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
1084 }else {
1085 /* FIXME: Analyze removing get_window_from_load_group call */
1086 if(This->load_group)
1087 window = get_window_from_load_group(This);
1088 if(!window)
1089 window = get_channel_window(This);
1090 if(window)
1091 set_uri_window(This->uri, window);
1092 }
1093 }
1094
1095 if(!window) {
1096 ERR("window = NULL\n");
1097 return NS_ERROR_UNEXPECTED;
1098 }
1099
1100 if(This->uri->is_doc_uri && window == window->doc_obj->basedoc.window) {
1101 if(This->uri->channel_bsc) {
1102 channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
1103
1104 if(window->doc_obj->mime) {
1105 heap_free(This->content_type);
1106 This->content_type = heap_strdupWtoA(window->doc_obj->mime);
1107 }
1108
1109 cancel = TRUE;
1110 }else {
1111 nsres = before_async_open(This, window->doc_obj->nscontainer, &cancel);
1112 if(NS_SUCCEEDED(nsres) && cancel) {
1113 TRACE("canceled\n");
1114 nsres = NS_BINDING_ABORTED;
1115 }
1116 }
1117 }
1118
1119 if(!cancel)
1120 nsres = async_open(This, window, This->uri->is_doc_uri, aListener, aContext);
1121
1122 if(NS_SUCCEEDED(nsres) && This->load_group) {
1123 nsres = nsILoadGroup_AddRequest(This->load_group, (nsIRequest*)&This->nsIHttpChannel_iface,
1124 aContext);
1125 if(NS_FAILED(nsres))
1126 ERR("AddRequest failed: %08x\n", nsres);
1127 }
1128
1129 IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
1130 return nsres;
1131 }
1132
1133 static nsresult NSAPI nsChannel_GetContentDisposition(nsIHttpChannel *iface, UINT32 *aContentDisposition)
1134 {
1135 nsChannel *This = impl_from_nsIHttpChannel(iface);
1136 FIXME("(%p)->(%p)\n", This, aContentDisposition);
1137 return NS_ERROR_NOT_IMPLEMENTED;
1138 }
1139
1140 static nsresult NSAPI nsChannel_SetContentDisposition(nsIHttpChannel *iface, UINT32 aContentDisposition)
1141 {
1142 nsChannel *This = impl_from_nsIHttpChannel(iface);
1143 FIXME("(%p)->(%u)\n", This, aContentDisposition);
1144 return NS_ERROR_NOT_IMPLEMENTED;
1145 }
1146
1147 static nsresult NSAPI nsChannel_GetContentDispositionFilename(nsIHttpChannel *iface, nsAString *aContentDispositionFilename)
1148 {
1149 nsChannel *This = impl_from_nsIHttpChannel(iface);
1150 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1151 return NS_ERROR_NOT_IMPLEMENTED;
1152 }
1153
1154 static nsresult NSAPI nsChannel_SetContentDispositionFilename(nsIHttpChannel *iface, const nsAString *aContentDispositionFilename)
1155 {
1156 nsChannel *This = impl_from_nsIHttpChannel(iface);
1157 FIXME("(%p)->(%p)\n", This, aContentDispositionFilename);
1158 return NS_ERROR_NOT_IMPLEMENTED;
1159 }
1160
1161 static nsresult NSAPI nsChannel_GetContentDispositionHeader(nsIHttpChannel *iface, nsACString *aContentDispositionHeader)
1162 {
1163 nsChannel *This = impl_from_nsIHttpChannel(iface);
1164 FIXME("(%p)->(%p)\n", This, aContentDispositionHeader);
1165 return NS_ERROR_NOT_IMPLEMENTED;
1166 }
1167
1168 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
1169 {
1170 nsChannel *This = impl_from_nsIHttpChannel(iface);
1171
1172 TRACE("(%p)->(%p)\n", This, aRequestMethod);
1173
1174 nsACString_SetData(aRequestMethod, request_method_strings[This->request_method]);
1175 return NS_OK;
1176 }
1177
1178 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
1179 const nsACString *aRequestMethod)
1180 {
1181 nsChannel *This = impl_from_nsIHttpChannel(iface);
1182 const char *method;
1183 unsigned i;
1184
1185 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRequestMethod));
1186
1187 nsACString_GetData(aRequestMethod, &method);
1188 for(i=0; i < sizeof(request_method_strings)/sizeof(*request_method_strings); i++) {
1189 if(!strcasecmp(method, request_method_strings[i])) {
1190 This->request_method = i;
1191 return NS_OK;
1192 }
1193 }
1194
1195 ERR("Invalid method %s\n", debugstr_a(method));
1196 return NS_ERROR_UNEXPECTED;
1197 }
1198
1199 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
1200 {
1201 nsChannel *This = impl_from_nsIHttpChannel(iface);
1202
1203 TRACE("(%p)->(%p)\n", This, aReferrer);
1204
1205 if(This->referrer)
1206 nsIURI_AddRef(This->referrer);
1207 *aReferrer = This->referrer;
1208 return NS_OK;
1209 }
1210
1211 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
1212 {
1213 nsChannel *This = impl_from_nsIHttpChannel(iface);
1214
1215 TRACE("(%p)->(%p)\n", This, aReferrer);
1216
1217 if(aReferrer)
1218 nsIURI_AddRef(aReferrer);
1219 if(This->referrer)
1220 nsIURI_Release(This->referrer);
1221 This->referrer = aReferrer;
1222 return NS_OK;
1223 }
1224
1225 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
1226 const nsACString *aHeader, nsACString *_retval)
1227 {
1228 nsChannel *This = impl_from_nsIHttpChannel(iface);
1229
1230 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aHeader), _retval);
1231
1232 return get_channel_http_header(&This->request_headers, aHeader, _retval);
1233 }
1234
1235 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
1236 const nsACString *aHeader, const nsACString *aValue, cpp_bool aMerge)
1237 {
1238 nsChannel *This = impl_from_nsIHttpChannel(iface);
1239
1240 TRACE("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(aHeader), debugstr_nsacstr(aValue), aMerge);
1241
1242 if(aMerge)
1243 FIXME("aMerge not supported\n");
1244
1245 return set_channel_http_header(&This->request_headers, aHeader, aValue);
1246 }
1247
1248 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
1249 nsIHttpHeaderVisitor *aVisitor)
1250 {
1251 nsChannel *This = impl_from_nsIHttpChannel(iface);
1252
1253 FIXME("(%p)->(%p)\n", This, aVisitor);
1254
1255 return NS_ERROR_NOT_IMPLEMENTED;
1256 }
1257
1258 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, cpp_bool *aAllowPipelining)
1259 {
1260 nsChannel *This = impl_from_nsIHttpChannel(iface);
1261
1262 FIXME("(%p)->(%p)\n", This, aAllowPipelining);
1263
1264 return NS_ERROR_NOT_IMPLEMENTED;
1265 }
1266
1267 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, cpp_bool aAllowPipelining)
1268 {
1269 nsChannel *This = impl_from_nsIHttpChannel(iface);
1270
1271 FIXME("(%p)->(%x)\n", This, aAllowPipelining);
1272
1273 return NS_ERROR_NOT_IMPLEMENTED;
1274 }
1275
1276 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, UINT32 *aRedirectionLimit)
1277 {
1278 nsChannel *This = impl_from_nsIHttpChannel(iface);
1279
1280 FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
1281
1282 return NS_ERROR_NOT_IMPLEMENTED;
1283 }
1284
1285 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, UINT32 aRedirectionLimit)
1286 {
1287 nsChannel *This = impl_from_nsIHttpChannel(iface);
1288
1289 FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
1290
1291 return NS_ERROR_NOT_IMPLEMENTED;
1292 }
1293
1294 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, UINT32 *aResponseStatus)
1295 {
1296 nsChannel *This = impl_from_nsIHttpChannel(iface);
1297
1298 TRACE("(%p)->(%p)\n", This, aResponseStatus);
1299
1300 if(This->response_status) {
1301 *aResponseStatus = This->response_status;
1302 return NS_OK;
1303 }
1304
1305 WARN("No response status\n");
1306 return NS_ERROR_UNEXPECTED;
1307 }
1308
1309 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
1310 nsACString *aResponseStatusText)
1311 {
1312 nsChannel *This = impl_from_nsIHttpChannel(iface);
1313
1314 FIXME("(%p)->(%p)\n", This, aResponseStatusText);
1315
1316 return NS_ERROR_NOT_IMPLEMENTED;
1317 }
1318
1319 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
1320 cpp_bool *aRequestSucceeded)
1321 {
1322 nsChannel *This = impl_from_nsIHttpChannel(iface);
1323
1324 TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
1325
1326 if(!This->response_status)
1327 return NS_ERROR_NOT_AVAILABLE;
1328
1329 *aRequestSucceeded = This->response_status/100 == 2;
1330
1331 return NS_OK;
1332 }
1333
1334 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
1335 const nsACString *header, nsACString *_retval)
1336 {
1337 nsChannel *This = impl_from_nsIHttpChannel(iface);
1338
1339 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(header), _retval);
1340
1341 return get_channel_http_header(&This->response_headers, header, _retval);
1342 }
1343
1344 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
1345 const nsACString *header, const nsACString *value, cpp_bool merge)
1346 {
1347 nsChannel *This = impl_from_nsIHttpChannel(iface);
1348
1349 FIXME("(%p)->(%s %s %x)\n", This, debugstr_nsacstr(header), debugstr_nsacstr(value), merge);
1350
1351 return NS_ERROR_NOT_IMPLEMENTED;
1352 }
1353
1354 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
1355 nsIHttpHeaderVisitor *aVisitor)
1356 {
1357 nsChannel *This = impl_from_nsIHttpChannel(iface);
1358
1359 TRACE("(%p)->(%p)\n", This, aVisitor);
1360
1361 return visit_http_headers(&This->response_headers, aVisitor);
1362 }
1363
1364 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1365 {
1366 nsChannel *This = impl_from_nsIHttpChannel(iface);
1367 http_header_t *header;
1368
1369 static const WCHAR cache_controlW[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l'};
1370 static const WCHAR no_storeW[] = {'n','o','-','s','t','o','r','e',0};
1371
1372 TRACE("(%p)->(%p)\n", This, _retval);
1373
1374 header = find_http_header(&This->response_headers, cache_controlW, sizeof(cache_controlW)/sizeof(WCHAR));
1375 *_retval = header && !strcmpiW(header->data, no_storeW);
1376 return NS_OK;
1377 }
1378
1379 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, cpp_bool *_retval)
1380 {
1381 nsChannel *This = impl_from_nsIHttpChannel(iface);
1382
1383 FIXME("(%p)->(%p)\n", This, _retval);
1384
1385 return NS_ERROR_NOT_IMPLEMENTED;
1386 }
1387
1388 static nsresult NSAPI nsChannel_RedirectTo(nsIHttpChannel *iface, nsIURI *aNewURI)
1389 {
1390 nsChannel *This = impl_from_nsIHttpChannel(iface);
1391
1392 FIXME("(%p)->(%p)\n", This, aNewURI);
1393
1394 return NS_ERROR_NOT_IMPLEMENTED;
1395 }
1396
1397 static const nsIHttpChannelVtbl nsChannelVtbl = {
1398 nsChannel_QueryInterface,
1399 nsChannel_AddRef,
1400 nsChannel_Release,
1401 nsChannel_GetName,
1402 nsChannel_IsPending,
1403 nsChannel_GetStatus,
1404 nsChannel_Cancel,
1405 nsChannel_Suspend,
1406 nsChannel_Resume,
1407 nsChannel_GetLoadGroup,
1408 nsChannel_SetLoadGroup,
1409 nsChannel_GetLoadFlags,
1410 nsChannel_SetLoadFlags,
1411 nsChannel_GetOriginalURI,
1412 nsChannel_SetOriginalURI,
1413 nsChannel_GetURI,
1414 nsChannel_GetOwner,
1415 nsChannel_SetOwner,
1416 nsChannel_GetNotificationCallbacks,
1417 nsChannel_SetNotificationCallbacks,
1418 nsChannel_GetSecurityInfo,
1419 nsChannel_GetContentType,
1420 nsChannel_SetContentType,
1421 nsChannel_GetContentCharset,
1422 nsChannel_SetContentCharset,
1423 nsChannel_GetContentLength,
1424 nsChannel_SetContentLength,
1425 nsChannel_Open,
1426 nsChannel_AsyncOpen,
1427 nsChannel_GetContentDisposition,
1428 nsChannel_SetContentDisposition,
1429 nsChannel_GetContentDispositionFilename,
1430 nsChannel_SetContentDispositionFilename,
1431 nsChannel_GetContentDispositionHeader,
1432 nsChannel_GetRequestMethod,
1433 nsChannel_SetRequestMethod,
1434 nsChannel_GetReferrer,
1435 nsChannel_SetReferrer,
1436 nsChannel_GetRequestHeader,
1437 nsChannel_SetRequestHeader,
1438 nsChannel_VisitRequestHeaders,
1439 nsChannel_GetAllowPipelining,
1440 nsChannel_SetAllowPipelining,
1441 nsChannel_GetRedirectionLimit,
1442 nsChannel_SetRedirectionLimit,
1443 nsChannel_GetResponseStatus,
1444 nsChannel_GetResponseStatusText,
1445 nsChannel_GetRequestSucceeded,
1446 nsChannel_GetResponseHeader,
1447 nsChannel_SetResponseHeader,
1448 nsChannel_VisitResponseHeaders,
1449 nsChannel_IsNoStoreResponse,
1450 nsChannel_IsNoCacheResponse,
1451 nsChannel_RedirectTo
1452 };
1453
1454 static inline nsChannel *impl_from_nsIUploadChannel(nsIUploadChannel *iface)
1455 {
1456 return CONTAINING_RECORD(iface, nsChannel, nsIUploadChannel_iface);
1457 }
1458
1459 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
1460 void **result)
1461 {
1462 nsChannel *This = impl_from_nsIUploadChannel(iface);
1463 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1464 }
1465
1466 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
1467 {
1468 nsChannel *This = impl_from_nsIUploadChannel(iface);
1469 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1470 }
1471
1472 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
1473 {
1474 nsChannel *This = impl_from_nsIUploadChannel(iface);
1475 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1476 }
1477
1478 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
1479 nsIInputStream *aStream, const nsACString *aContentType, INT64 aContentLength)
1480 {
1481 nsChannel *This = impl_from_nsIUploadChannel(iface);
1482 const char *content_type;
1483
1484 static const WCHAR content_typeW[] =
1485 {'C','o','n','t','e','n','t','-','T','y','p','e',0};
1486
1487 TRACE("(%p)->(%p %s %s)\n", This, aStream, debugstr_nsacstr(aContentType), wine_dbgstr_longlong(aContentLength));
1488
1489 This->post_data_contains_headers = TRUE;
1490
1491 if(aContentType) {
1492 nsACString_GetData(aContentType, &content_type);
1493 if(*content_type) {
1494 WCHAR *ct;
1495
1496 ct = heap_strdupAtoW(content_type);
1497 if(!ct)
1498 return NS_ERROR_UNEXPECTED;
1499
1500 set_http_header(&This->request_headers, content_typeW,
1501 sizeof(content_typeW)/sizeof(WCHAR), ct, strlenW(ct));
1502 heap_free(ct);
1503 This->post_data_contains_headers = FALSE;
1504 }
1505 }
1506
1507 if(This->post_data_stream)
1508 nsIInputStream_Release(This->post_data_stream);
1509
1510 if(aContentLength != -1)
1511 FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength));
1512
1513 if(This->post_data_stream)
1514 nsIInputStream_Release(This->post_data_stream);
1515 This->post_data_stream = aStream;
1516 if(aStream)
1517 nsIInputStream_AddRef(aStream);
1518
1519 This->request_method = METHOD_POST;
1520 return NS_OK;
1521 }
1522
1523 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
1524 nsIInputStream **aUploadStream)
1525 {
1526 nsChannel *This = impl_from_nsIUploadChannel(iface);
1527
1528 TRACE("(%p)->(%p)\n", This, aUploadStream);
1529
1530 if(This->post_data_stream)
1531 nsIInputStream_AddRef(This->post_data_stream);
1532
1533 *aUploadStream = This->post_data_stream;
1534 return NS_OK;
1535 }
1536
1537 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
1538 nsUploadChannel_QueryInterface,
1539 nsUploadChannel_AddRef,
1540 nsUploadChannel_Release,
1541 nsUploadChannel_SetUploadStream,
1542 nsUploadChannel_GetUploadStream
1543 };
1544
1545 static inline nsChannel *impl_from_nsIHttpChannelInternal(nsIHttpChannelInternal *iface)
1546 {
1547 return CONTAINING_RECORD(iface, nsChannel, nsIHttpChannelInternal_iface);
1548 }
1549
1550 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
1551 void **result)
1552 {
1553 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1554 return nsIHttpChannel_QueryInterface(&This->nsIHttpChannel_iface, riid, result);
1555 }
1556
1557 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
1558 {
1559 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1560 return nsIHttpChannel_AddRef(&This->nsIHttpChannel_iface);
1561 }
1562
1563 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
1564 {
1565 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1566 return nsIHttpChannel_Release(&This->nsIHttpChannel_iface);
1567 }
1568
1569 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
1570 {
1571 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1572
1573 FIXME("(%p)->()\n", This);
1574
1575 return NS_ERROR_NOT_IMPLEMENTED;
1576 }
1577
1578 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
1579 {
1580 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1581
1582 FIXME("(%p)->()\n", This);
1583
1584 return NS_ERROR_NOT_IMPLEMENTED;
1585 }
1586
1587 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1588 {
1589 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1590
1591 FIXME("(%p)->()\n", This);
1592
1593 return NS_ERROR_NOT_IMPLEMENTED;
1594 }
1595
1596 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, UINT32 *major, UINT32 *minor)
1597 {
1598 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1599
1600 FIXME("(%p)->()\n", This);
1601
1602 return NS_ERROR_NOT_IMPLEMENTED;
1603 }
1604
1605 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
1606 {
1607 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1608
1609 FIXME("(%p)->()\n", This);
1610
1611 return NS_ERROR_NOT_IMPLEMENTED;
1612 }
1613
1614 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
1615 {
1616 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1617
1618 FIXME("(%p)->()\n", This);
1619
1620 return NS_ERROR_NOT_IMPLEMENTED;
1621 }
1622
1623 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool *aForceThirdPartyCookie)
1624 {
1625 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1626
1627 FIXME("(%p)->()\n", This);
1628
1629 return NS_ERROR_NOT_IMPLEMENTED;
1630 }
1631
1632 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, cpp_bool aForceThirdPartyCookie)
1633 {
1634 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1635
1636 FIXME("(%p)->()\n", This);
1637
1638 return NS_ERROR_NOT_IMPLEMENTED;
1639 }
1640
1641 static nsresult NSAPI nsHttpChannelInternal_GetCanceled(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1642 {
1643 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1644
1645 FIXME("(%p)->(%p)\n", This, aCanceled);
1646
1647 return NS_ERROR_NOT_IMPLEMENTED;
1648 }
1649
1650 static nsresult NSAPI nsHttpChannelInternal_GetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool *aCanceled)
1651 {
1652 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1653
1654 FIXME("(%p)->(%p)\n", This, aCanceled);
1655
1656 return NS_ERROR_NOT_IMPLEMENTED;
1657 }
1658
1659 static nsresult NSAPI nsHttpChannelInternal_SetChannelIsForDownload(nsIHttpChannelInternal *iface, cpp_bool aCanceled)
1660 {
1661 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1662
1663 FIXME("(%p)->(%x)\n", This, aCanceled);
1664
1665 return NS_ERROR_NOT_IMPLEMENTED;
1666 }
1667
1668 static nsresult NSAPI nsHttpChannelInternal_GetLocalAddress(nsIHttpChannelInternal *iface, nsACString *aLocalAddress)
1669 {
1670 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1671
1672 FIXME("(%p)->(%p)\n", This, aLocalAddress);
1673
1674 return NS_ERROR_NOT_IMPLEMENTED;
1675 }
1676
1677 static nsresult NSAPI nsHttpChannelInternal_GetLocalPort(nsIHttpChannelInternal *iface, LONG *aLocalPort)
1678 {
1679 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1680
1681 FIXME("(%p)->(%p)\n", This, aLocalPort);
1682
1683 return NS_ERROR_NOT_IMPLEMENTED;
1684 }
1685
1686 static nsresult NSAPI nsHttpChannelInternal_GetRemoteAddress(nsIHttpChannelInternal *iface, nsACString *aRemoteAddress)
1687 {
1688 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1689
1690 FIXME("(%p)->(%p)\n", This, aRemoteAddress);
1691
1692 return NS_ERROR_NOT_IMPLEMENTED;
1693 }
1694
1695 static nsresult NSAPI nsHttpChannelInternal_GetRemotePort(nsIHttpChannelInternal *iface, LONG *aRemotePort)
1696 {
1697 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1698
1699 FIXME("(%p)->(%p)\n", This, aRemotePort);
1700
1701 return NS_ERROR_NOT_IMPLEMENTED;
1702 }
1703
1704 static nsresult NSAPI nsHttpChannelInternal_SetCacheKeysRedirectChain(nsIHttpChannelInternal *iface, void *cacheKeys)
1705 {
1706 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1707
1708 FIXME("(%p)->(%p)\n", This, cacheKeys);
1709
1710 return NS_ERROR_NOT_IMPLEMENTED;
1711 }
1712
1713 static nsresult NSAPI nsHttpChannelInternal_HTTPUpgrade(nsIHttpChannelInternal *iface,
1714 const nsACString *aProtocolName, nsIHttpUpgradeListener *aListener)
1715 {
1716 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1717 FIXME("(%p)->(%s %p)\n", This, debugstr_nsacstr(aProtocolName), aListener);
1718 return NS_ERROR_NOT_IMPLEMENTED;
1719 }
1720
1721 static nsresult NSAPI nsHttpChannelInternal_GetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool *aAllowSpdy)
1722 {
1723 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1724 FIXME("(%p)->(%p)\n", This, aAllowSpdy);
1725 return NS_ERROR_NOT_IMPLEMENTED;
1726 }
1727
1728 static nsresult NSAPI nsHttpChannelInternal_SetAllowSpdy(nsIHttpChannelInternal *iface, cpp_bool aAllowSpdy)
1729 {
1730 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1731 FIXME("(%p)->(%x)\n", This, aAllowSpdy);
1732 return NS_ERROR_NOT_IMPLEMENTED;
1733 }
1734
1735 static nsresult NSAPI nsHttpChannelInternal_GetLoadAsBlocking(nsIHttpChannelInternal *iface, cpp_bool *aLoadAsBlocking)
1736 {
1737 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1738 FIXME("(%p)->(%p)\n", This, aLoadAsBlocking);
1739 return NS_ERROR_NOT_IMPLEMENTED;
1740 }
1741
1742 static nsresult NSAPI nsHttpChannelInternal_SetLoadAsBlocking(nsIHttpChannelInternal *iface, cpp_bool aLoadAsBlocking)
1743 {
1744 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1745 FIXME("(%p)->(%x)\n", This, aLoadAsBlocking);
1746 return NS_ERROR_NOT_IMPLEMENTED;
1747 }
1748
1749 static nsresult NSAPI nsHttpChannelInternal_GetLoadUnblocked(nsIHttpChannelInternal *iface, cpp_bool *aLoadUnblocked)
1750 {
1751 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1752 FIXME("(%p)->(%p)\n", This, aLoadUnblocked);
1753 return NS_ERROR_NOT_IMPLEMENTED;
1754 }
1755
1756 static nsresult NSAPI nsHttpChannelInternal_SetLoadUnblocked(nsIHttpChannelInternal *iface, cpp_bool aLoadUnblocked)
1757 {
1758 nsChannel *This = impl_from_nsIHttpChannelInternal(iface);
1759 FIXME("(%p)->(%x)\n", This, aLoadUnblocked);
1760 return NS_ERROR_NOT_IMPLEMENTED;
1761 }
1762
1763 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
1764 nsHttpChannelInternal_QueryInterface,
1765 nsHttpChannelInternal_AddRef,
1766 nsHttpChannelInternal_Release,
1767 nsHttpChannelInternal_GetDocumentURI,
1768 nsHttpChannelInternal_SetDocumentURI,
1769 nsHttpChannelInternal_GetRequestVersion,
1770 nsHttpChannelInternal_GetResponseVersion,
1771 nsHttpChannelInternal_SetCookie,
1772 nsHttpChannelInternal_SetupFallbackChannel,
1773 nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
1774 nsHttpChannelInternal_SetForceAllowThirdPartyCookie,
1775 nsHttpChannelInternal_GetCanceled,
1776 nsHttpChannelInternal_GetChannelIsForDownload,
1777 nsHttpChannelInternal_SetChannelIsForDownload,
1778 nsHttpChannelInternal_GetLocalAddress,
1779 nsHttpChannelInternal_GetLocalPort,
1780 nsHttpChannelInternal_GetRemoteAddress,
1781 nsHttpChannelInternal_GetRemotePort,
1782 nsHttpChannelInternal_SetCacheKeysRedirectChain,
1783 nsHttpChannelInternal_HTTPUpgrade,
1784 nsHttpChannelInternal_GetAllowSpdy,
1785 nsHttpChannelInternal_SetAllowSpdy,
1786 nsHttpChannelInternal_GetLoadAsBlocking,
1787 nsHttpChannelInternal_SetLoadAsBlocking,
1788 nsHttpChannelInternal_GetLoadUnblocked,
1789 nsHttpChannelInternal_SetLoadUnblocked
1790 };
1791
1792
1793 static void invalidate_uri(nsWineURI *This)
1794 {
1795 if(This->uri) {
1796 IUri_Release(This->uri);
1797 This->uri = NULL;
1798 }
1799 }
1800
1801 static BOOL ensure_uri_builder(nsWineURI *This)
1802 {
1803 if(!This->is_mutable) {
1804 WARN("Not mutable URI\n");
1805 return FALSE;
1806 }
1807
1808 if(!This->uri_builder) {
1809 HRESULT hres;
1810
1811 if(!ensure_uri(This))
1812 return FALSE;
1813
1814 hres = CreateIUriBuilder(This->uri, 0, 0, &This->uri_builder);
1815 if(FAILED(hres)) {
1816 WARN("CreateIUriBuilder failed: %08x\n", hres);
1817 return FALSE;
1818 }
1819 }
1820
1821 invalidate_uri(This);
1822 return TRUE;
1823 }
1824
1825 static nsresult get_uri_string(nsWineURI *This, Uri_PROPERTY prop, nsACString *ret)
1826 {
1827 char *vala;
1828 BSTR val;
1829 HRESULT hres;
1830
1831 if(!ensure_uri(This))
1832 return NS_ERROR_UNEXPECTED;
1833
1834 hres = IUri_GetPropertyBSTR(This->uri, prop, &val, 0);
1835 if(FAILED(hres)) {
1836 WARN("GetPropertyBSTR failed: %08x\n", hres);
1837 return NS_ERROR_UNEXPECTED;
1838 }
1839
1840 vala = heap_strdupWtoU(val);
1841 SysFreeString(val);
1842 if(!vala)
1843 return NS_ERROR_OUT_OF_MEMORY;
1844
1845 TRACE("ret %s\n", debugstr_a(vala));
1846 nsACString_SetData(ret, vala);
1847 heap_free(vala);
1848 return NS_OK;
1849 }
1850
1851 static inline nsWineURI *impl_from_nsIFileURL(nsIFileURL *iface)
1852 {
1853 return CONTAINING_RECORD(iface, nsWineURI, nsIFileURL_iface);
1854 }
1855
1856 static nsresult NSAPI nsURI_QueryInterface(nsIFileURL *iface, nsIIDRef riid, void **result)
1857 {
1858 nsWineURI *This = impl_from_nsIFileURL(iface);
1859
1860 *result = NULL;
1861
1862 if(IsEqualGUID(&IID_nsISupports, riid)) {
1863 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
1864 *result = &This->nsIFileURL_iface;
1865 }else if(IsEqualGUID(&IID_nsIURI, riid)) {
1866 TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
1867 *result = &This->nsIFileURL_iface;
1868 }else if(IsEqualGUID(&IID_nsIURL, riid)) {
1869 TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
1870 *result = &This->nsIFileURL_iface;
1871 }else if(IsEqualGUID(&IID_nsIFileURL, riid)) {
1872 TRACE("(%p)->(IID_nsIFileURL %p)\n", This, result);
1873 *result = This->scheme == URL_SCHEME_FILE ? &This->nsIFileURL_iface : NULL;
1874 }else if(IsEqualGUID(&IID_nsIMutable, riid)) {
1875 TRACE("(%p)->(IID_nsIMutable %p)\n", This, result);
1876 *result = &This->nsIStandardURL_iface;
1877 }else if(IsEqualGUID(&IID_nsIStandardURL, riid)) {
1878 TRACE("(%p)->(IID_nsIStandardURL %p)\n", This, result);
1879 *result = &This->nsIStandardURL_iface;
1880 }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
1881 TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
1882 *result = This;
1883 }
1884
1885 if(*result) {
1886 nsIFileURL_AddRef(&This->nsIFileURL_iface);
1887 return NS_OK;
1888 }
1889
1890 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
1891 return NS_NOINTERFACE;
1892 }
1893
1894 static nsrefcnt NSAPI nsURI_AddRef(nsIFileURL *iface)
1895 {
1896 nsWineURI *This = impl_from_nsIFileURL(iface);
1897 LONG ref = InterlockedIncrement(&This->ref);
1898
1899 TRACE("(%p) ref=%d\n", This, ref);
1900
1901 return ref;
1902 }
1903
1904 static nsrefcnt NSAPI nsURI_Release(nsIFileURL *iface)
1905 {
1906 nsWineURI *This = impl_from_nsIFileURL(iface);
1907 LONG ref = InterlockedDecrement(&This->ref);
1908
1909 TRACE("(%p) ref=%d\n", This, ref);
1910
1911 if(!ref) {
1912 if(This->window_ref)
1913 windowref_release(This->window_ref);
1914 if(This->container)
1915 nsIWebBrowserChrome_Release(&This->container->nsIWebBrowserChrome_iface);
1916 if(This->uri)
1917 IUri_Release(This->uri);
1918 heap_free(This->origin_charset);
1919 heap_free(This);
1920 }
1921
1922 return ref;
1923 }
1924
1925 static nsresult NSAPI nsURI_GetSpec(nsIFileURL *iface, nsACString *aSpec)
1926 {
1927 nsWineURI *This = impl_from_nsIFileURL(iface);
1928
1929 TRACE("(%p)->(%p)\n", This, aSpec);
1930
1931 return get_uri_string(This, Uri_PROPERTY_DISPLAY_URI, aSpec);
1932 }
1933
1934 static nsresult NSAPI nsURI_SetSpec(nsIFileURL *iface, const nsACString *aSpec)
1935 {
1936 nsWineURI *This = impl_from_nsIFileURL(iface);
1937 const char *speca;
1938 WCHAR *spec;
1939 IUri *uri;
1940 HRESULT hres;
1941
1942 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aSpec));
1943
1944 if(!This->is_mutable)
1945 return NS_ERROR_UNEXPECTED;
1946
1947 nsACString_GetData(aSpec, &speca);
1948 spec = heap_strdupUtoW(speca);
1949 if(!spec)
1950 return NS_ERROR_OUT_OF_MEMORY;
1951
1952 hres = create_uri(spec, 0, &uri);
1953 heap_free(spec);
1954 if(FAILED(hres)) {
1955 WARN("create_uri failed: %08x\n", hres);
1956 return NS_ERROR_FAILURE;
1957 }
1958
1959 invalidate_uri(This);
1960 if(This->uri_builder) {
1961 IUriBuilder_Release(This->uri_builder);
1962 This->uri_builder = NULL;
1963 }
1964
1965 This->uri = uri;
1966 return NS_OK;
1967 }
1968
1969 static nsresult NSAPI nsURI_GetPrePath(nsIFileURL *iface, nsACString *aPrePath)
1970 {
1971 nsWineURI *This = impl_from_nsIFileURL(iface);
1972 FIXME("(%p)->(%p)\n", This, aPrePath);
1973 return NS_ERROR_NOT_IMPLEMENTED;
1974 }
1975
1976 static nsresult NSAPI nsURI_GetScheme(nsIFileURL *iface, nsACString *aScheme)
1977 {
1978 nsWineURI *This = impl_from_nsIFileURL(iface);
1979 DWORD scheme;
1980 HRESULT hres;
1981
1982 TRACE("(%p)->(%p)\n", This, aScheme);
1983
1984 if(!ensure_uri(This))
1985 return NS_ERROR_UNEXPECTED;
1986
1987 hres = IUri_GetScheme(This->uri, &scheme);
1988 if(FAILED(hres)) {
1989 WARN("GetScheme failed: %08x\n", hres);
1990 return NS_ERROR_UNEXPECTED;
1991 }
1992
1993 if(scheme == URL_SCHEME_ABOUT) {
1994 nsACString_SetData(aScheme, "wine");
1995 return NS_OK;
1996 }
1997
1998 return get_uri_string(This, Uri_PROPERTY_SCHEME_NAME, aScheme);
1999 }
2000
2001 static nsresult NSAPI nsURI_SetScheme(nsIFileURL *iface, const nsACString *aScheme)
2002 {
2003 nsWineURI *This = impl_from_nsIFileURL(iface);
2004 const char *schemea;
2005 WCHAR *scheme;
2006 HRESULT hres;
2007
2008 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aScheme));
2009
2010 if(!ensure_uri_builder(This))
2011 return NS_ERROR_UNEXPECTED;
2012
2013 nsACString_GetData(aScheme, &schemea);
2014 scheme = heap_strdupUtoW(schemea);
2015 if(!scheme)
2016 return NS_ERROR_OUT_OF_MEMORY;
2017
2018 hres = IUriBuilder_SetSchemeName(This->uri_builder, scheme);
2019 heap_free(scheme);
2020 if(FAILED(hres))
2021 return NS_ERROR_UNEXPECTED;
2022
2023 return NS_OK;
2024 }
2025
2026 static nsresult NSAPI nsURI_GetUserPass(nsIFileURL *iface, nsACString *aUserPass)
2027 {
2028 nsWineURI *This = impl_from_nsIFileURL(iface);
2029 BSTR user, pass;
2030 HRESULT hres;
2031
2032 TRACE("(%p)->(%p)\n", This, aUserPass);
2033
2034 if(!ensure_uri(This))
2035 return NS_ERROR_UNEXPECTED;
2036
2037 hres = IUri_GetUserName(This->uri, &user);
2038 if(FAILED(hres))
2039 return NS_ERROR_FAILURE;
2040
2041 hres = IUri_GetPassword(This->uri, &pass);
2042 if(FAILED(hres)) {
2043 SysFreeString(user);
2044 return NS_ERROR_FAILURE;
2045 }
2046
2047 if(*user || *pass) {
2048 FIXME("Construct user:pass string\n");
2049 }else {
2050 nsACString_SetData(aUserPass, "");
2051 }
2052
2053 SysFreeString(user);
2054 SysFreeString(pass);
2055 return NS_OK;
2056 }
2057
2058 static nsresult NSAPI nsURI_SetUserPass(nsIFileURL *iface, const nsACString *aUserPass)
2059 {
2060 nsWineURI *This = impl_from_nsIFileURL(iface);
2061 WCHAR *user = NULL, *pass = NULL, *buf = NULL;
2062 const char *user_pass;
2063 HRESULT hres;
2064
2065 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUserPass));
2066
2067 if(!ensure_uri_builder(This))
2068 return NS_ERROR_UNEXPECTED;
2069
2070 nsACString_GetData(aUserPass, &user_pass);
2071 if(*user_pass) {
2072 WCHAR *ptr;
2073
2074 buf = heap_strdupUtoW(user_pass);
2075 if(!buf)
2076 return NS_ERROR_OUT_OF_MEMORY;
2077
2078 ptr = strchrW(buf, ':');
2079 if(!ptr) {
2080 user = buf;
2081 }else if(ptr != buf) {
2082 *ptr++ = 0;
2083 user = buf;
2084 if(*ptr)
2085 pass = ptr;
2086 }else {
2087 pass = buf+1;
2088 }
2089 }
2090
2091 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2092 if(SUCCEEDED(hres))
2093 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2094
2095 heap_free(buf);
2096 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2097 }
2098
2099 static nsresult NSAPI nsURI_GetUsername(nsIFileURL *iface, nsACString *aUsername)
2100 {
2101 nsWineURI *This = impl_from_nsIFileURL(iface);
2102
2103 TRACE("(%p)->(%p)\n", This, aUsername);
2104
2105 return get_uri_string(This, Uri_PROPERTY_USER_NAME, aUsername);
2106 }
2107
2108 static nsresult NSAPI nsURI_SetUsername(nsIFileURL *iface, const nsACString *aUsername)
2109 {
2110 nsWineURI *This = impl_from_nsIFileURL(iface);
2111 const char *usera;
2112 WCHAR *user;
2113 HRESULT hres;
2114
2115 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aUsername));
2116
2117 if(!ensure_uri_builder(This))
2118 return NS_ERROR_UNEXPECTED;
2119
2120 nsACString_GetData(aUsername, &usera);
2121 user = heap_strdupUtoW(usera);
2122 if(!user)
2123 return NS_ERROR_OUT_OF_MEMORY;
2124
2125 hres = IUriBuilder_SetUserName(This->uri_builder, user);
2126 heap_free(user);
2127 if(FAILED(hres))
2128 return NS_ERROR_UNEXPECTED;
2129
2130 return NS_OK;
2131 }
2132
2133 static nsresult NSAPI nsURI_GetPassword(nsIFileURL *iface, nsACString *aPassword)
2134 {
2135 nsWineURI *This = impl_from_nsIFileURL(iface);
2136
2137 TRACE("(%p)->(%p)\n", This, aPassword);
2138
2139 return get_uri_string(This, Uri_PROPERTY_PASSWORD, aPassword);
2140 }
2141
2142 static nsresult NSAPI nsURI_SetPassword(nsIFileURL *iface, const nsACString *aPassword)
2143 {
2144 nsWineURI *This = impl_from_nsIFileURL(iface);
2145 const char *passa;
2146 WCHAR *pass;
2147 HRESULT hres;
2148
2149 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPassword));
2150
2151 if(!ensure_uri_builder(This))
2152 return NS_ERROR_UNEXPECTED;
2153
2154 nsACString_GetData(aPassword, &passa);
2155 pass = heap_strdupUtoW(passa);
2156 if(!pass)
2157 return NS_ERROR_OUT_OF_MEMORY;
2158
2159 hres = IUriBuilder_SetPassword(This->uri_builder, pass);
2160 heap_free(pass);
2161 if(FAILED(hres))
2162 return NS_ERROR_UNEXPECTED;
2163
2164 return NS_OK;
2165 }
2166
2167 static nsresult NSAPI nsURI_GetHostPort(nsIFileURL *iface, nsACString *aHostPort)
2168 {
2169 nsWineURI *This = impl_from_nsIFileURL(iface);
2170 const WCHAR *ptr;
2171 char *vala;
2172 BSTR val;
2173 HRESULT hres;
2174
2175 TRACE("(%p)->(%p)\n", This, aHostPort);
2176
2177 if(!ensure_uri(This))
2178 return NS_ERROR_UNEXPECTED;
2179
2180 hres = IUri_GetAuthority(This->uri, &val);
2181 if(FAILED(hres)) {
2182 WARN("GetAuthority failed: %08x\n", hres);
2183 return NS_ERROR_UNEXPECTED;
2184 }
2185
2186 ptr = strchrW(val, '@');
2187 if(!ptr)
2188 ptr = val;
2189
2190 vala = heap_strdupWtoU(ptr);
2191 SysFreeString(val);
2192 if(!vala)
2193 return NS_ERROR_OUT_OF_MEMORY;
2194
2195 TRACE("ret %s\n", debugstr_a(vala));
2196 nsACString_SetData(aHostPort, vala);
2197 heap_free(vala);
2198 return NS_OK;
2199 }
2200
2201 static nsresult NSAPI nsURI_SetHostPort(nsIFileURL *iface, const nsACString *aHostPort)
2202 {
2203 nsWineURI *This = impl_from_nsIFileURL(iface);
2204
2205 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aHostPort));
2206
2207 /* Not implemented by Gecko */
2208 return NS_ERROR_NOT_IMPLEMENTED;
2209 }
2210
2211 static nsresult NSAPI nsURI_GetHost(nsIFileURL *iface, nsACString *aHost)
2212 {
2213 nsWineURI *This = impl_from_nsIFileURL(iface);
2214
2215 TRACE("(%p)->(%p)\n", This, aHost);
2216
2217 return get_uri_string(This, Uri_PROPERTY_HOST, aHost);
2218 }
2219
2220 static nsresult NSAPI nsURI_SetHost(nsIFileURL *iface, const nsACString *aHost)
2221 {
2222 nsWineURI *This = impl_from_nsIFileURL(iface);
2223 const char *hosta;
2224 WCHAR *host;
2225 HRESULT hres;
2226
2227 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aHost));
2228
2229 if(!ensure_uri_builder(This))
2230 return NS_ERROR_UNEXPECTED;
2231
2232 nsACString_GetData(aHost, &hosta);
2233 host = heap_strdupUtoW(hosta);
2234 if(!host)
2235 return NS_ERROR_OUT_OF_MEMORY;
2236
2237 hres = IUriBuilder_SetHost(This->uri_builder, host);
2238 heap_free(host);
2239 if(FAILED(hres))
2240 return NS_ERROR_UNEXPECTED;
2241
2242 return NS_OK;
2243 }
2244
2245 static nsresult NSAPI nsURI_GetPort(nsIFileURL *iface, LONG *aPort)
2246 {
2247 nsWineURI *This = impl_from_nsIFileURL(iface);
2248 DWORD port;
2249 HRESULT hres;
2250
2251 TRACE("(%p)->(%p)\n", This, aPort);
2252
2253 if(!ensure_uri(This))
2254 return NS_ERROR_UNEXPECTED;
2255
2256 hres = IUri_GetPort(This->uri, &port);
2257 if(FAILED(hres)) {
2258 WARN("GetPort failed: %08x\n", hres);
2259 return NS_ERROR_UNEXPECTED;
2260 }
2261
2262 *aPort = port ? port : -1;
2263 return NS_OK;
2264 }
2265
2266 static nsresult NSAPI nsURI_SetPort(nsIFileURL *iface, LONG aPort)
2267 {
2268 nsWineURI *This = impl_from_nsIFileURL(iface);
2269 HRESULT hres;
2270
2271 TRACE("(%p)->(%d)\n", This, aPort);
2272
2273 if(!ensure_uri_builder(This))
2274 return NS_ERROR_UNEXPECTED;
2275
2276 hres = IUriBuilder_SetPort(This->uri_builder, aPort != -1, aPort);
2277 return SUCCEEDED(hres) ? NS_OK : NS_ERROR_FAILURE;
2278 }
2279
2280 static nsresult NSAPI nsURI_GetPath(nsIFileURL *iface, nsACString *aPath)
2281 {
2282 nsWineURI *This = impl_from_nsIFileURL(iface);
2283
2284 TRACE("(%p)->(%p)\n", This, aPath);
2285
2286 return get_uri_string(This, Uri_PROPERTY_PATH, aPath);
2287 }
2288
2289 static nsresult NSAPI nsURI_SetPath(nsIFileURL *iface, const nsACString *aPath)
2290 {
2291 nsWineURI *This = impl_from_nsIFileURL(iface);
2292 const char *patha;
2293 WCHAR *path;
2294 HRESULT hres;
2295
2296 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aPath));
2297
2298 if(!ensure_uri_builder(This))
2299 return NS_ERROR_UNEXPECTED;
2300
2301 nsACString_GetData(aPath, &patha);
2302 path = heap_strdupUtoW(patha);
2303 if(!path)
2304 return NS_ERROR_OUT_OF_MEMORY;
2305
2306 hres = IUriBuilder_SetPath(This->uri_builder, path);
2307 heap_free(path);
2308 if(FAILED(hres))
2309 return NS_ERROR_UNEXPECTED;
2310
2311 return NS_OK;
2312 }
2313
2314 static nsresult NSAPI nsURI_Equals(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2315 {
2316 nsWineURI *This = impl_from_nsIFileURL(iface);
2317 nsWineURI *other_obj;
2318 nsresult nsres;
2319 HRESULT hres;
2320
2321 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2322
2323 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2324 if(NS_FAILED(nsres)) {
2325 TRACE("Could not get nsWineURI interface\n");
2326 *_retval = FALSE;
2327 return NS_OK;
2328 }
2329
2330 if(ensure_uri(This) && ensure_uri(other_obj)) {
2331 BOOL b;
2332
2333 hres = IUri_IsEqual(This->uri, other_obj->uri, &b);
2334 if(SUCCEEDED(hres)) {
2335 *_retval = b;
2336 nsres = NS_OK;
2337 }else {
2338 nsres = NS_ERROR_FAILURE;
2339 }
2340 }else {
2341 nsres = NS_ERROR_UNEXPECTED;
2342 }
2343
2344 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2345 return nsres;
2346 }
2347
2348 static nsresult NSAPI nsURI_SchemeIs(nsIFileURL *iface, const char *scheme, cpp_bool *_retval)
2349 {
2350 nsWineURI *This = impl_from_nsIFileURL(iface);
2351 WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
2352 BSTR scheme_name;
2353 HRESULT hres;
2354
2355 TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
2356
2357 if(!ensure_uri(This))
2358 return NS_ERROR_UNEXPECTED;
2359
2360 hres = IUri_GetSchemeName(This->uri, &scheme_name);
2361 if(FAILED(hres))
2362 return NS_ERROR_UNEXPECTED;
2363
2364 MultiByteToWideChar(CP_UTF8, 0, scheme, -1, buf, sizeof(buf)/sizeof(WCHAR));
2365 *_retval = !strcmpW(scheme_name, buf);
2366 SysFreeString(scheme_name);
2367 return NS_OK;
2368 }
2369
2370 static nsresult NSAPI nsURI_Clone(nsIFileURL *iface, nsIURI **_retval)
2371 {
2372 nsWineURI *This = impl_from_nsIFileURL(iface);
2373 nsWineURI *wine_uri;
2374 nsresult nsres;
2375
2376 TRACE("(%p)->(%p)\n", This, _retval);
2377
2378 if(!ensure_uri(This))
2379 return NS_ERROR_UNEXPECTED;
2380
2381 nsres = create_nsuri(This->uri, This->window_ref ? This->window_ref->window : NULL,
2382 This->container, This->origin_charset, &wine_uri);
2383 if(NS_FAILED(nsres)) {
2384 WARN("create_nsuri failed: %08x\n", nsres);
2385 return nsres;
2386 }
2387
2388 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2389 return NS_OK;
2390 }
2391
2392 static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelativePath,
2393 nsACString *_retval)
2394 {
2395 nsWineURI *This = impl_from_nsIFileURL(iface);
2396 const char *patha;
2397 IUri *new_uri;
2398 WCHAR *path;
2399 char *reta;
2400 BSTR ret;
2401 HRESULT hres;
2402
2403 TRACE("(%p)->(%s %p)\n", This, debugstr_nsacstr(aRelativePath), _retval);
2404
2405 if(!ensure_uri(This))
2406 return NS_ERROR_UNEXPECTED;
2407
2408 nsACString_GetData(aRelativePath, &patha);
2409 path = heap_strdupUtoW(patha);
2410 if(!path)
2411 return NS_ERROR_OUT_OF_MEMORY;
2412
2413 hres = CoInternetCombineUrlEx(This->uri, path, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, &new_uri, 0);
2414 heap_free(path);
2415 if(FAILED(hres)) {
2416 ERR("CoIntenetCombineUrlEx failed: %08x\n", hres);
2417 return NS_ERROR_FAILURE;
2418 }
2419
2420 hres = IUri_GetDisplayUri(new_uri, &ret);
2421 IUri_Release(new_uri);
2422 if(FAILED(hres))
2423 return NS_ERROR_FAILURE;
2424
2425 reta = heap_strdupWtoU(ret);
2426 SysFreeString(ret);
2427 if(!reta)
2428 return NS_ERROR_OUT_OF_MEMORY;
2429
2430 TRACE("returning %s\n", debugstr_a(reta));
2431 nsACString_SetData(_retval, reta);
2432 heap_free(reta);
2433 return NS_OK;
2434 }
2435
2436 static nsresult NSAPI nsURI_GetAsciiSpec(nsIFileURL *iface, nsACString *aAsciiSpec)
2437 {
2438 nsWineURI *This = impl_from_nsIFileURL(iface);
2439
2440 TRACE("(%p)->(%p)\n", This, aAsciiSpec);
2441
2442 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aAsciiSpec);
2443 }
2444
2445 static nsresult NSAPI nsURI_GetAsciiHost(nsIFileURL *iface, nsACString *aAsciiHost)
2446 {
2447 nsWineURI *This = impl_from_nsIFileURL(iface);
2448
2449 WARN("(%p)->(%p) FIXME: Use Uri_PUNYCODE_IDN_HOST flag\n", This, aAsciiHost);
2450
2451 return get_uri_string(This, Uri_PROPERTY_HOST, aAsciiHost);
2452 }
2453
2454 static nsresult NSAPI nsURI_GetOriginCharset(nsIFileURL *iface, nsACString *aOriginCharset)
2455 {
2456 nsWineURI *This = impl_from_nsIFileURL(iface);
2457
2458 TRACE("(%p)->(%p)\n", This, aOriginCharset);
2459
2460 nsACString_SetData(aOriginCharset, This->origin_charset);
2461 return NS_OK;
2462 }
2463
2464 static nsresult NSAPI nsURL_GetRef(nsIFileURL *iface, nsACString *aRef)
2465 {
2466 nsWineURI *This = impl_from_nsIFileURL(iface);
2467 char *refa = NULL;
2468 BSTR ref;
2469 HRESULT hres;
2470
2471 TRACE("(%p)->(%p)\n", This, aRef);
2472
2473 if(!ensure_uri(This))
2474 return NS_ERROR_UNEXPECTED;
2475
2476 hres = IUri_GetFragment(This->uri, &ref);
2477 if(FAILED(hres))
2478 return NS_ERROR_UNEXPECTED;
2479
2480 refa = heap_strdupWtoU(ref);
2481 SysFreeString(ref);
2482 if(ref && !refa)
2483 return NS_ERROR_OUT_OF_MEMORY;
2484
2485 nsACString_SetData(aRef, refa && *refa == '#' ? refa+1 : refa);
2486 heap_free(refa);
2487 return NS_OK;
2488 }
2489
2490 static nsresult NSAPI nsURL_SetRef(nsIFileURL *iface, const nsACString *aRef)
2491 {
2492 nsWineURI *This = impl_from_nsIFileURL(iface);
2493 const char *refa;
2494 WCHAR *ref;
2495 HRESULT hres;
2496
2497 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
2498
2499 if(!ensure_uri_builder(This))
2500 return NS_ERROR_UNEXPECTED;
2501
2502 nsACString_GetData(aRef, &refa);
2503 ref = heap_strdupUtoW(refa);
2504 if(!ref)
2505 return NS_ERROR_OUT_OF_MEMORY;
2506
2507 hres = IUriBuilder_SetFragment(This->uri_builder, ref);
2508 heap_free(ref);
2509 if(FAILED(hres))
2510 return NS_ERROR_UNEXPECTED;
2511
2512 return NS_OK;
2513 }
2514
2515 static nsresult NSAPI nsURI_EqualsExceptRef(nsIFileURL *iface, nsIURI *other, cpp_bool *_retval)
2516 {
2517 nsWineURI *This = impl_from_nsIFileURL(iface);
2518 nsWineURI *other_obj;
2519 nsresult nsres;
2520
2521 TRACE("(%p)->(%p %p)\n", This, other, _retval);
2522
2523 nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&other_obj);
2524 if(NS_FAILED(nsres)) {
2525 TRACE("Could not get nsWineURI interface\n");
2526 *_retval = FALSE;
2527 return NS_OK;
2528 }
2529
2530 if(ensure_uri(This) && ensure_uri(other_obj)) {
2531 *_retval = compare_ignoring_frag(This->uri, other_obj->uri);
2532 nsres = NS_OK;
2533 }else {
2534 nsres = NS_ERROR_UNEXPECTED;
2535 }
2536
2537 nsIFileURL_Release(&other_obj->nsIFileURL_iface);
2538 return nsres;
2539 }
2540
2541 static nsresult NSAPI nsURI_CloneIgnoreRef(nsIFileURL *iface, nsIURI **_retval)
2542 {
2543 nsWineURI *This = impl_from_nsIFileURL(iface);
2544 nsWineURI *wine_uri;
2545 IUri *uri;
2546 nsresult nsres;
2547
2548 TRACE("(%p)->(%p)\n", This, _retval);
2549
2550 if(!ensure_uri(This))
2551 return NS_ERROR_UNEXPECTED;
2552
2553 uri = get_uri_nofrag(This->uri);
2554 if(!uri)
2555 return NS_ERROR_FAILURE;
2556
2557 nsres = create_nsuri(uri, This->window_ref ? This->window_ref->window : NULL, This->container,
2558 This->origin_charset, &wine_uri);
2559 IUri_Release(uri);
2560 if(NS_FAILED(nsres)) {
2561 WARN("create_nsuri failed: %08x\n", nsres);
2562 return nsres;
2563 }
2564
2565 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
2566 return NS_OK;
2567 }
2568
2569 static nsresult NSAPI nsURI_GetSpecIgnoringRef(nsIFileURL *iface, nsACString *aSpecIgnoringRef)
2570 {
2571 nsWineURI *This = impl_from_nsIFileURL(iface);
2572
2573 FIXME("(%p)->(%p)\n", This, aSpecIgnoringRef);
2574
2575 return nsIFileURL_GetSpec(&This->nsIFileURL_iface, aSpecIgnoringRef);
2576 }
2577
2578 static nsresult NSAPI nsURI_GetHasRef(nsIFileURL *iface, cpp_bool *aHasRef)
2579 {
2580 nsWineURI *This = impl_from_nsIFileURL(iface);
2581 BOOL b;
2582 HRESULT hres;
2583
2584 TRACE("(%p)->(%p)\n", This, aHasRef);
2585
2586 if(!ensure_uri(This))
2587 return NS_ERROR_UNEXPECTED;
2588
2589 hres = IUri_HasProperty(This->uri, Uri_PROPERTY_FRAGMENT, &b);
2590 if(FAILED(hres))
2591 return NS_ERROR_FAILURE;
2592
2593 *aHasRef = b;
2594 return NS_OK;
2595 }
2596
2597 static nsresult NSAPI nsURL_GetFilePath(nsIFileURL *iface, nsACString *aFilePath)
2598 {
2599 nsWineURI *This = impl_from_nsIFileURL(iface);
2600
2601 TRACE("(%p)->(%p)\n", This, aFilePath);
2602
2603 return nsIFileURL_GetPath(&This->nsIFileURL_iface, aFilePath);
2604 }
2605
2606 static nsresult NSAPI nsURL_SetFilePath(nsIFileURL *iface, const nsACString *aFilePath)
2607 {
2608 nsWineURI *This = impl_from_nsIFileURL(iface);
2609
2610 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
2611
2612 if(!This->is_mutable)
2613 return NS_ERROR_UNEXPECTED;
2614
2615 return nsIFileURL_SetPath(&This->nsIFileURL_iface, aFilePath);
2616 }
2617
2618 static nsresult NSAPI nsURL_GetQuery(nsIFileURL *iface, nsACString *aQuery)
2619 {
2620 nsWineURI *This = impl_from_nsIFileURL(iface);
2621
2622 TRACE("(%p)->(%p)\n", This, aQuery);
2623
2624 return get_uri_string(This, Uri_PROPERTY_QUERY, aQuery);
2625 }
2626
2627 static nsresult NSAPI nsURL_SetQuery(nsIFileURL *iface, const nsACString *aQuery)
2628 {
2629 nsWineURI *This = impl_from_nsIFileURL(iface);
2630 const char *querya;
2631 WCHAR *query;
2632 HRESULT hres;
2633
2634 TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
2635
2636 if(!ensure_uri_builder(This))
2637 return NS_ERROR_UNEXPECTED;
2638
2639 nsACString_GetData(aQuery, &querya);
2640 query = heap_strdupUtoW(querya);
2641 if(!query)
2642 return NS_ERROR_OUT_OF_MEMORY;
2643
2644 hres = IUriBuilder_SetQuery(This->uri_builder, query);
2645 heap_free(query);
2646 if(FAILED(hres))
2647 return NS_ERROR_UNEXPECTED;
2648
2649 return NS_OK;
2650 }
2651
2652 static nsresult get_uri_path(nsWineURI *This, BSTR *path, const WCHAR **file, const WCHAR **ext)
2653 {
2654 const WCHAR *ptr;
2655 HRESULT hres;
2656
2657 if(!ensure_uri(This))
2658 return NS_ERROR_UNEXPECTED;
2659
2660 hres = IUri_GetPath(This->uri, path);
2661 if(FAILED(hres))
2662 return NS_ERROR_FAILURE;
2663
2664 for(ptr = *path + SysStringLen(*path)-1; ptr > *path && *ptr != '/' && *ptr != '\\'; ptr--);
2665 if(*ptr == '/' || *ptr == '\\')
2666 ptr++;
2667 *file = ptr;
2668
2669 if(ext) {
2670 ptr = strrchrW(ptr, '.');
2671 if(!ptr)
2672 ptr = *path + SysStringLen(*path);
2673 *ext = ptr;
2674 }
2675
2676 return NS_OK;
2677 }
2678
2679 static nsresult NSAPI nsURL_GetDirectory(nsIFileURL *iface, nsACString *aDirectory)
2680 {
2681 nsWineURI *This = impl_from_nsIFileURL(iface);
2682 const WCHAR *file;
2683 BSTR path;
2684 nsresult nsres;
2685
2686 TRACE("(%p)->(%p)\n", This, aDirectory);
2687
2688 nsres = get_uri_path(This, &path, &file, NULL);
2689 if(NS_FAILED(nsres))
2690 return nsres;
2691
2692 nsres = return_wstr_nsacstr(aDirectory, path, file-path);
2693 SysFreeString(path);
2694 return nsres;
2695 }
2696
2697 static nsresult NSAPI nsURL_SetDirectory(nsIFileURL *iface, const nsACString *aDirectory)
2698 {
2699 nsWineURI *This = impl_from_nsIFileURL(iface);
2700
2701 WARN("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
2702
2703 /* Not implemented by Gecko */
2704 return NS_ERROR_NOT_IMPLEMENTED;
2705 }
2706
2707 static nsresult NSAPI nsURL_GetFileName(nsIFileURL *iface, nsACString *aFileName)
2708 {
2709 nsWineURI *This = impl_from_nsIFileURL(iface);
2710 const WCHAR *file;
2711 BSTR path;
2712 nsresult nsres;
2713
2714 TRACE("(%p)->(%p)\n", This, aFileName);
2715
2716 nsres = get_uri_path(This, &path, &file, NULL);
2717 if(NS_FAILED(nsres))
2718 return nsres;
2719
2720 nsres = return_wstr_nsacstr(aFileName, file, -1);
2721 SysFreeString(path);
2722 return nsres;
2723 }
2724
2725 static nsresult NSAPI nsURL_SetFileName(nsIFileURL *iface, const nsACString *aFileName)
2726 {
2727 nsWineURI *This = impl_from_nsIFileURL(iface);
2728 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
2729 return NS_ERROR_NOT_IMPLEMENTED;
2730 }
2731
2732 static nsresult NSAPI nsURL_GetFileBaseName(nsIFileURL *iface, nsACString *aFileBaseName)
2733 {
2734 nsWineURI *This = impl_from_nsIFileURL(iface);
2735 const WCHAR *file, *ext;
2736 BSTR path;
2737 nsresult nsres;
2738
2739 TRACE("(%p)->(%p)\n", This, aFileBaseName);
2740
2741 nsres = get_uri_path(This, &path, &file, &ext);
2742 if(NS_FAILED(nsres))
2743 return nsres;
2744
2745 nsres = return_wstr_nsacstr(aFileBaseName, file, ext-file);
2746 SysFreeString(path);
2747 return nsres;
2748 }
2749
2750 static nsresult NSAPI nsURL_SetFileBaseName(nsIFileURL *iface, const nsACString *aFileBaseName)
2751 {
2752 nsWineURI *This = impl_from_nsIFileURL(iface);
2753 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
2754 return NS_ERROR_NOT_IMPLEMENTED;
2755 }
2756
2757 static nsresult NSAPI nsURL_GetFileExtension(nsIFileURL *iface, nsACString *aFileExtension)
2758 {
2759 nsWineURI *This = impl_from_nsIFileURL(iface);
2760
2761 TRACE("(%p)->(%p)\n", This, aFileExtension);
2762
2763 return get_uri_string(This, Uri_PROPERTY_EXTENSION, aFileExtension);
2764 }
2765
2766 static nsresult NSAPI nsURL_SetFileExtension(nsIFileURL *iface, const nsACString *aFileExtension)
2767 {
2768 nsWineURI *This = impl_from_nsIFileURL(iface);
2769 FIXME("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
2770 return NS_ERROR_NOT_IMPLEMENTED;
2771 }
2772
2773 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
2774 {
2775 nsWineURI *This = impl_from_nsIFileURL(iface);
2776 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
2777 return NS_ERROR_NOT_IMPLEMENTED;
2778 }
2779
2780 static nsresult NSAPI nsURL_GetRelativeSpec(nsIFileURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
2781 {
2782 nsWineURI *This = impl_from_nsIFileURL(iface);
2783 FIXME("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
2784 return NS_ERROR_NOT_IMPLEMENTED;
2785 }
2786
2787 static nsresult NSAPI nsFileURL_GetFile(nsIFileURL *iface, nsIFile **aFile)
2788 {
2789 nsWineURI *This = impl_from_nsIFileURL(iface);
2790 WCHAR path[MAX_PATH];
2791 DWORD size;
2792 HRESULT hres;
2793
2794 TRACE("(%p)->(%p)\n", This, aFile);
2795
2796 hres = CoInternetParseIUri(This->uri, PARSE_PATH_FROM_URL, 0, path, sizeof(path)/sizeof(WCHAR), &size, 0);
2797 if(FAILED(hres)) {
2798 WARN("CoInternetParseIUri failed: %08x\n", hres);
2799 return NS_ERROR_FAILURE;
2800 }
2801
2802 return create_nsfile(path, aFile);
2803 }
2804
2805 static nsresult NSAPI nsFileURL_SetFile(nsIFileURL *iface, nsIFile *aFile)
2806 {
2807 nsWineURI *This = impl_from_nsIFileURL(iface);
2808 FIXME("(%p)->(%p)\n", This, aFile);
2809 return NS_ERROR_NOT_IMPLEMENTED;
2810 }
2811
2812 static const nsIFileURLVtbl nsFileURLVtbl = {
2813 nsURI_QueryInterface,
2814 nsURI_AddRef,
2815 nsURI_Release,
2816 nsURI_GetSpec,
2817 nsURI_SetSpec,
2818 nsURI_GetPrePath,
2819 nsURI_GetScheme,
2820 nsURI_SetScheme,
2821 nsURI_GetUserPass,
2822 nsURI_SetUserPass,
2823 nsURI_GetUsername,
2824 nsURI_SetUsername,
2825 nsURI_GetPassword,
2826 nsURI_SetPassword,
2827 nsURI_GetHostPort,
2828 nsURI_SetHostPort,
2829 nsURI_GetHost,
2830 nsURI_SetHost,
2831 nsURI_GetPort,
2832 nsURI_SetPort,
2833 nsURI_GetPath,
2834 nsURI_SetPath,
2835 nsURI_Equals,
2836 nsURI_SchemeIs,
2837 nsURI_Clone,
2838 nsURI_Resolve,
2839 nsURI_GetAsciiSpec,
2840 nsURI_GetAsciiHost,
2841 nsURI_GetOriginCharset,
2842 nsURL_GetRef,
2843 nsURL_SetRef,
2844 nsURI_EqualsExceptRef,
2845 nsURI_CloneIgnoreRef,
2846 nsURI_GetSpecIgnoringRef,
2847 nsURI_GetHasRef,
2848 nsURL_GetFilePath,
2849 nsURL_SetFilePath,
2850 nsURL_GetQuery,
2851 nsURL_SetQuery,
2852 nsURL_GetDirectory,
2853 nsURL_SetDirectory,
2854 nsURL_GetFileName,
2855 nsURL_SetFileName,
2856 nsURL_GetFileBaseName,
2857 nsURL_SetFileBaseName,
2858 nsURL_GetFileExtension,
2859 nsURL_SetFileExtension,
2860 nsURL_GetCommonBaseSpec,
2861 nsURL_GetRelativeSpec,
2862 nsFileURL_GetFile,
2863 nsFileURL_SetFile
2864 };
2865
2866 static inline nsWineURI *impl_from_nsIStandardURL(nsIStandardURL *iface)
2867 {
2868 return CONTAINING_RECORD(iface, nsWineURI, nsIStandardURL_iface);
2869 }
2870
2871 static nsresult NSAPI nsStandardURL_QueryInterface(nsIStandardURL *iface, nsIIDRef riid,
2872 void **result)
2873 {
2874 nsWineURI *This = impl_from_nsIStandardURL(iface);
2875 return nsIFileURL_QueryInterface(&This->nsIFileURL_iface, riid, result);
2876 }
2877
2878 static nsrefcnt NSAPI nsStandardURL_AddRef(nsIStandardURL *iface)
2879 {
2880 nsWineURI *This = impl_from_nsIStandardURL(iface);
2881 return nsIFileURL_AddRef(&This->nsIFileURL_iface);
2882 }
2883
2884 static nsrefcnt NSAPI nsStandardURL_Release(nsIStandardURL *iface)
2885 {
2886 nsWineURI *This = impl_from_nsIStandardURL(iface);
2887 return nsIFileURL_Release(&This->nsIFileURL_iface);
2888 }
2889
2890 static nsresult NSAPI nsStandardURL_GetMutable(nsIStandardURL *iface, cpp_bool *aMutable)
2891 {
2892 nsWineURI *This = impl_from_nsIStandardURL(iface);
2893
2894 TRACE("(%p)->(%p)\n", This, aMutable);
2895
2896 *aMutable = This->is_mutable;
2897 return NS_OK;
2898 }
2899
2900 static nsresult NSAPI nsStandardURL_SetMutable(nsIStandardURL *iface, cpp_bool aMutable)
2901 {
2902 nsWineURI *This = impl_from_nsIStandardURL(iface);
2903
2904 TRACE("(%p)->(%x)\n", This, aMutable);
2905
2906 This->is_mutable = aMutable;
2907 return NS_OK;
2908 }
2909
2910 static nsresult NSAPI nsStandardURL_Init(nsIStandardURL *iface, UINT32 aUrlType, LONG aDefaultPort,
2911 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI)
2912 {
2913 nsWineURI *This = impl_from_nsIStandardURL(iface);
2914 FIXME("(%p)->(%d %d %s %s %p)\n", This, aUrlType, aDefaultPort, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI);
2915 return NS_ERROR_NOT_IMPLEMENTED;
2916 }
2917
2918 static const nsIStandardURLVtbl nsStandardURLVtbl = {
2919 nsStandardURL_QueryInterface,
2920 nsStandardURL_AddRef,
2921 nsStandardURL_Release,
2922 nsStandardURL_GetMutable,
2923 nsStandardURL_SetMutable,
2924 nsStandardURL_Init
2925 };
2926
2927 static nsresult create_nsuri(IUri *iuri, HTMLOuterWindow *window, NSContainer *container,
2928 const char *origin_charset, nsWineURI **_retval)
2929 {
2930 nsWineURI *ret;
2931 HRESULT hres;
2932
2933 ret = heap_alloc_zero(sizeof(nsWineURI));
2934 if(!ret)
2935 return NS_ERROR_OUT_OF_MEMORY;
2936
2937 ret->nsIFileURL_iface.lpVtbl = &nsFileURLVtbl;
2938 ret->nsIStandardURL_iface.lpVtbl = &nsStandardURLVtbl;
2939 ret->ref = 1;
2940 ret->is_mutable = TRUE;
2941
2942 set_uri_nscontainer(ret, container);
2943 set_uri_window(ret, window);
2944
2945 IUri_AddRef(iuri);
2946 ret->uri = iuri;
2947
2948 hres = IUri_GetScheme(iuri, &ret->scheme);
2949 if(FAILED(hres))
2950 ret->scheme = URL_SCHEME_UNKNOWN;
2951
2952 if(origin_charset && *origin_charset && strcmp(origin_charset, "UTF-8")) {
2953 ret->origin_charset = heap_strdupA(origin_charset);
2954 if(!ret->origin_charset) {
2955 nsIFileURL_Release(&ret->nsIFileURL_iface);
2956 return NS_ERROR_OUT_OF_MEMORY;
2957 }
2958 }
2959
2960 TRACE("retval=%p\n", ret);
2961 *_retval = ret;
2962 return NS_OK;
2963 }
2964
2965 HRESULT create_doc_uri(HTMLOuterWindow *window, IUri *iuri, nsWineURI **ret)
2966 {
2967 nsWineURI *uri;
2968 nsresult nsres;
2969
2970 nsres = create_nsuri(iuri, window, window->doc_obj->nscontainer, NULL, &uri);
2971 if(NS_FAILED(nsres))
2972 return E_FAIL;
2973
2974 uri->is_doc_uri = TRUE;
2975
2976 *ret = uri;
2977 return S_OK;
2978 }
2979
2980 static nsresult create_nschannel(nsWineURI *uri, nsChannel **ret)
2981 {
2982 nsChannel *channel;
2983
2984 if(!ensure_uri(uri))
2985 return NS_ERROR_UNEXPECTED;
2986
2987 channel = heap_alloc_zero(sizeof(nsChannel));
2988 if(!channel)
2989 return NS_ERROR_OUT_OF_MEMORY;
2990
2991 channel->nsIHttpChannel_iface.lpVtbl = &nsChannelVtbl;
2992 channel->nsIUploadChannel_iface.lpVtbl = &nsUploadChannelVtbl;
2993 channel->nsIHttpChannelInternal_iface.lpVtbl = &nsHttpChannelInternalVtbl;
2994 channel->ref = 1;
2995 channel->request_method = METHOD_GET;
2996 list_init(&channel->response_headers);
2997 list_init(&channel->request_headers);
2998
2999 nsIFileURL_AddRef(&uri->nsIFileURL_iface);
3000 channel->uri = uri;
3001
3002 *ret = channel;
3003 return NS_OK;
3004 }
3005
3006 HRESULT create_redirect_nschannel(const WCHAR *url, nsChannel *orig_channel, nsChannel **ret)
3007 {
3008 HTMLOuterWindow *window = NULL;
3009 nsChannel *channel;
3010 nsWineURI *uri;
3011 IUri *iuri;
3012 nsresult nsres;
3013 HRESULT hres;
3014
3015 hres = create_uri(url, 0, &iuri);
3016 if(FAILED(hres))
3017 return hres;
3018
3019 if(orig_channel->uri->window_ref)
3020 window = orig_channel->uri->window_ref->window;
3021 nsres = create_nsuri(iuri, window, NULL, NULL, &uri);
3022 IUri_Release(iuri);
3023 if(NS_FAILED(nsres))
3024 return E_FAIL;
3025
3026 nsres = create_nschannel(uri, &channel);
3027 nsIFileURL_Release(&uri->nsIFileURL_iface);
3028 if(NS_FAILED(nsres))
3029 return E_FAIL;
3030
3031 if(orig_channel->load_group) {
3032 nsILoadGroup_AddRef(orig_channel->load_group);
3033 channel->load_group = orig_channel->load_group;
3034 }
3035
3036 if(orig_channel->notif_callback) {
3037 nsIInterfaceRequestor_AddRef(orig_channel->notif_callback);
3038 channel->notif_callback = orig_channel->notif_callback;
3039 }
3040
3041 channel->load_flags = orig_channel->load_flags | LOAD_REPLACE;
3042
3043 if(orig_channel->request_method == METHOD_POST)
3044 FIXME("unsupported POST method\n");
3045
3046 if(orig_channel->original_uri) {
3047 nsIURI_AddRef(orig_channel->original_uri);
3048 channel->original_uri = orig_channel->original_uri;
3049 }
3050
3051 if(orig_channel->referrer) {
3052 nsIURI_AddRef(orig_channel->referrer);
3053 channel->referrer = orig_channel->referrer;
3054 }
3055
3056 *ret = channel;
3057 return S_OK;
3058 }
3059
3060 typedef struct {
3061 nsIProtocolHandler nsIProtocolHandler_iface;
3062
3063 LONG ref;
3064
3065 nsIProtocolHandler *nshandler;
3066 } nsProtocolHandler;
3067
3068 static inline nsProtocolHandler *impl_from_nsIProtocolHandler(nsIProtocolHandler *iface)
3069 {
3070 return CONTAINING_RECORD(iface, nsProtocolHandler, nsIProtocolHandler_iface);
3071 }
3072
3073 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
3074 void **result)
3075 {
3076 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3077
3078 *result = NULL;
3079
3080 if(IsEqualGUID(&IID_nsISupports, riid)) {
3081 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
3082 *result = &This->nsIProtocolHandler_iface;
3083 }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
3084 TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
3085 *result = &This->nsIProtocolHandler_iface;
3086 }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
3087 TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
3088 return NS_NOINTERFACE;
3089 }
3090
3091 if(*result) {
3092 nsISupports_AddRef((nsISupports*)*result);
3093 return NS_OK;
3094 }
3095
3096 WARN("(%s %p)\n", debugstr_guid(riid), result);
3097 return NS_NOINTERFACE;
3098 }
3099
3100 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
3101 {
3102 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3103 LONG ref = InterlockedIncrement(&This->ref);
3104
3105 TRACE("(%p) ref=%d\n", This, ref);
3106
3107 return ref;
3108 }
3109
3110 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
3111 {
3112 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3113 LONG ref = InterlockedDecrement(&This->ref);
3114
3115 TRACE("(%p) ref=%d\n", This, ref);
3116
3117 if(!ref) {
3118 if(This->nshandler)
3119 nsIProtocolHandler_Release(This->nshandler);
3120 heap_free(This);
3121 }
3122
3123 return ref;
3124 }
3125
3126 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
3127 {
3128 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3129
3130 TRACE("(%p)->(%p)\n", This, aScheme);
3131
3132 if(This->nshandler)
3133 return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
3134 return NS_ERROR_NOT_IMPLEMENTED;
3135 }
3136
3137 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
3138 LONG *aDefaultPort)
3139 {
3140 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3141
3142 TRACE("(%p)->(%p)\n", This, aDefaultPort);
3143
3144 if(This->nshandler)
3145 return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
3146 return NS_ERROR_NOT_IMPLEMENTED;
3147 }
3148
3149 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
3150 UINT32 *aProtocolFlags)
3151 {
3152 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3153
3154 TRACE("(%p)->(%p)\n", This, aProtocolFlags);
3155
3156 if(This->nshandler)
3157 return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
3158 return NS_ERROR_NOT_IMPLEMENTED;
3159 }
3160
3161 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
3162 const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3163 {
3164 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3165
3166 TRACE("((%p)->%s %s %p %p)\n", This, debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3167 aBaseURI, _retval);
3168
3169 if(This->nshandler)
3170 return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
3171 return NS_ERROR_NOT_IMPLEMENTED;
3172 }
3173
3174 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
3175 nsIURI *aURI, nsIChannel **_retval)
3176 {
3177 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3178
3179 TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
3180
3181 if(This->nshandler)
3182 return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
3183 return NS_ERROR_NOT_IMPLEMENTED;
3184 }
3185
3186 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
3187 LONG port, const char *scheme, cpp_bool *_retval)
3188 {
3189 nsProtocolHandler *This = impl_from_nsIProtocolHandler(iface);
3190
3191 TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
3192
3193 if(This->nshandler)
3194 return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
3195 return NS_ERROR_NOT_IMPLEMENTED;
3196 }
3197
3198 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
3199 nsProtocolHandler_QueryInterface,
3200 nsProtocolHandler_AddRef,
3201 nsProtocolHandler_Release,
3202 nsProtocolHandler_GetScheme,
3203 nsProtocolHandler_GetDefaultPort,
3204 nsProtocolHandler_GetProtocolFlags,
3205 nsProtocolHandler_NewURI,
3206 nsProtocolHandler_NewChannel,
3207 nsProtocolHandler_AllowPort
3208 };
3209
3210 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService*,nsIIDRef,void**);
3211
3212 static nsrefcnt NSAPI nsIOService_AddRef(nsIIOService *iface)
3213 {
3214 return 2;
3215 }
3216
3217 static nsrefcnt NSAPI nsIOService_Release(nsIIOService *iface)
3218 {
3219 return 1;
3220 }
3221
3222 static nsresult NSAPI nsIOService_GetProtocolHandler(nsIIOService *iface, const char *aScheme,
3223 nsIProtocolHandler **_retval)
3224 {
3225 nsIExternalProtocolHandler *nsexthandler;
3226 nsIProtocolHandler *nshandler;
3227 nsProtocolHandler *ret;
3228 nsresult nsres;
3229
3230 TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
3231
3232 nsres = nsIIOService_GetProtocolHandler(nsio, aScheme, &nshandler);
3233 if(NS_FAILED(nsres)) {
3234 WARN("GetProtocolHandler failed: %08x\n", nsres);
3235 return nsres;
3236 }
3237
3238 nsres = nsIProtocolHandler_QueryInterface(nshandler, &IID_nsIExternalProtocolHandler,
3239 (void**)&nsexthandler);
3240 if(NS_FAILED(nsres)) {
3241 *_retval = nshandler;
3242 return NS_OK;
3243 }
3244
3245 nsIExternalProtocolHandler_Release(nsexthandler);
3246
3247 ret = heap_alloc(sizeof(nsProtocolHandler));
3248 if(!ret)
3249 return NS_ERROR_OUT_OF_MEMORY;
3250
3251 ret->nsIProtocolHandler_iface.lpVtbl = &nsProtocolHandlerVtbl;
3252 ret->ref = 1;
3253 ret->nshandler = nshandler;
3254 *_retval = &ret->nsIProtocolHandler_iface;
3255
3256 TRACE("return %p\n", *_retval);
3257 return NS_OK;
3258 }
3259
3260 static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const char *aScheme,
3261 UINT32 *_retval)
3262 {
3263 TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
3264 return nsIIOService_GetProtocolFlags(nsio, aScheme, _retval);
3265 }
3266
3267 static BOOL is_gecko_special_uri(const char *spec)
3268 {
3269 static const char *special_schemes[] = {"chrome:", "jar:", "moz-safe-about", "resource:", "javascript:", "wyciwyg:"};
3270 unsigned int i;
3271
3272 for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
3273 if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
3274 return TRUE;
3275 }
3276
3277 if(!strncasecmp(spec, "file:", 5)) {
3278 const char *ptr = spec+5;
3279 while(*ptr == '/')
3280 ptr++;
3281 return is_gecko_path(ptr);
3282 }
3283
3284 return FALSE;
3285 }
3286
3287 static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *aSpec,
3288 const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
3289 {
3290 nsWineURI *wine_uri, *base_wine_uri = NULL;
3291 WCHAR new_spec[INTERNET_MAX_URL_LENGTH];
3292 HTMLOuterWindow *window = NULL;
3293 const char *spec = NULL;
3294 IUri *urlmon_uri;
3295 nsresult nsres;
3296 HRESULT hres;
3297
3298 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset),
3299 aBaseURI, _retval);
3300
3301 nsACString_GetData(aSpec, &spec);
3302 if(is_gecko_special_uri(spec))
3303 return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3304
3305 if(!strncmp(spec, "wine:", 5))
3306 spec += 5;
3307
3308 if(aBaseURI) {
3309 nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
3310 if(NS_SUCCEEDED(nsres)) {
3311 if(!ensure_uri(base_wine_uri))
3312 return NS_ERROR_UNEXPECTED;
3313 if(base_wine_uri->window_ref)
3314 window = base_wine_uri->window_ref->window;
3315 }else {
3316 WARN("Could not get base nsWineURI: %08x\n", nsres);
3317 }
3318 }
3319
3320 MultiByteToWideChar(CP_ACP, 0, spec, -1, new_spec, sizeof(new_spec)/sizeof(WCHAR));
3321
3322 if(base_wine_uri) {
3323 hres = CoInternetCombineUrlEx(base_wine_uri->uri, new_spec, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
3324 &urlmon_uri, 0);
3325 if(FAILED(hres))
3326 WARN("CoInternetCombineUrlEx failed: %08x\n", hres);
3327 }else {
3328 hres = create_uri(new_spec, 0, &urlmon_uri);
3329 if(FAILED(hres))
3330 WARN("create_uri failed: %08x\n", hres);
3331 }
3332
3333 if(FAILED(hres))
3334 return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3335
3336 nsres = create_nsuri(urlmon_uri, window, NULL, NULL, &wine_uri);
3337 IUri_Release(urlmon_uri);
3338 if(base_wine_uri)
3339 nsIFileURL_Release(&base_wine_uri->nsIFileURL_iface);
3340 if(NS_FAILED(nsres))
3341 return nsres;
3342
3343 *_retval = (nsIURI*)&wine_uri->nsIFileURL_iface;
3344 return nsres;
3345 }
3346
3347 static nsresult NSAPI nsIOService_NewFileURI(nsIIOService *iface, nsIFile *aFile,
3348 nsIURI **_retval)
3349 {
3350 TRACE("(%p %p)\n", aFile, _retval);
3351 return nsIIOService_NewFileURI(nsio, aFile, _retval);
3352 }
3353
3354 static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI *aURI,
3355 nsIChannel **_retval)
3356 {
3357 nsWineURI *wine_uri;
3358 nsChannel *ret;
3359 nsresult nsres;
3360
3361 TRACE("(%p %p)\n", aURI, _retval);
3362
3363 nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
3364 if(NS_FAILED(nsres)) {
3365 TRACE("Could not get nsWineURI: %08x\n", nsres);
3366 return nsIIOService_NewChannelFromURI(nsio, aURI, _retval);
3367 }
3368
3369 nsres = create_nschannel(wine_uri, &ret);
3370 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3371 if(NS_FAILED(nsres))
3372 return nsres;
3373
3374 nsIURI_AddRef(aURI);
3375 ret->original_uri = aURI;
3376
3377 *_retval = (nsIChannel*)&ret->nsIHttpChannel_iface;
3378 return NS_OK;
3379 }
3380
3381 static nsresult NSAPI nsIOService_NewChannel(nsIIOService *iface, const nsACString *aSpec,
3382 const char *aOriginCharset, nsIURI *aBaseURI, nsIChannel **_retval)
3383 {
3384 TRACE("(%s %s %p %p)\n", debugstr_nsacstr(aSpec), debugstr_a(aOriginCharset), aBaseURI, _retval);
3385 return nsIIOService_NewChannel(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
3386 }
3387
3388 static nsresult NSAPI nsIOService_GetOffline(nsIIOService *iface, cpp_bool *aOffline)
3389 {
3390 TRACE("(%p)\n", aOffline);
3391 return nsIIOService_GetOffline(nsio, aOffline);
3392 }
3393
3394 static nsresult NSAPI nsIOService_SetOffline(nsIIOService *iface, cpp_bool aOffline)
3395 {
3396 TRACE("(%x)\n", aOffline);
3397 return nsIIOService_SetOffline(nsio, aOffline);
3398 }
3399
3400 static nsresult NSAPI nsIOService_AllowPort(nsIIOService *iface, LONG aPort,
3401 const char *aScheme, cpp_bool *_retval)
3402 {
3403 TRACE("(%d %s %p)\n", aPort, debugstr_a(aScheme), _retval);
3404 return nsIIOService_AllowPort(nsio, aPort, debugstr_a(aScheme), _retval);
3405 }
3406
3407 static nsresult NSAPI nsIOService_ExtractScheme(nsIIOService *iface, const nsACString *urlString,
3408 nsACString * _retval)
3409 {
3410 TRACE("(%s %p)\n", debugstr_nsacstr(urlString), _retval);
3411 return nsIIOService_ExtractScheme(nsio, urlString, _retval);
3412 }
3413
3414 static const nsIIOServiceVtbl nsIOServiceVtbl = {
3415 nsIOService_QueryInterface,
3416 nsIOService_AddRef,
3417 nsIOService_Release,
3418 nsIOService_GetProtocolHandler,
3419 nsIOService_GetProtocolFlags,
3420 nsIOService_NewURI,
3421 nsIOService_NewFileURI,
3422 nsIOService_NewChannelFromURI,
3423 nsIOService_NewChannel,
3424 nsIOService_GetOffline,
3425 nsIOService_SetOffline,
3426 nsIOService_AllowPort,
3427 nsIOService_ExtractScheme
3428 };
3429
3430 static nsIIOService nsIOService = { &nsIOServiceVtbl };
3431
3432 static nsresult NSAPI nsNetUtil_QueryInterface(nsINetUtil *iface, nsIIDRef riid,
3433 void **result)
3434 {
3435 return nsIIOService_QueryInterface(&nsIOService, riid, result);
3436 }
3437
3438 static nsrefcnt NSAPI nsNetUtil_AddRef(nsINetUtil *iface)
3439 {
3440 return 2;
3441 }
3442
3443 static nsrefcnt NSAPI nsNetUtil_Release(nsINetUtil *iface)
3444 {
3445 return 1;
3446 }
3447
3448 static nsresult NSAPI nsNetUtil_ParseContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
3449 nsACString *aCharset, cpp_bool *aHadCharset, nsACString *aContentType)
3450 {
3451 TRACE("(%s %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aHadCharset, aContentType);
3452
3453 return nsINetUtil_ParseContentType(net_util, aTypeHeader, aCharset, aHadCharset, aContentType);
3454 }
3455
3456 static nsresult NSAPI nsNetUtil_ProtocolHasFlags(nsINetUtil *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3457 {
3458 TRACE("()\n");
3459
3460 return nsINetUtil_ProtocolHasFlags(net_util, aURI, aFlags, _retval);
3461 }
3462
3463 static nsresult NSAPI nsNetUtil_URIChainHasFlags(nsINetUtil *iface, nsIURI *aURI, UINT32 aFlags, cpp_bool *_retval)
3464 {
3465 TRACE("(%p %08x %p)\n", aURI, aFlags, _retval);
3466
3467 if(aFlags == (1<<11)) {
3468 *_retval = FALSE;
3469 return NS_OK;
3470 }
3471
3472 return nsINetUtil_URIChainHasFlags(net_util, aURI, aFlags, _retval);
3473 }
3474
3475 static nsresult NSAPI nsNetUtil_ToImmutableURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
3476 {
3477 TRACE("(%p %p)\n", aURI, _retval);
3478
3479 return nsINetUtil_ToImmutableURI(net_util, aURI, _retval);
3480 }
3481
3482 static nsresult NSAPI nsNetUtil_NewSimpleNestedURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
3483 {
3484 TRACE("(%p %p)\n", aURI, _retval);
3485
3486 return nsINetUtil_NewSimpleNestedURI(net_util, aURI, _retval);
3487 }
3488
3489 static nsresult NSAPI nsNetUtil_EscapeString(nsINetUtil *iface, const nsACString *aString,
3490 UINT32 aEscapeType, nsACString *_retval)
3491 {
3492 TRACE("(%s %x %p)\n", debugstr_nsacstr(aString), aEscapeType, _retval);
3493
3494 return nsINetUtil_EscapeString(net_util, aString, aEscapeType, _retval);
3495 }
3496
3497 static nsresult NSAPI nsNetUtil_EscapeURL(nsINetUtil *iface, const nsACString *aStr, UINT32 aFlags,
3498 nsACString *_retval)
3499 {
3500 TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval);
3501
3502 return nsINetUtil_EscapeURL(net_util, aStr, aFlags, _retval);
3503 }
3504
3505 static nsresult NSAPI nsNetUtil_UnescapeString(nsINetUtil *iface, const nsACString *aStr,
3506 UINT32 aFlags, nsACString *_retval)
3507 {
3508 TRACE("(%s %08x %p)\n", debugstr_nsacstr(aStr), aFlags, _retval);
3509
3510 return nsINetUtil_UnescapeString(net_util, aStr, aFlags, _retval);
3511 }
3512
3513 static nsresult NSAPI nsNetUtil_ExtractCharsetFromContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
3514 nsACString *aCharset, LONG *aCharsetStart, LONG *aCharsetEnd, cpp_bool *_retval)
3515 {
3516 TRACE("(%s %p %p %p %p)\n", debugstr_nsacstr(aTypeHeader), aCharset, aCharsetStart,
3517 aCharsetEnd, _retval);
3518
3519 return nsINetUtil_ExtractCharsetFromContentType(net_util, aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
3520 }
3521
3522 static const nsINetUtilVtbl nsNetUtilVtbl = {
3523 nsNetUtil_QueryInterface,
3524 nsNetUtil_AddRef,
3525 nsNetUtil_Release,
3526 nsNetUtil_ParseContentType,
3527 nsNetUtil_ProtocolHasFlags,
3528 nsNetUtil_URIChainHasFlags,
3529 nsNetUtil_ToImmutableURI,
3530 nsNetUtil_NewSimpleNestedURI,
3531 nsNetUtil_EscapeString,
3532 nsNetUtil_EscapeURL,
3533 nsNetUtil_UnescapeString,
3534 nsNetUtil_ExtractCharsetFromContentType
3535 };
3536
3537 static nsINetUtil nsNetUtil = { &nsNetUtilVtbl };
3538
3539 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService *iface, nsIIDRef riid,
3540 void **result)
3541 {
3542 *result = NULL;
3543
3544 if(IsEqualGUID(&IID_nsISupports, riid))
3545 *result = &nsIOService;
3546 else if(IsEqualGUID(&IID_nsIIOService, riid))
3547 *result = &nsIOService;
3548 else if(IsEqualGUID(&IID_nsINetUtil, riid))
3549 *result = &nsNetUtil;
3550
3551 if(*result) {
3552 nsISupports_AddRef((nsISupports*)*result);
3553 return NS_OK;
3554 }
3555
3556 FIXME("(%s %p)\n", debugstr_guid(riid), result);
3557 return NS_NOINTERFACE;
3558 }
3559
3560 static nsresult NSAPI nsIOServiceFactory_QueryInterface(nsIFactory *iface, nsIIDRef riid,
3561 void **result)
3562 {
3563 *result = NULL;
3564
3565 if(IsEqualGUID(&IID_nsISupports, riid)) {
3566 TRACE("(IID_nsISupports %p)\n", result);
3567 *result = iface;
3568 }else if(IsEqualGUID(&IID_nsIFactory, riid)) {
3569 TRACE("(IID_nsIFactory %p)\n", result);
3570 *result = iface;
3571 }
3572
3573 if(*result) {
3574 nsIFactory_AddRef(iface);
3575 return NS_OK;
3576 }
3577
3578 WARN("(%s %p)\n", debugstr_guid(riid), result);
3579 return NS_NOINTERFACE;
3580 }
3581
3582 static nsrefcnt NSAPI nsIOServiceFactory_AddRef(nsIFactory *iface)
3583 {
3584 return 2;
3585 }
3586
3587 static nsrefcnt NSAPI nsIOServiceFactory_Release(nsIFactory *iface)
3588 {
3589 return 1;
3590 }
3591
3592 static nsresult NSAPI nsIOServiceFactory_CreateInstance(nsIFactory *iface,
3593 nsISupports *aOuter, const nsIID *iid, void **result)
3594 {
3595 return nsIIOService_QueryInterface(&nsIOService, iid, result);
3596 }
3597
3598 static nsresult NSAPI nsIOServiceFactory_LockFactory(nsIFactory *iface, cpp_bool lock)
3599 {
3600 WARN("(%x)\n", lock);
3601 return NS_OK;
3602 }
3603
3604 static const nsIFactoryVtbl nsIOServiceFactoryVtbl = {
3605 nsIOServiceFactory_QueryInterface,
3606 nsIOServiceFactory_AddRef,
3607 nsIOServiceFactory_Release,
3608 nsIOServiceFactory_CreateInstance,
3609 nsIOServiceFactory_LockFactory
3610 };
3611
3612 static nsIFactory nsIOServiceFactory = { &nsIOServiceFactoryVtbl };
3613
3614 static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri)
3615 {
3616 OLECHAR *new_url = NULL;
3617 WCHAR *url;
3618 BOOL ret = FALSE;
3619 HRESULT hres;
3620
3621 if(!doc->hostui || !ensure_uri(uri))
3622 return FALSE;
3623
3624 hres = IUri_GetDisplayUri(uri->uri, &url);
3625 if(FAILED(hres))
3626 return FALSE;
3627
3628 hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
3629 if(hres == S_OK && new_url) {
3630 if(strcmpW(url, new_url)) {
3631 FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
3632 ret = TRUE;
3633 }
3634 CoTaskMemFree(new_url);
3635 }
3636
3637 SysFreeString(url);
3638 return ret;
3639 }
3640
3641 nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, cpp_bool *_retval)
3642 {
3643 nsWineURI *wine_uri;
3644 nsresult nsres;
3645
3646 *_retval = FALSE;
3647
3648 nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
3649 if(NS_FAILED(nsres)) {
3650 WARN("Could not get nsWineURI: %08x\n", nsres);
3651 return NS_ERROR_NOT_IMPLEMENTED;
3652 }
3653
3654 if(!wine_uri->is_doc_uri) {
3655 wine_uri->is_doc_uri = TRUE;
3656
3657 if(!wine_uri->container) {
3658 nsIWebBrowserChrome_AddRef(&nscontainer->nsIWebBrowserChrome_iface);
3659 wine_uri->container = nscontainer;
3660 }
3661
3662 if(nscontainer->doc)
3663 *_retval = translate_url(nscontainer->doc, wine_uri);
3664 }
3665
3666 nsIFileURL_Release(&wine_uri->nsIFileURL_iface);
3667 return NS_OK;
3668 }
3669
3670 void init_nsio(nsIComponentManager *component_manager, nsIComponentRegistrar *registrar)
3671 {
3672 nsIFactory *old_factory = NULL;
3673 nsresult nsres;
3674
3675 nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
3676 &IID_nsIFactory, (void**)&old_factory);
3677 if(NS_FAILED(nsres)) {
3678 ERR("Could not get factory: %08x\n", nsres);
3679 return;
3680 }
3681
3682 nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
3683 if(NS_FAILED(nsres)) {
3684 ERR("Couldn not create nsIOService instance %08x\n", nsres);
3685 nsIFactory_Release(old_factory);
3686 return;
3687 }
3688
3689 nsres = nsIIOService_QueryInterface(nsio, &IID_nsINetUtil, (void**)&net_util);
3690 if(NS_FAILED(nsres)) {
3691 WARN("Could not get nsINetUtil interface: %08x\n", nsres);
3692 nsIIOService_Release(nsio);
3693 return;
3694 }
3695
3696 nsres = nsIComponentRegistrar_UnregisterFactory(registrar, &NS_IOSERVICE_CID, old_factory);
3697 nsIFactory_Release(old_factory);
3698 if(NS_FAILED(nsres))
3699 ERR("UnregisterFactory failed: %08x\n", nsres);
3700
3701 nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_IOSERVICE_CID,
3702 NS_IOSERVICE_CLASSNAME, NS_IOSERVICE_CONTRACTID, &nsIOServiceFactory);
3703 if(NS_FAILED(nsres))
3704 ERR("RegisterFactory failed: %08x\n", nsres);
3705 }
3706
3707 void release_nsio(void)
3708 {
3709 if(net_util) {
3710 nsINetUtil_Release(net_util);
3711 net_util = NULL;
3712 }
3713
3714 if(nsio) {
3715 nsIIOService_Release(nsio);
3716 nsio = NULL;
3717 }
3718 }