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