ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nsio.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2007 Jacek Caban for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include "config.h"
00020 
00021 #include <stdarg.h>
00022 
00023 #define COBJMACROS
00024 
00025 #include "windef.h"
00026 #include "winbase.h"
00027 #include "winuser.h"
00028 #include "winreg.h"
00029 #include "ole2.h"
00030 #include "shlguid.h"
00031 #include "wininet.h"
00032 #include "shlwapi.h"
00033 
00034 #include "wine/debug.h"
00035 #include "wine/unicode.h"
00036 
00037 #include "mshtml_private.h"
00038 
00039 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
00040 
00041 #define NS_IOSERVICE_CLASSNAME "nsIOService"
00042 #define NS_IOSERVICE_CONTRACTID "@mozilla.org/network/io-service;1"
00043 
00044 static const IID NS_IOSERVICE_CID =
00045     {0x9ac9e770, 0x18bc, 0x11d3, {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40}};
00046 static const IID IID_nsWineURI =
00047     {0x5088272e, 0x900b, 0x11da, {0xc6,0x87, 0x00,0x0f,0xea,0x57,0xf2,0x1a}};
00048 
00049 static nsIIOService *nsio = NULL;
00050 static nsINetUtil *net_util;
00051 
00052 static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
00053 
00054 struct  nsWineURI {
00055     const nsIURLVtbl *lpIURLVtbl;
00056 
00057     LONG ref;
00058 
00059     nsIURI *uri;
00060     nsIURL *nsurl;
00061     NSContainer *container;
00062     windowref_t *window_ref;
00063     nsChannelBSC *channel_bsc;
00064     LPWSTR wine_url;
00065     BOOL is_doc_uri;
00066     BOOL use_wine_url;
00067 };
00068 
00069 #define NSURI(x)  ((nsIURI*)  &(x)->lpIURLVtbl)
00070 #define NSURL(x)  ((nsIURL*)  &(x)->lpIURLVtbl)
00071 
00072 static nsresult create_uri(nsIURI*,HTMLWindow*,NSContainer*,nsWineURI**);
00073 
00074 static const char *debugstr_nsacstr(const nsACString *nsstr)
00075 {
00076     const char *data;
00077 
00078     nsACString_GetData(nsstr, &data);
00079     return debugstr_a(data);
00080 }
00081 
00082 HRESULT nsuri_to_url(LPCWSTR nsuri, BOOL ret_empty, BSTR *ret)
00083 {
00084     const WCHAR *ptr = nsuri;
00085 
00086     static const WCHAR wine_prefixW[] = {'w','i','n','e',':'};
00087 
00088     if(!strncmpW(nsuri, wine_prefixW, sizeof(wine_prefixW)/sizeof(WCHAR)))
00089         ptr += sizeof(wine_prefixW)/sizeof(WCHAR);
00090 
00091     if(*ptr || ret_empty) {
00092         *ret = SysAllocString(ptr);
00093         if(!*ret)
00094             return E_OUTOFMEMORY;
00095     }else {
00096         *ret = NULL;
00097     }
00098 
00099     TRACE("%s -> %s\n", debugstr_w(nsuri), debugstr_w(*ret));
00100     return S_OK;
00101 }
00102 
00103 static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, LPCWSTR url)
00104 {
00105     IOleCommandTarget *cmdtrg = NULL;
00106     HRESULT hres;
00107 
00108     hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&cmdtrg);
00109     if(SUCCEEDED(hres)) {
00110         VARIANT varUrl, varRes;
00111 
00112         V_VT(&varUrl) = VT_BSTR;
00113         V_BSTR(&varUrl) = SysAllocString(url);
00114         V_VT(&varRes) = VT_BOOL;
00115 
00116         hres = IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 67, 0, &varUrl, &varRes);
00117 
00118         IOleCommandTarget_Release(cmdtrg);
00119         SysFreeString(V_BSTR(&varUrl));
00120 
00121         if(SUCCEEDED(hres) && !V_BOOL(&varRes)) {
00122             TRACE("got VARIANT_FALSE, do not load\n");
00123             return FALSE;
00124         }
00125     }
00126 
00127     return TRUE;
00128 }
00129 
00130 static BOOL before_async_open(nsChannel *channel, NSContainer *container)
00131 {
00132     HTMLDocumentObj *doc = container->doc;
00133     DWORD hlnf = 0;
00134     BOOL cancel;
00135     HRESULT hres;
00136 
00137     if(!doc) {
00138         NSContainer *container_iter = container;
00139 
00140         hlnf = HLNF_OPENINNEWWINDOW;
00141         while(!container_iter->doc)
00142             container_iter = container_iter->parent;
00143         doc = container_iter->doc;
00144     }
00145 
00146     if(!doc->client)
00147         return TRUE;
00148 
00149     if(!hlnf && !exec_shldocvw_67(doc, channel->uri->wine_url))
00150         return FALSE;
00151 
00152     hres = hlink_frame_navigate(&doc->basedoc, channel->uri->wine_url, channel->post_data_stream, hlnf, &cancel);
00153     return FAILED(hres) || cancel;
00154 }
00155 
00156 HRESULT load_nsuri(HTMLWindow *window, nsWineURI *uri, nsChannelBSC *channelbsc, DWORD flags)
00157 {
00158     nsIWebNavigation *web_navigation;
00159     nsIDocShell *doc_shell;
00160     nsresult nsres;
00161 
00162     nsres = get_nsinterface((nsISupports*)window->nswindow, &IID_nsIWebNavigation, (void**)&web_navigation);
00163     if(NS_FAILED(nsres)) {
00164         ERR("Could not get nsIWebNavigation interface: %08x\n", nsres);
00165         return E_FAIL;
00166     }
00167 
00168     nsres = nsIWebNavigation_QueryInterface(web_navigation, &IID_nsIDocShell, (void**)&doc_shell);
00169     nsIWebNavigation_Release(web_navigation);
00170     if(NS_FAILED(nsres)) {
00171         ERR("Could not get nsIDocShell: %08x\n", nsres);
00172         return E_FAIL;
00173     }
00174 
00175 
00176     uri->channel_bsc = channelbsc;
00177     nsres = nsIDocShell_LoadURI(doc_shell, NSURI(uri), NULL, flags, FALSE);
00178     uri->channel_bsc = NULL;
00179     nsIDocShell_Release(doc_shell);
00180     if(NS_FAILED(nsres)) {
00181         WARN("LoadURI failed: %08x\n", nsres);
00182         return E_FAIL;
00183     }
00184 
00185     return S_OK;
00186 }
00187 
00188 static BOOL translate_url(HTMLDocumentObj *doc, nsWineURI *uri)
00189 {
00190     OLECHAR *new_url = NULL, *url;
00191     BOOL ret = FALSE;
00192     HRESULT hres;
00193 
00194     if(!doc->hostui)
00195         return FALSE;
00196 
00197     url = heap_strdupW(uri->wine_url);
00198     hres = IDocHostUIHandler_TranslateUrl(doc->hostui, 0, url, &new_url);
00199     if(hres == S_OK && new_url) {
00200         if(strcmpW(url, new_url)) {
00201             FIXME("TranslateUrl returned new URL %s -> %s\n", debugstr_w(url), debugstr_w(new_url));
00202             ret = TRUE;
00203         }
00204         CoTaskMemFree(new_url);
00205     }
00206 
00207     heap_free(url);
00208     return ret;
00209 }
00210 
00211 nsresult on_start_uri_open(NSContainer *nscontainer, nsIURI *uri, PRBool *_retval)
00212 {
00213     nsWineURI *wine_uri;
00214     nsresult nsres;
00215 
00216     *_retval = FALSE;
00217 
00218     nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
00219     if(NS_FAILED(nsres)) {
00220         WARN("Could not get nsWineURI: %08x\n", nsres);
00221         return NS_ERROR_NOT_IMPLEMENTED;
00222     }
00223 
00224     if(!wine_uri->is_doc_uri) {
00225         wine_uri->is_doc_uri = TRUE;
00226 
00227         if(!wine_uri->container) {
00228             nsIWebBrowserChrome_AddRef(NSWBCHROME(nscontainer));
00229             wine_uri->container = nscontainer;
00230         }
00231 
00232         if(nscontainer->doc)
00233             *_retval = translate_url(nscontainer->doc, wine_uri);
00234     }
00235 
00236     nsIURI_Release(NSURI(wine_uri));
00237     return NS_OK;
00238 }
00239 
00240 HRESULT set_wine_url(nsWineURI *This, LPCWSTR url)
00241 {
00242     static const WCHAR wszFtp[]   = {'f','t','p',':'};
00243     static const WCHAR wszHttp[]  = {'h','t','t','p',':'};
00244     static const WCHAR wszHttps[] = {'h','t','t','p','s',':'};
00245 
00246     TRACE("(%p)->(%s)\n", This, debugstr_w(url));
00247 
00248     if(url) {
00249         WCHAR *new_url;
00250 
00251         new_url = heap_strdupW(url);
00252         if(!new_url)
00253             return E_OUTOFMEMORY;
00254         heap_free(This->wine_url);
00255         This->wine_url = new_url;
00256 
00257         if(This->uri) {
00258             /* FIXME: Always use wine url */
00259             This->use_wine_url =
00260                    strncmpW(url, wszFtp,   sizeof(wszFtp)/sizeof(WCHAR))
00261                 && strncmpW(url, wszHttp,  sizeof(wszHttp)/sizeof(WCHAR))
00262                 && strncmpW(url, wszHttps, sizeof(wszHttps)/sizeof(WCHAR));
00263         }else {
00264             This->use_wine_url = TRUE;
00265         }
00266     }else {
00267         heap_free(This->wine_url);
00268         This->wine_url = NULL;
00269         This->use_wine_url = FALSE;
00270     }
00271 
00272     return S_OK;
00273 }
00274 
00275 static void set_uri_nscontainer(nsWineURI *This, NSContainer *nscontainer)
00276 {
00277     if(This->container) {
00278         if(This->container == nscontainer)
00279             return;
00280         TRACE("Changing %p -> %p\n", This->container, nscontainer);
00281         nsIWebBrowserChrome_Release(NSWBCHROME(This->container));
00282     }
00283 
00284     if(nscontainer)
00285         nsIWebBrowserChrome_AddRef(NSWBCHROME(nscontainer));
00286     This->container = nscontainer;
00287 }
00288 
00289 static void set_uri_window(nsWineURI *This, HTMLWindow *window)
00290 {
00291     if(This->window_ref) {
00292         if(This->window_ref->window == window)
00293             return;
00294         TRACE("Changing %p -> %p\n", This->window_ref->window, window);
00295         windowref_release(This->window_ref);
00296     }
00297 
00298     if(window) {
00299         windowref_addref(window->window_ref);
00300         This->window_ref = window->window_ref;
00301 
00302         if(window->doc_obj)
00303             set_uri_nscontainer(This, window->doc_obj->nscontainer);
00304     }else {
00305         This->window_ref = NULL;
00306     }
00307 }
00308 
00309 static inline BOOL is_http_channel(nsChannel *This)
00310 {
00311     return This->url_scheme == URL_SCHEME_HTTP || This->url_scheme == URL_SCHEME_HTTPS;
00312 }
00313 
00314 #define NSCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, HttpChannel, iface)
00315 
00316 static nsresult NSAPI nsChannel_QueryInterface(nsIHttpChannel *iface, nsIIDRef riid, nsQIResult result)
00317 {
00318     nsChannel *This = NSCHANNEL_THIS(iface);
00319 
00320     if(IsEqualGUID(&IID_nsISupports, riid)) {
00321         TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
00322         *result = NSCHANNEL(This);
00323     }else if(IsEqualGUID(&IID_nsIRequest, riid)) {
00324         TRACE("(%p)->(IID_nsIRequest %p)\n", This, result);
00325         *result = NSCHANNEL(This);
00326     }else if(IsEqualGUID(&IID_nsIChannel, riid)) {
00327         TRACE("(%p)->(IID_nsIChannel %p)\n", This, result);
00328         *result = NSCHANNEL(This);
00329     }else if(IsEqualGUID(&IID_nsIHttpChannel, riid)) {
00330         TRACE("(%p)->(IID_nsIHttpChannel %p)\n", This, result);
00331         *result = is_http_channel(This) ? NSHTTPCHANNEL(This) : NULL;
00332     }else if(IsEqualGUID(&IID_nsIUploadChannel, riid)) {
00333         TRACE("(%p)->(IID_nsIUploadChannel %p)\n", This, result);
00334         *result = NSUPCHANNEL(This);
00335     }else if(IsEqualGUID(&IID_nsIHttpChannelInternal, riid)) {
00336         TRACE("(%p)->(IID_nsIHttpChannelInternal %p)\n", This, result);
00337         *result = is_http_channel(This) ? NSHTTPINTERNAL(This) : NULL;
00338     }else {
00339         TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
00340         *result = NULL;
00341     }
00342 
00343     if(*result) {
00344         nsIChannel_AddRef(NSCHANNEL(This));
00345         return NS_OK;
00346     }
00347 
00348     return NS_NOINTERFACE;
00349 }
00350 
00351 static nsrefcnt NSAPI nsChannel_AddRef(nsIHttpChannel *iface)
00352 {
00353     nsChannel *This = NSCHANNEL_THIS(iface);
00354     nsrefcnt ref = InterlockedIncrement(&This->ref);
00355 
00356     TRACE("(%p) ref=%d\n", This, ref);
00357 
00358     return ref;
00359 }
00360 
00361 static nsrefcnt NSAPI nsChannel_Release(nsIHttpChannel *iface)
00362 {
00363     nsChannel *This = NSCHANNEL_THIS(iface);
00364     LONG ref = InterlockedDecrement(&This->ref);
00365 
00366     if(!ref) {
00367         struct ResponseHeader *header, *next_hdr;
00368 
00369         nsIURI_Release(NSURI(This->uri));
00370         if(This->owner)
00371             nsISupports_Release(This->owner);
00372         if(This->post_data_stream)
00373             nsIInputStream_Release(This->post_data_stream);
00374         if(This->load_group)
00375             nsILoadGroup_Release(This->load_group);
00376         if(This->notif_callback)
00377             nsIInterfaceRequestor_Release(This->notif_callback);
00378         if(This->original_uri)
00379             nsIURI_Release(This->original_uri);
00380         heap_free(This->content_type);
00381         heap_free(This->charset);
00382 
00383         LIST_FOR_EACH_ENTRY_SAFE(header, next_hdr, &This->response_headers, struct ResponseHeader, entry) {
00384             list_remove(&header->entry);
00385             heap_free(header->header);
00386             heap_free(header->data);
00387             heap_free(header);
00388         }
00389 
00390         heap_free(This);
00391     }
00392 
00393     return ref;
00394 }
00395 
00396 static nsresult NSAPI nsChannel_GetName(nsIHttpChannel *iface, nsACString *aName)
00397 {
00398     nsChannel *This = NSCHANNEL_THIS(iface);
00399 
00400     FIXME("(%p)->(%p)\n", This, aName);
00401 
00402     return NS_ERROR_NOT_IMPLEMENTED;
00403 }
00404 
00405 static nsresult NSAPI nsChannel_IsPending(nsIHttpChannel *iface, PRBool *_retval)
00406 {
00407     nsChannel *This = NSCHANNEL_THIS(iface);
00408 
00409     FIXME("(%p)->(%p)\n", This, _retval);
00410 
00411     return NS_ERROR_NOT_IMPLEMENTED;
00412 }
00413 
00414 static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStatus)
00415 {
00416     nsChannel *This = NSCHANNEL_THIS(iface);
00417 
00418     WARN("(%p)->(%p) returning NS_OK\n", This, aStatus);
00419 
00420     return *aStatus = NS_OK;
00421 }
00422 
00423 static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
00424 {
00425     nsChannel *This = NSCHANNEL_THIS(iface);
00426 
00427     FIXME("(%p)->(%08x)\n", This, aStatus);
00428 
00429     return NS_ERROR_NOT_IMPLEMENTED;
00430 }
00431 
00432 static nsresult NSAPI nsChannel_Suspend(nsIHttpChannel *iface)
00433 {
00434     nsChannel *This = NSCHANNEL_THIS(iface);
00435 
00436     FIXME("(%p)\n", This);
00437 
00438     return NS_ERROR_NOT_IMPLEMENTED;
00439 }
00440 
00441 static nsresult NSAPI nsChannel_Resume(nsIHttpChannel *iface)
00442 {
00443     nsChannel *This = NSCHANNEL_THIS(iface);
00444 
00445     FIXME("(%p)\n", This);
00446 
00447     return NS_ERROR_NOT_IMPLEMENTED;
00448 }
00449 
00450 static nsresult NSAPI nsChannel_GetLoadGroup(nsIHttpChannel *iface, nsILoadGroup **aLoadGroup)
00451 {
00452     nsChannel *This = NSCHANNEL_THIS(iface);
00453 
00454     TRACE("(%p)->(%p)\n", This, aLoadGroup);
00455 
00456     if(This->load_group)
00457         nsILoadGroup_AddRef(This->load_group);
00458 
00459     *aLoadGroup = This->load_group;
00460     return NS_OK;
00461 }
00462 
00463 static nsresult NSAPI nsChannel_SetLoadGroup(nsIHttpChannel *iface, nsILoadGroup *aLoadGroup)
00464 {
00465     nsChannel *This = NSCHANNEL_THIS(iface);
00466 
00467     TRACE("(%p)->(%p)\n", This, aLoadGroup);
00468 
00469     if(This->load_group)
00470         nsILoadGroup_Release(This->load_group);
00471     if(aLoadGroup)
00472         nsILoadGroup_AddRef(aLoadGroup);
00473     This->load_group = aLoadGroup;
00474 
00475     return NS_OK;
00476 }
00477 
00478 static nsresult NSAPI nsChannel_GetLoadFlags(nsIHttpChannel *iface, nsLoadFlags *aLoadFlags)
00479 {
00480     nsChannel *This = NSCHANNEL_THIS(iface);
00481 
00482     TRACE("(%p)->(%p)\n", This, aLoadFlags);
00483 
00484     *aLoadFlags = This->load_flags;
00485     return NS_OK;
00486 }
00487 
00488 static nsresult NSAPI nsChannel_SetLoadFlags(nsIHttpChannel *iface, nsLoadFlags aLoadFlags)
00489 {
00490     nsChannel *This = NSCHANNEL_THIS(iface);
00491 
00492     TRACE("(%p)->(%08x)\n", This, aLoadFlags);
00493 
00494     This->load_flags = aLoadFlags;
00495     return NS_OK;
00496 }
00497 
00498 static nsresult NSAPI nsChannel_GetOriginalURI(nsIHttpChannel *iface, nsIURI **aOriginalURI)
00499 {
00500     nsChannel *This = NSCHANNEL_THIS(iface);
00501 
00502     TRACE("(%p)->(%p)\n", This, aOriginalURI);
00503 
00504     if(This->original_uri)
00505         nsIURI_AddRef(This->original_uri);
00506 
00507     *aOriginalURI = This->original_uri;
00508     return NS_OK;
00509 }
00510 
00511 static nsresult NSAPI nsChannel_SetOriginalURI(nsIHttpChannel *iface, nsIURI *aOriginalURI)
00512 {
00513     nsChannel *This = NSCHANNEL_THIS(iface);
00514 
00515     TRACE("(%p)->(%p)\n", This, aOriginalURI);
00516 
00517     if(This->original_uri)
00518         nsIURI_Release(This->original_uri);
00519 
00520     nsIURI_AddRef(aOriginalURI);
00521     This->original_uri = aOriginalURI;
00522     return NS_OK;
00523 }
00524 
00525 static nsresult NSAPI nsChannel_GetURI(nsIHttpChannel *iface, nsIURI **aURI)
00526 {
00527     nsChannel *This = NSCHANNEL_THIS(iface);
00528 
00529     TRACE("(%p)->(%p)\n", This, aURI);
00530 
00531     nsIURI_AddRef(NSURI(This->uri));
00532     *aURI = (nsIURI*)This->uri;
00533 
00534     return NS_OK;
00535 }
00536 
00537 static nsresult NSAPI nsChannel_GetOwner(nsIHttpChannel *iface, nsISupports **aOwner)
00538 {
00539     nsChannel *This = NSCHANNEL_THIS(iface);
00540 
00541     TRACE("(%p)->(%p)\n", This, aOwner);
00542 
00543     if(This->owner)
00544         nsISupports_AddRef(This->owner);
00545     *aOwner = This->owner;
00546 
00547     return NS_OK;
00548 }
00549 
00550 static nsresult NSAPI nsChannel_SetOwner(nsIHttpChannel *iface, nsISupports *aOwner)
00551 {
00552     nsChannel *This = NSCHANNEL_THIS(iface);
00553 
00554     TRACE("(%p)->(%p)\n", This, aOwner);
00555 
00556     if(aOwner)
00557         nsISupports_AddRef(aOwner);
00558     if(This->owner)
00559         nsISupports_Release(This->owner);
00560     This->owner = aOwner;
00561 
00562     return NS_OK;
00563 }
00564 
00565 static nsresult NSAPI nsChannel_GetNotificationCallbacks(nsIHttpChannel *iface,
00566         nsIInterfaceRequestor **aNotificationCallbacks)
00567 {
00568     nsChannel *This = NSCHANNEL_THIS(iface);
00569 
00570     TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
00571 
00572     if(This->notif_callback)
00573         nsIInterfaceRequestor_AddRef(This->notif_callback);
00574     *aNotificationCallbacks = This->notif_callback;
00575 
00576     return NS_OK;
00577 }
00578 
00579 static nsresult NSAPI nsChannel_SetNotificationCallbacks(nsIHttpChannel *iface,
00580         nsIInterfaceRequestor *aNotificationCallbacks)
00581 {
00582     nsChannel *This = NSCHANNEL_THIS(iface);
00583 
00584     TRACE("(%p)->(%p)\n", This, aNotificationCallbacks);
00585 
00586     if(This->notif_callback)
00587         nsIInterfaceRequestor_Release(This->notif_callback);
00588     if(aNotificationCallbacks)
00589         nsIInterfaceRequestor_AddRef(aNotificationCallbacks);
00590 
00591     This->notif_callback = aNotificationCallbacks;
00592 
00593     return NS_OK;
00594 }
00595 
00596 static nsresult NSAPI nsChannel_GetSecurityInfo(nsIHttpChannel *iface, nsISupports **aSecurityInfo)
00597 {
00598     nsChannel *This = NSCHANNEL_THIS(iface);
00599 
00600     TRACE("(%p)->(%p)\n", This, aSecurityInfo);
00601 
00602     return NS_ERROR_NOT_IMPLEMENTED;
00603 }
00604 
00605 static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString *aContentType)
00606 {
00607     nsChannel *This = NSCHANNEL_THIS(iface);
00608 
00609     TRACE("(%p)->(%p)\n", This, aContentType);
00610 
00611     if(This->content_type) {
00612         nsACString_SetData(aContentType, This->content_type);
00613         return S_OK;
00614     }
00615 
00616     WARN("unknown type\n");
00617     return NS_ERROR_FAILURE;
00618 }
00619 
00620 static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
00621                                                const nsACString *aContentType)
00622 {
00623     nsChannel *This = NSCHANNEL_THIS(iface);
00624     const char *content_type;
00625 
00626     TRACE("(%p)->(%p)\n", This, aContentType);
00627 
00628     nsACString_GetData(aContentType, &content_type);
00629 
00630     TRACE("content_type %s\n", content_type);
00631 
00632     heap_free(This->content_type);
00633     This->content_type = heap_strdupA(content_type);
00634 
00635     return NS_OK;
00636 }
00637 
00638 static nsresult NSAPI nsChannel_GetContentCharset(nsIHttpChannel *iface,
00639                                                   nsACString *aContentCharset)
00640 {
00641     nsChannel *This = NSCHANNEL_THIS(iface);
00642 
00643     TRACE("(%p)->(%p)\n", This, aContentCharset);
00644 
00645     if(This->charset) {
00646         nsACString_SetData(aContentCharset, This->charset);
00647         return NS_OK;
00648     }
00649 
00650     nsACString_SetData(aContentCharset, "");
00651     return NS_OK;
00652 }
00653 
00654 static nsresult NSAPI nsChannel_SetContentCharset(nsIHttpChannel *iface,
00655                                                   const nsACString *aContentCharset)
00656 {
00657     nsChannel *This = NSCHANNEL_THIS(iface);
00658 
00659     FIXME("(%p)->(%p)\n", This, aContentCharset);
00660 
00661     return NS_ERROR_NOT_IMPLEMENTED;
00662 }
00663 
00664 static nsresult NSAPI nsChannel_GetContentLength(nsIHttpChannel *iface, PRInt32 *aContentLength)
00665 {
00666     nsChannel *This = NSCHANNEL_THIS(iface);
00667 
00668     FIXME("(%p)->(%p)\n", This, aContentLength);
00669 
00670     return NS_ERROR_NOT_IMPLEMENTED;
00671 }
00672 
00673 static nsresult NSAPI nsChannel_SetContentLength(nsIHttpChannel *iface, PRInt32 aContentLength)
00674 {
00675     nsChannel *This = NSCHANNEL_THIS(iface);
00676 
00677     FIXME("(%p)->(%d)\n", This, aContentLength);
00678 
00679     return NS_ERROR_NOT_IMPLEMENTED;
00680 }
00681 
00682 static nsresult NSAPI nsChannel_Open(nsIHttpChannel *iface, nsIInputStream **_retval)
00683 {
00684     nsChannel *This = NSCHANNEL_THIS(iface);
00685 
00686     FIXME("(%p)->(%p)\n", This, _retval);
00687 
00688     return NS_ERROR_NOT_IMPLEMENTED;
00689 }
00690 
00691 static HRESULT create_mon_for_nschannel(nsChannel *channel, IMoniker **mon)
00692 {
00693     nsWineURI *wine_uri;
00694     nsresult nsres;
00695     HRESULT hres;
00696 
00697     if(!channel->original_uri) {
00698         ERR("original_uri == NULL\n");
00699         return E_FAIL;
00700     }
00701 
00702     nsres = nsIURI_QueryInterface(channel->original_uri, &IID_nsWineURI, (void**)&wine_uri);
00703     if(NS_FAILED(nsres)) {
00704         ERR("Could not get nsWineURI: %08x\n", nsres);
00705         return E_FAIL;
00706     }
00707 
00708     if(wine_uri->wine_url) {
00709         hres = CreateURLMoniker(NULL, wine_uri->wine_url, mon);
00710         if(FAILED(hres))
00711             WARN("CreateURLMoniker failed: %08x\n", hres);
00712     }else {
00713         TRACE("wine_url == NULL\n");
00714         hres = E_FAIL;
00715     }
00716 
00717     nsIURI_Release(NSURI(wine_uri));
00718 
00719     return hres;
00720 }
00721 
00722 static HTMLWindow *get_window_from_load_group(nsChannel *This)
00723 {
00724     HTMLWindow *window;
00725     nsIChannel *channel;
00726     nsIRequest *req;
00727     nsWineURI *wine_uri;
00728     nsIURI *uri;
00729     nsresult nsres;
00730 
00731     nsres = nsILoadGroup_GetDefaultLoadRequest(This->load_group, &req);
00732     if(NS_FAILED(nsres)) {
00733         ERR("GetDefaultLoadRequest failed: %08x\n", nsres);
00734         return NULL;
00735     }
00736 
00737     if(!req)
00738         return NULL;
00739 
00740     nsres = nsIRequest_QueryInterface(req, &IID_nsIChannel, (void**)&channel);
00741     nsIRequest_Release(req);
00742     if(NS_FAILED(nsres)) {
00743         WARN("Could not get nsIChannel interface: %08x\n", nsres);
00744         return NULL;
00745     }
00746 
00747     nsres = nsIChannel_GetURI(channel, &uri);
00748     nsIChannel_Release(channel);
00749     if(NS_FAILED(nsres)) {
00750         ERR("GetURI failed: %08x\n", nsres);
00751         return NULL;
00752     }
00753 
00754     nsres = nsIURI_QueryInterface(uri, &IID_nsWineURI, (void**)&wine_uri);
00755     nsIURI_Release(uri);
00756     if(NS_FAILED(nsres)) {
00757         TRACE("Could not get nsWineURI: %08x\n", nsres);
00758         return NULL;
00759     }
00760 
00761     window = wine_uri->window_ref ? wine_uri->window_ref->window : NULL;
00762     if(window)
00763         IHTMLWindow2_AddRef(HTMLWINDOW2(window));
00764     nsIURI_Release(NSURI(wine_uri));
00765 
00766     return window;
00767 }
00768 
00769 static HTMLWindow *get_channel_window(nsChannel *This)
00770 {
00771     nsIRequestObserver *req_observer;
00772     nsIWebProgress *web_progress;
00773     nsIDOMWindow *nswindow;
00774     HTMLWindow *window;
00775     nsresult nsres;
00776 
00777     if(!This->load_group) {
00778         ERR("NULL load_group\n");
00779         return NULL;
00780     }
00781 
00782     nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
00783     if(NS_FAILED(nsres) || !req_observer) {
00784         ERR("GetGroupObserver failed: %08x\n", nsres);
00785         return NULL;
00786     }
00787 
00788     nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
00789     nsIRequestObserver_Release(req_observer);
00790     if(NS_FAILED(nsres)) {
00791         ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
00792         return NULL;
00793     }
00794 
00795     nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
00796     nsIWebProgress_Release(web_progress);
00797     if(NS_FAILED(nsres) || !nswindow) {
00798         ERR("GetDOMWindow failed: %08x\n", nsres);
00799         return NULL;
00800     }
00801 
00802     window = nswindow_to_window(nswindow);
00803     nsIDOMWindow_Release(nswindow);
00804 
00805     if(window)
00806         IHTMLWindow2_AddRef(HTMLWINDOW2(window));
00807     else
00808         FIXME("NULL window for %p\n", nswindow);
00809     return window;
00810 }
00811 
00812 typedef struct {
00813     task_t header;
00814     HTMLDocumentNode *doc;
00815     nsChannelBSC *bscallback;
00816 } start_binding_task_t;
00817 
00818 static void start_binding_proc(task_t *_task)
00819 {
00820     start_binding_task_t *task = (start_binding_task_t*)_task;
00821 
00822     start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL);
00823 
00824     IUnknown_Release((IUnknown*)task->bscallback);
00825 }
00826 
00827 static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
00828         nsISupports *context)
00829 {
00830     nsChannelBSC *bscallback;
00831     IMoniker *mon = NULL;
00832     HRESULT hres;
00833 
00834     hres = create_mon_for_nschannel(This, &mon);
00835     if(FAILED(hres))
00836         return NS_ERROR_UNEXPECTED;
00837 
00838     if(is_doc_channel)
00839         set_current_mon(window, mon);
00840 
00841     hres = create_channelbsc(mon, NULL, NULL, 0, &bscallback);
00842     IMoniker_Release(mon);
00843     if(FAILED(hres))
00844         return NS_ERROR_UNEXPECTED;
00845 
00846     channelbsc_set_channel(bscallback, This, listener, context);
00847 
00848     if(is_doc_channel) {
00849         set_window_bscallback(window, bscallback);
00850         async_start_doc_binding(window, bscallback);
00851         IUnknown_Release((IUnknown*)bscallback);
00852     }else {
00853         start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t));
00854 
00855         task->doc = window->doc;
00856         task->bscallback = bscallback;
00857         push_task(&task->header, start_binding_proc, window->doc->basedoc.task_magic);
00858     }
00859 
00860     return NS_OK;
00861 }
00862 
00863 static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListener *aListener,
00864                                           nsISupports *aContext)
00865 {
00866     nsChannel *This = NSCHANNEL_THIS(iface);
00867     HTMLWindow *window = NULL;
00868     BOOL open = TRUE;
00869     nsresult nsres = NS_OK;
00870 
00871     TRACE("(%p)->(%p %p) opening %s\n", This, aListener, aContext, debugstr_w(This->uri->wine_url));
00872 
00873     if(This->uri->is_doc_uri) {
00874         window = get_channel_window(This);
00875         if(window) {
00876             set_uri_window(This->uri, window);
00877         }else if(This->uri->container) {
00878             BOOL b;
00879 
00880             /* nscontainer->doc should be NULL which means navigation to a new window */
00881             if(This->uri->container->doc)
00882                 FIXME("nscontainer->doc = %p\n", This->uri->container->doc);
00883 
00884             b = before_async_open(This, This->uri->container);
00885             if(b)
00886                 FIXME("Navigation not cancelled\n");
00887             return NS_ERROR_UNEXPECTED;
00888         }
00889     }
00890 
00891     if(!window) {
00892         if(This->uri->window_ref && This->uri->window_ref->window) {
00893             window = This->uri->window_ref->window;
00894             IHTMLWindow2_AddRef(HTMLWINDOW2(window));
00895         }else if(This->load_group) {
00896             window = get_window_from_load_group(This);
00897             if(window)
00898                 set_uri_window(This->uri, window);
00899         }
00900     }
00901 
00902     if(!window) {
00903         ERR("window = NULL\n");
00904         return NS_ERROR_UNEXPECTED;
00905     }
00906 
00907     if(This->uri->is_doc_uri && window == window->doc_obj->basedoc.window) {
00908         if(This->uri->channel_bsc) {
00909             channelbsc_set_channel(This->uri->channel_bsc, This, aListener, aContext);
00910 
00911             if(window->doc_obj->mime) {
00912                 heap_free(This->content_type);
00913                 This->content_type = heap_strdupWtoA(window->doc_obj->mime);
00914             }
00915 
00916             open = FALSE;
00917         }else {
00918             open = !before_async_open(This, window->doc_obj->nscontainer);
00919             if(!open) {
00920                 TRACE("canceled\n");
00921                 nsres = NS_ERROR_UNEXPECTED;
00922             }
00923         }
00924     }
00925 
00926     if(open)
00927         nsres = async_open(This, window, This->uri->is_doc_uri, aListener, aContext);
00928 
00929     IHTMLWindow2_Release(HTMLWINDOW2(window));
00930     return nsres;
00931 }
00932 
00933 static nsresult NSAPI nsChannel_GetRequestMethod(nsIHttpChannel *iface, nsACString *aRequestMethod)
00934 {
00935     nsChannel *This = NSCHANNEL_THIS(iface);
00936 
00937     FIXME("(%p)->(%p)\n", This, aRequestMethod);
00938 
00939     return NS_ERROR_NOT_IMPLEMENTED;
00940 }
00941 
00942 static nsresult NSAPI nsChannel_SetRequestMethod(nsIHttpChannel *iface,
00943                                                  const nsACString *aRequestMethod)
00944 {
00945     nsChannel *This = NSCHANNEL_THIS(iface);
00946 
00947     TRACE("(%p)->(%p): Returning NS_OK\n", This, aRequestMethod);
00948 
00949     return NS_OK;
00950 }
00951 
00952 static nsresult NSAPI nsChannel_GetReferrer(nsIHttpChannel *iface, nsIURI **aReferrer)
00953 {
00954     nsChannel *This = NSCHANNEL_THIS(iface);
00955 
00956     FIXME("(%p)->(%p)\n", This, aReferrer);
00957 
00958     return NS_ERROR_NOT_IMPLEMENTED;
00959 }
00960 
00961 static nsresult NSAPI nsChannel_SetReferrer(nsIHttpChannel *iface, nsIURI *aReferrer)
00962 {
00963     nsChannel *This = NSCHANNEL_THIS(iface);
00964 
00965     FIXME("(%p)->(%p)\n", This, aReferrer);
00966 
00967     return NS_OK;
00968 }
00969 
00970 static nsresult NSAPI nsChannel_GetRequestHeader(nsIHttpChannel *iface,
00971          const nsACString *aHeader, nsACString *_retval)
00972 {
00973     nsChannel *This = NSCHANNEL_THIS(iface);
00974 
00975     FIXME("(%p)->(%p %p)\n", This, aHeader, _retval);
00976 
00977     return NS_ERROR_NOT_IMPLEMENTED;
00978 }
00979 
00980 static nsresult NSAPI nsChannel_SetRequestHeader(nsIHttpChannel *iface,
00981          const nsACString *aHeader, const nsACString *aValue, PRBool aMerge)
00982 {
00983     nsChannel *This = NSCHANNEL_THIS(iface);
00984 
00985     FIXME("(%p)->(%p %p %x)\n", This, aHeader, aValue, aMerge);
00986 
00987     return NS_OK;
00988 }
00989 
00990 static nsresult NSAPI nsChannel_VisitRequestHeaders(nsIHttpChannel *iface,
00991                                                     nsIHttpHeaderVisitor *aVisitor)
00992 {
00993     nsChannel *This = NSCHANNEL_THIS(iface);
00994 
00995     FIXME("(%p)->(%p)\n", This, aVisitor);
00996 
00997     return NS_ERROR_NOT_IMPLEMENTED;
00998 }
00999 
01000 static nsresult NSAPI nsChannel_GetAllowPipelining(nsIHttpChannel *iface, PRBool *aAllowPipelining)
01001 {
01002     nsChannel *This = NSCHANNEL_THIS(iface);
01003 
01004     FIXME("(%p)->(%p)\n", This, aAllowPipelining);
01005 
01006     return NS_ERROR_NOT_IMPLEMENTED;
01007 }
01008 
01009 static nsresult NSAPI nsChannel_SetAllowPipelining(nsIHttpChannel *iface, PRBool aAllowPipelining)
01010 {
01011     nsChannel *This = NSCHANNEL_THIS(iface);
01012 
01013     FIXME("(%p)->(%x)\n", This, aAllowPipelining);
01014 
01015     return NS_ERROR_NOT_IMPLEMENTED;
01016 }
01017 
01018 static nsresult NSAPI nsChannel_GetRedirectionLimit(nsIHttpChannel *iface, PRUint32 *aRedirectionLimit)
01019 {
01020     nsChannel *This = NSCHANNEL_THIS(iface);
01021 
01022     FIXME("(%p)->(%p)\n", This, aRedirectionLimit);
01023 
01024     return NS_ERROR_NOT_IMPLEMENTED;
01025 }
01026 
01027 static nsresult NSAPI nsChannel_SetRedirectionLimit(nsIHttpChannel *iface, PRUint32 aRedirectionLimit)
01028 {
01029     nsChannel *This = NSCHANNEL_THIS(iface);
01030 
01031     FIXME("(%p)->(%u)\n", This, aRedirectionLimit);
01032 
01033     return NS_ERROR_NOT_IMPLEMENTED;
01034 }
01035 
01036 static nsresult NSAPI nsChannel_GetResponseStatus(nsIHttpChannel *iface, PRUint32 *aResponseStatus)
01037 {
01038     nsChannel *This = NSCHANNEL_THIS(iface);
01039 
01040     TRACE("(%p)->(%p)\n", This, aResponseStatus);
01041 
01042     if(This->response_status) {
01043         *aResponseStatus = This->response_status;
01044         return NS_OK;
01045     }
01046 
01047     WARN("No response status\n");
01048     return NS_ERROR_UNEXPECTED;
01049 }
01050 
01051 static nsresult NSAPI nsChannel_GetResponseStatusText(nsIHttpChannel *iface,
01052                                                       nsACString *aResponseStatusText)
01053 {
01054     nsChannel *This = NSCHANNEL_THIS(iface);
01055 
01056     FIXME("(%p)->(%p)\n", This, aResponseStatusText);
01057 
01058     return NS_ERROR_NOT_IMPLEMENTED;
01059 }
01060 
01061 static nsresult NSAPI nsChannel_GetRequestSucceeded(nsIHttpChannel *iface,
01062                                                     PRBool *aRequestSucceeded)
01063 {
01064     nsChannel *This = NSCHANNEL_THIS(iface);
01065 
01066     TRACE("(%p)->(%p)\n", This, aRequestSucceeded);
01067 
01068     if(!This->response_status)
01069         return NS_ERROR_NOT_AVAILABLE;
01070 
01071     *aRequestSucceeded = This->response_status/100 == 2;
01072 
01073     return NS_OK;
01074 }
01075 
01076 static nsresult NSAPI nsChannel_GetResponseHeader(nsIHttpChannel *iface,
01077          const nsACString *header, nsACString *_retval)
01078 {
01079     nsChannel *This = NSCHANNEL_THIS(iface);
01080     const char *header_str;
01081     WCHAR *header_wstr;
01082     struct ResponseHeader *this_header;
01083 
01084     nsACString_GetData(header, &header_str);
01085     TRACE("(%p)->(%p(%s) %p)\n", This, header, header_str, _retval);
01086 
01087     header_wstr = heap_strdupAtoW(header_str);
01088     if(!header_wstr)
01089         return NS_ERROR_UNEXPECTED;
01090 
01091     LIST_FOR_EACH_ENTRY(this_header, &This->response_headers, struct ResponseHeader, entry) {
01092         if(!strcmpW(this_header->header, header_wstr)) {
01093             char *data = heap_strdupWtoA(this_header->data);
01094             if(!data) {
01095                 heap_free(header_wstr);
01096                 return NS_ERROR_UNEXPECTED;
01097             }
01098             nsACString_SetData(_retval, data);
01099             heap_free(data);
01100             heap_free(header_wstr);
01101             return NS_OK;
01102         }
01103     }
01104 
01105     heap_free(header_wstr);
01106 
01107     return NS_ERROR_NOT_AVAILABLE;
01108 }
01109 
01110 static nsresult NSAPI nsChannel_SetResponseHeader(nsIHttpChannel *iface,
01111         const nsACString *header, const nsACString *value, PRBool merge)
01112 {
01113     nsChannel *This = NSCHANNEL_THIS(iface);
01114 
01115     FIXME("(%p)->(%p %p %x)\n", This, header, value, merge);
01116 
01117     return NS_ERROR_NOT_IMPLEMENTED;
01118 }
01119 
01120 static nsresult NSAPI nsChannel_VisitResponseHeaders(nsIHttpChannel *iface,
01121         nsIHttpHeaderVisitor *aVisitor)
01122 {
01123     nsChannel *This = NSCHANNEL_THIS(iface);
01124 
01125     FIXME("(%p)->(%p)\n", This, aVisitor);
01126 
01127     return NS_ERROR_NOT_IMPLEMENTED;
01128 }
01129 
01130 static nsresult NSAPI nsChannel_IsNoStoreResponse(nsIHttpChannel *iface, PRBool *_retval)
01131 {
01132     nsChannel *This = NSCHANNEL_THIS(iface);
01133 
01134     FIXME("(%p)->(%p)\n", This, _retval);
01135 
01136     return NS_ERROR_NOT_IMPLEMENTED;
01137 }
01138 
01139 static nsresult NSAPI nsChannel_IsNoCacheResponse(nsIHttpChannel *iface, PRBool *_retval)
01140 {
01141     nsChannel *This = NSCHANNEL_THIS(iface);
01142 
01143     FIXME("(%p)->(%p)\n", This, _retval);
01144 
01145     return NS_ERROR_NOT_IMPLEMENTED;
01146 }
01147 
01148 #undef NSCHANNEL_THIS
01149 
01150 static const nsIHttpChannelVtbl nsChannelVtbl = {
01151     nsChannel_QueryInterface,
01152     nsChannel_AddRef,
01153     nsChannel_Release,
01154     nsChannel_GetName,
01155     nsChannel_IsPending,
01156     nsChannel_GetStatus,
01157     nsChannel_Cancel,
01158     nsChannel_Suspend,
01159     nsChannel_Resume,
01160     nsChannel_GetLoadGroup,
01161     nsChannel_SetLoadGroup,
01162     nsChannel_GetLoadFlags,
01163     nsChannel_SetLoadFlags,
01164     nsChannel_GetOriginalURI,
01165     nsChannel_SetOriginalURI,
01166     nsChannel_GetURI,
01167     nsChannel_GetOwner,
01168     nsChannel_SetOwner,
01169     nsChannel_GetNotificationCallbacks,
01170     nsChannel_SetNotificationCallbacks,
01171     nsChannel_GetSecurityInfo,
01172     nsChannel_GetContentType,
01173     nsChannel_SetContentType,
01174     nsChannel_GetContentCharset,
01175     nsChannel_SetContentCharset,
01176     nsChannel_GetContentLength,
01177     nsChannel_SetContentLength,
01178     nsChannel_Open,
01179     nsChannel_AsyncOpen,
01180     nsChannel_GetRequestMethod,
01181     nsChannel_SetRequestMethod,
01182     nsChannel_GetReferrer,
01183     nsChannel_SetReferrer,
01184     nsChannel_GetRequestHeader,
01185     nsChannel_SetRequestHeader,
01186     nsChannel_VisitRequestHeaders,
01187     nsChannel_GetAllowPipelining,
01188     nsChannel_SetAllowPipelining,
01189     nsChannel_GetRedirectionLimit,
01190     nsChannel_SetRedirectionLimit,
01191     nsChannel_GetResponseStatus,
01192     nsChannel_GetResponseStatusText,
01193     nsChannel_GetRequestSucceeded,
01194     nsChannel_GetResponseHeader,
01195     nsChannel_SetResponseHeader,
01196     nsChannel_VisitResponseHeaders,
01197     nsChannel_IsNoStoreResponse,
01198     nsChannel_IsNoCacheResponse
01199 };
01200 
01201 #define NSUPCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, UploadChannel, iface)
01202 
01203 static nsresult NSAPI nsUploadChannel_QueryInterface(nsIUploadChannel *iface, nsIIDRef riid,
01204                                                      nsQIResult result)
01205 {
01206     nsChannel *This = NSUPCHANNEL_THIS(iface);
01207     return nsIChannel_QueryInterface(NSCHANNEL(This), riid, result);
01208 }
01209 
01210 static nsrefcnt NSAPI nsUploadChannel_AddRef(nsIUploadChannel *iface)
01211 {
01212     nsChannel *This = NSUPCHANNEL_THIS(iface);
01213     return nsIChannel_AddRef(NSCHANNEL(This));
01214 }
01215 
01216 static nsrefcnt NSAPI nsUploadChannel_Release(nsIUploadChannel *iface)
01217 {
01218     nsChannel *This = NSUPCHANNEL_THIS(iface);
01219     return nsIChannel_Release(NSCHANNEL(This));
01220 }
01221 
01222 static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface,
01223         nsIInputStream *aStream, const nsACString *aContentType, PRInt32 aContentLength)
01224 {
01225     nsChannel *This = NSUPCHANNEL_THIS(iface);
01226     const char *content_type;
01227 
01228     TRACE("(%p)->(%p %p %d)\n", This, aStream, aContentType, aContentLength);
01229 
01230     if(This->post_data_stream)
01231         nsIInputStream_Release(This->post_data_stream);
01232 
01233     if(aContentType) {
01234         nsACString_GetData(aContentType, &content_type);
01235         if(*content_type)
01236             FIXME("Unsupported aContentType argument: %s\n", debugstr_a(content_type));
01237     }
01238 
01239     if(aContentLength != -1)
01240         FIXME("Unsupported acontentLength = %d\n", aContentLength);
01241 
01242     if(This->post_data_stream)
01243         nsIInputStream_Release(This->post_data_stream);
01244     This->post_data_stream = aStream;
01245     if(aStream)
01246         nsIInputStream_AddRef(aStream);
01247 
01248     return NS_OK;
01249 }
01250 
01251 static nsresult NSAPI nsUploadChannel_GetUploadStream(nsIUploadChannel *iface,
01252         nsIInputStream **aUploadStream)
01253 {
01254     nsChannel *This = NSUPCHANNEL_THIS(iface);
01255 
01256     TRACE("(%p)->(%p)\n", This, aUploadStream);
01257 
01258     if(This->post_data_stream)
01259         nsIInputStream_AddRef(This->post_data_stream);
01260 
01261     *aUploadStream = This->post_data_stream;
01262     return NS_OK;
01263 }
01264 
01265 #undef NSUPCHANNEL_THIS
01266 
01267 static const nsIUploadChannelVtbl nsUploadChannelVtbl = {
01268     nsUploadChannel_QueryInterface,
01269     nsUploadChannel_AddRef,
01270     nsUploadChannel_Release,
01271     nsUploadChannel_SetUploadStream,
01272     nsUploadChannel_GetUploadStream
01273 };
01274 
01275 #define NSHTTPINTERNAL_THIS(iface) DEFINE_THIS(nsChannel, IHttpChannelInternal, iface)
01276 
01277 static nsresult NSAPI nsHttpChannelInternal_QueryInterface(nsIHttpChannelInternal *iface, nsIIDRef riid,
01278         nsQIResult result)
01279 {
01280     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01281     return nsIChannel_QueryInterface(NSCHANNEL(This), riid, result);
01282 }
01283 
01284 static nsrefcnt NSAPI nsHttpChannelInternal_AddRef(nsIHttpChannelInternal *iface)
01285 {
01286     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01287     return nsIChannel_AddRef(NSCHANNEL(This));
01288 }
01289 
01290 static nsrefcnt NSAPI nsHttpChannelInternal_Release(nsIHttpChannelInternal *iface)
01291 {
01292     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01293     return nsIChannel_Release(NSCHANNEL(This));
01294 }
01295 
01296 static nsresult NSAPI nsHttpChannelInternal_GetDocumentURI(nsIHttpChannelInternal *iface, nsIURI **aDocumentURI)
01297 {
01298     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01299 
01300     FIXME("(%p)->()\n", This);
01301 
01302     return NS_ERROR_NOT_IMPLEMENTED;
01303 }
01304 
01305 static nsresult NSAPI nsHttpChannelInternal_SetDocumentURI(nsIHttpChannelInternal *iface, nsIURI *aDocumentURI)
01306 {
01307     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01308 
01309     FIXME("(%p)->()\n", This);
01310 
01311     return NS_ERROR_NOT_IMPLEMENTED;
01312 }
01313 
01314 static nsresult NSAPI nsHttpChannelInternal_GetRequestVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
01315 {
01316     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01317 
01318     FIXME("(%p)->()\n", This);
01319 
01320     return NS_ERROR_NOT_IMPLEMENTED;
01321 }
01322 
01323 static nsresult NSAPI nsHttpChannelInternal_GetResponseVersion(nsIHttpChannelInternal *iface, PRUint32 *major, PRUint32 *minor)
01324 {
01325     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01326 
01327     FIXME("(%p)->()\n", This);
01328 
01329     return NS_ERROR_NOT_IMPLEMENTED;
01330 }
01331 
01332 static nsresult NSAPI nsHttpChannelInternal_SetCookie(nsIHttpChannelInternal *iface, const char *aCookieHeader)
01333 {
01334     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01335 
01336     FIXME("(%p)->()\n", This);
01337 
01338     return NS_ERROR_NOT_IMPLEMENTED;
01339 }
01340 
01341 static nsresult NSAPI nsHttpChannelInternal_SetupFallbackChannel(nsIHttpChannelInternal *iface, const char *aFallbackKey)
01342 {
01343     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01344 
01345     FIXME("(%p)->()\n", This);
01346 
01347     return NS_ERROR_NOT_IMPLEMENTED;
01348 }
01349 
01350 static nsresult NSAPI nsHttpChannelInternal_GetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool *aForceThirdPartyCookie)
01351 {
01352     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01353 
01354     FIXME("(%p)->()\n", This);
01355 
01356     return NS_ERROR_NOT_IMPLEMENTED;
01357 }
01358 
01359 static nsresult NSAPI nsHttpChannelInternal_SetForceAllowThirdPartyCookie(nsIHttpChannelInternal *iface, PRBool aForceThirdPartyCookie)
01360 {
01361     nsChannel *This = NSHTTPINTERNAL_THIS(iface);
01362 
01363     FIXME("(%p)->()\n", This);
01364 
01365     return NS_ERROR_NOT_IMPLEMENTED;
01366 }
01367 
01368 #undef NSHTTPINTERNAL_THIS
01369 
01370 static const nsIHttpChannelInternalVtbl nsHttpChannelInternalVtbl = {
01371     nsHttpChannelInternal_QueryInterface,
01372     nsHttpChannelInternal_AddRef,
01373     nsHttpChannelInternal_Release,
01374     nsHttpChannelInternal_GetDocumentURI,
01375     nsHttpChannelInternal_SetDocumentURI,
01376     nsHttpChannelInternal_GetRequestVersion,
01377     nsHttpChannelInternal_GetResponseVersion,
01378     nsHttpChannelInternal_SetCookie,
01379     nsHttpChannelInternal_SetupFallbackChannel,
01380     nsHttpChannelInternal_GetForceAllowThirdPartyCookie,
01381     nsHttpChannelInternal_SetForceAllowThirdPartyCookie
01382 };
01383 
01384 #define NSURI_THIS(iface) DEFINE_THIS(nsWineURI, IURL, iface)
01385 
01386 static nsresult NSAPI nsURI_QueryInterface(nsIURL *iface, nsIIDRef riid, nsQIResult result)
01387 {
01388     nsWineURI *This = NSURI_THIS(iface);
01389 
01390     *result = NULL;
01391 
01392     if(IsEqualGUID(&IID_nsISupports, riid)) {
01393         TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
01394         *result = NSURI(This);
01395     }else if(IsEqualGUID(&IID_nsIURI, riid)) {
01396         TRACE("(%p)->(IID_nsIURI %p)\n", This, result);
01397         *result = NSURI(This);
01398     }else if(IsEqualGUID(&IID_nsIURL, riid)) {
01399         TRACE("(%p)->(IID_nsIURL %p)\n", This, result);
01400         *result = NSURL(This);
01401     }else if(IsEqualGUID(&IID_nsWineURI, riid)) {
01402         TRACE("(%p)->(IID_nsWineURI %p)\n", This, result);
01403         *result = This;
01404     }
01405 
01406     if(*result) {
01407         nsIURI_AddRef(NSURI(This));
01408         return NS_OK;
01409     }
01410 
01411     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
01412     return This->uri ? nsIURI_QueryInterface(This->uri, riid, result) : NS_NOINTERFACE;
01413 }
01414 
01415 static nsrefcnt NSAPI nsURI_AddRef(nsIURL *iface)
01416 {
01417     nsWineURI *This = NSURI_THIS(iface);
01418     LONG ref = InterlockedIncrement(&This->ref);
01419 
01420     TRACE("(%p) ref=%d\n", This, ref);
01421 
01422     return ref;
01423 }
01424 
01425 static nsrefcnt NSAPI nsURI_Release(nsIURL *iface)
01426 {
01427     nsWineURI *This = NSURI_THIS(iface);
01428     LONG ref = InterlockedDecrement(&This->ref);
01429 
01430     TRACE("(%p) ref=%d\n", This, ref);
01431 
01432     if(!ref) {
01433         if(This->window_ref)
01434             windowref_release(This->window_ref);
01435         if(This->container)
01436             nsIWebBrowserChrome_Release(NSWBCHROME(This->container));
01437         if(This->nsurl)
01438             nsIURL_Release(This->nsurl);
01439         if(This->uri)
01440             nsIURI_Release(This->uri);
01441         heap_free(This->wine_url);
01442         heap_free(This);
01443     }
01444 
01445     return ref;
01446 }
01447 
01448 static nsresult NSAPI nsURI_GetSpec(nsIURL *iface, nsACString *aSpec)
01449 {
01450     nsWineURI *This = NSURI_THIS(iface);
01451 
01452     TRACE("(%p)->(%p)\n", This, aSpec);
01453 
01454     if(This->use_wine_url) {
01455         char speca[INTERNET_MAX_URL_LENGTH] = "wine:";
01456         WideCharToMultiByte(CP_ACP, 0, This->wine_url, -1, speca+5, sizeof(speca)-5, NULL, NULL);
01457         nsACString_SetData(aSpec, speca);
01458 
01459         return NS_OK;
01460     }
01461 
01462     if(This->uri)
01463         return nsIURI_GetSpec(This->uri, aSpec);
01464 
01465     TRACE("returning error\n");
01466     return NS_ERROR_NOT_IMPLEMENTED;
01467 
01468 }
01469 
01470 static nsresult NSAPI nsURI_SetSpec(nsIURL *iface, const nsACString *aSpec)
01471 {
01472     nsWineURI *This = NSURI_THIS(iface);
01473 
01474     TRACE("(%p)->(%p)\n", This, aSpec);
01475 
01476     if(This->uri)
01477         return nsIURI_SetSpec(This->uri, aSpec);
01478 
01479     FIXME("default action not implemented\n");
01480     return NS_ERROR_NOT_IMPLEMENTED;
01481 }
01482 
01483 static nsresult NSAPI nsURI_GetPrePath(nsIURL *iface, nsACString *aPrePath)
01484 {
01485     nsWineURI *This = NSURI_THIS(iface);
01486 
01487     TRACE("(%p)->(%p)\n", This, aPrePath);
01488 
01489     if(This->uri)
01490         return nsIURI_GetPrePath(This->uri, aPrePath);
01491 
01492     FIXME("default action not implemented\n");
01493     return NS_ERROR_NOT_IMPLEMENTED;
01494 }
01495 
01496 static nsresult NSAPI nsURI_GetScheme(nsIURL *iface, nsACString *aScheme)
01497 {
01498     nsWineURI *This = NSURI_THIS(iface);
01499 
01500     TRACE("(%p)->(%p)\n", This, aScheme);
01501 
01502     if(This->use_wine_url) {
01503         /*
01504          * For Gecko we set scheme to unknown so it won't be handled
01505          * as any special case.
01506          */
01507         nsACString_SetData(aScheme, "wine");
01508         return NS_OK;
01509     }
01510 
01511     if(This->uri)
01512         return nsIURI_GetScheme(This->uri, aScheme);
01513 
01514     TRACE("returning error\n");
01515     return NS_ERROR_NOT_IMPLEMENTED;
01516 }
01517 
01518 static nsresult NSAPI nsURI_SetScheme(nsIURL *iface, const nsACString *aScheme)
01519 {
01520     nsWineURI *This = NSURI_THIS(iface);
01521 
01522     TRACE("(%p)->(%p)\n", This, aScheme);
01523 
01524     if(This->uri)
01525         return nsIURI_SetScheme(This->uri, aScheme);
01526 
01527     FIXME("default action not implemented\n");
01528     return NS_ERROR_NOT_IMPLEMENTED;
01529 }
01530 
01531 static nsresult NSAPI nsURI_GetUserPass(nsIURL *iface, nsACString *aUserPass)
01532 {
01533     nsWineURI *This = NSURI_THIS(iface);
01534 
01535     TRACE("(%p)->(%p)\n", This, aUserPass);
01536 
01537     if(This->uri)
01538         return nsIURI_GetUserPass(This->uri, aUserPass);
01539 
01540     FIXME("default action not implemented\n");
01541     return NS_ERROR_NOT_IMPLEMENTED;
01542 }
01543 
01544 static nsresult NSAPI nsURI_SetUserPass(nsIURL *iface, const nsACString *aUserPass)
01545 {
01546     nsWineURI *This = NSURI_THIS(iface);
01547 
01548     TRACE("(%p)->(%p)\n", This, aUserPass);
01549 
01550     if(This->uri)
01551         return nsIURI_SetUserPass(This->uri, aUserPass);
01552 
01553     FIXME("default action not implemented\n");
01554     return NS_ERROR_NOT_IMPLEMENTED;
01555 }
01556 
01557 static nsresult NSAPI nsURI_GetUsername(nsIURL *iface, nsACString *aUsername)
01558 {
01559     nsWineURI *This = NSURI_THIS(iface);
01560 
01561     TRACE("(%p)->(%p)\n", This, aUsername);
01562 
01563     if(This->uri)
01564         return nsIURI_GetUsername(This->uri, aUsername);
01565 
01566     FIXME("default action not implemented\n");
01567     return NS_ERROR_NOT_IMPLEMENTED;
01568 }
01569 
01570 static nsresult NSAPI nsURI_SetUsername(nsIURL *iface, const nsACString *aUsername)
01571 {
01572     nsWineURI *This = NSURI_THIS(iface);
01573 
01574     TRACE("(%p)->(%p)\n", This, aUsername);
01575 
01576     if(This->uri)
01577         return nsIURI_SetUsername(This->uri, aUsername);
01578 
01579     FIXME("default action not implemented\n");
01580     return NS_ERROR_NOT_IMPLEMENTED;
01581 }
01582 
01583 static nsresult NSAPI nsURI_GetPassword(nsIURL *iface, nsACString *aPassword)
01584 {
01585     nsWineURI *This = NSURI_THIS(iface);
01586 
01587     TRACE("(%p)->(%p)\n", This, aPassword);
01588 
01589     if(This->uri)
01590         return nsIURI_GetPassword(This->uri, aPassword);
01591 
01592     FIXME("default action not implemented\n");
01593     return NS_ERROR_NOT_IMPLEMENTED;
01594 }
01595 
01596 static nsresult NSAPI nsURI_SetPassword(nsIURL *iface, const nsACString *aPassword)
01597 {
01598     nsWineURI *This = NSURI_THIS(iface);
01599 
01600     TRACE("(%p)->(%p)\n", This, aPassword);
01601 
01602     if(This->uri)
01603         return nsIURI_SetPassword(This->uri, aPassword);
01604 
01605     FIXME("default action not implemented\n");
01606     return NS_ERROR_NOT_IMPLEMENTED;
01607 }
01608 
01609 static nsresult NSAPI nsURI_GetHostPort(nsIURL *iface, nsACString *aHostPort)
01610 {
01611     nsWineURI *This = NSURI_THIS(iface);
01612 
01613     TRACE("(%p)->(%p)\n", This, aHostPort);
01614 
01615     if(This->uri)
01616         return nsIURI_GetHostPort(This->uri, aHostPort);
01617 
01618     FIXME("default action not implemented\n");
01619     return NS_ERROR_NOT_IMPLEMENTED;
01620 }
01621 
01622 static nsresult NSAPI nsURI_SetHostPort(nsIURL *iface, const nsACString *aHostPort)
01623 {
01624     nsWineURI *This = NSURI_THIS(iface);
01625 
01626     TRACE("(%p)->(%p)\n", This, aHostPort);
01627 
01628     if(This->uri)
01629         return nsIURI_SetHostPort(This->uri, aHostPort);
01630 
01631     FIXME("default action not implemented\n");
01632     return NS_ERROR_NOT_IMPLEMENTED;
01633 }
01634 
01635 static nsresult NSAPI nsURI_GetHost(nsIURL *iface, nsACString *aHost)
01636 {
01637     nsWineURI *This = NSURI_THIS(iface);
01638 
01639     TRACE("(%p)->(%p)\n", This, aHost);
01640 
01641     if(This->uri)
01642         return nsIURI_GetHost(This->uri, aHost);
01643 
01644     FIXME("default action not implemented\n");
01645     return NS_ERROR_NOT_IMPLEMENTED;
01646 }
01647 
01648 static nsresult NSAPI nsURI_SetHost(nsIURL *iface, const nsACString *aHost)
01649 {
01650     nsWineURI *This = NSURI_THIS(iface);
01651 
01652     TRACE("(%p)->(%p)\n", This, aHost);
01653 
01654     if(This->uri)
01655         return nsIURI_SetHost(This->uri, aHost);
01656 
01657     FIXME("default action not implemented\n");
01658     return NS_ERROR_NOT_IMPLEMENTED;
01659 }
01660 
01661 static nsresult NSAPI nsURI_GetPort(nsIURL *iface, PRInt32 *aPort)
01662 {
01663     nsWineURI *This = NSURI_THIS(iface);
01664 
01665     TRACE("(%p)->(%p)\n", This, aPort);
01666 
01667     if(This->uri)
01668         return nsIURI_GetPort(This->uri, aPort);
01669 
01670     FIXME("default action not implemented\n");
01671     return NS_ERROR_NOT_IMPLEMENTED;
01672 }
01673 
01674 static nsresult NSAPI nsURI_SetPort(nsIURL *iface, PRInt32 aPort)
01675 {
01676     nsWineURI *This = NSURI_THIS(iface);
01677 
01678     TRACE("(%p)->(%d)\n", This, aPort);
01679 
01680     if(This->uri)
01681         return nsIURI_SetPort(This->uri, aPort);
01682 
01683     FIXME("default action not implemented\n");
01684     return NS_ERROR_NOT_IMPLEMENTED;
01685 }
01686 
01687 static nsresult NSAPI nsURI_GetPath(nsIURL *iface, nsACString *aPath)
01688 {
01689     nsWineURI *This = NSURI_THIS(iface);
01690 
01691     TRACE("(%p)->(%p)\n", This, aPath);
01692 
01693     if(This->uri)
01694         return nsIURI_GetPath(This->uri, aPath);
01695 
01696     FIXME("default action not implemented\n");
01697     return NS_ERROR_NOT_IMPLEMENTED;
01698 }
01699 
01700 static nsresult NSAPI nsURI_SetPath(nsIURL *iface, const nsACString *aPath)
01701 {
01702     nsWineURI *This = NSURI_THIS(iface);
01703     const char *path;
01704 
01705     nsACString_GetData(aPath, &path);
01706     TRACE("(%p)->(%p(%s))\n", This, aPath, debugstr_a(path));
01707 
01708 
01709     if(This->wine_url) {
01710         WCHAR new_url[INTERNET_MAX_URL_LENGTH];
01711         DWORD size = sizeof(new_url)/sizeof(WCHAR);
01712         LPWSTR pathw;
01713         HRESULT hres;
01714 
01715         pathw = heap_strdupAtoW(path);
01716         hres = UrlCombineW(This->wine_url, pathw, new_url, &size, 0);
01717         heap_free(pathw);
01718         if(SUCCEEDED(hres))
01719             set_wine_url(This, new_url);
01720         else
01721             WARN("UrlCombine failed: %08x\n", hres);
01722     }
01723 
01724     if(!This->uri)
01725         return NS_OK;
01726 
01727     return nsIURI_SetPath(This->uri, aPath);
01728 }
01729 
01730 static nsresult NSAPI nsURI_Equals(nsIURL *iface, nsIURI *other, PRBool *_retval)
01731 {
01732     nsWineURI *This = NSURI_THIS(iface);
01733     nsWineURI *wine_uri;
01734     nsresult nsres;
01735 
01736     TRACE("(%p)->(%p %p)\n", This, other, _retval);
01737 
01738     if(This->uri)
01739         return nsIURI_Equals(This->uri, other, _retval);
01740 
01741     nsres = nsIURI_QueryInterface(other, &IID_nsWineURI, (void**)&wine_uri);
01742     if(NS_FAILED(nsres)) {
01743         TRACE("Could not get nsWineURI interface\n");
01744         *_retval = FALSE;
01745         return NS_OK;
01746     }
01747 
01748     *_retval = wine_uri->wine_url && !UrlCompareW(This->wine_url, wine_uri->wine_url, TRUE);
01749     nsIURI_Release(NSURI(wine_uri));
01750 
01751     return NS_OK;
01752 }
01753 
01754 static nsresult NSAPI nsURI_SchemeIs(nsIURL *iface, const char *scheme, PRBool *_retval)
01755 {
01756     nsWineURI *This = NSURI_THIS(iface);
01757 
01758     TRACE("(%p)->(%s %p)\n", This, debugstr_a(scheme), _retval);
01759 
01760     if(This->use_wine_url) {
01761         WCHAR buf[INTERNET_MAX_SCHEME_LENGTH];
01762         int len = MultiByteToWideChar(CP_ACP, 0, scheme, -1, buf, sizeof(buf)/sizeof(WCHAR))-1;
01763 
01764         *_retval = lstrlenW(This->wine_url) > len
01765             && This->wine_url[len] == ':'
01766             && !memcmp(buf, This->wine_url, len*sizeof(WCHAR));
01767         return NS_OK;
01768     }
01769 
01770     if(This->uri)
01771         return nsIURI_SchemeIs(This->uri, scheme, _retval);
01772 
01773     TRACE("returning error\n");
01774     return NS_ERROR_NOT_IMPLEMENTED;
01775 }
01776 
01777 static nsresult NSAPI nsURI_Clone(nsIURL *iface, nsIURI **_retval)
01778 {
01779     nsWineURI *This = NSURI_THIS(iface);
01780     nsIURI *nsuri = NULL;
01781     nsWineURI *wine_uri;
01782     nsresult nsres;
01783 
01784     TRACE("(%p)->(%p)\n", This, _retval);
01785 
01786     if(This->uri) {
01787         nsres = nsIURI_Clone(This->uri, &nsuri);
01788         if(NS_FAILED(nsres)) {
01789             WARN("Clone failed: %08x\n", nsres);
01790             return nsres;
01791         }
01792     }
01793 
01794     nsres = create_uri(nsuri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
01795     if(NS_FAILED(nsres)) {
01796         WARN("create_uri failed: %08x\n", nsres);
01797         return nsres;
01798     }
01799 
01800     set_wine_url(wine_uri, This->wine_url);
01801 
01802     *_retval = NSURI(wine_uri);
01803     return NS_OK;
01804 }
01805 
01806 static nsresult NSAPI nsURI_Resolve(nsIURL *iface, const nsACString *arelativePath,
01807         nsACString *_retval)
01808 {
01809     nsWineURI *This = NSURI_THIS(iface);
01810 
01811     TRACE("(%p)->(%p %p)\n", This, arelativePath, _retval);
01812 
01813     if(This->uri)
01814         return nsIURI_Resolve(This->uri, arelativePath, _retval);
01815 
01816     FIXME("default action not implemented\n");
01817     return NS_ERROR_NOT_IMPLEMENTED;
01818 }
01819 
01820 static nsresult NSAPI nsURI_GetAsciiSpec(nsIURL *iface, nsACString *aAsciiSpec)
01821 {
01822     nsWineURI *This = NSURI_THIS(iface);
01823 
01824     TRACE("(%p)->(%p)\n", This, aAsciiSpec);
01825 
01826     if(This->use_wine_url)
01827         return nsIURI_GetSpec(NSURI(This), aAsciiSpec);
01828 
01829     if(This->uri)
01830         return nsIURI_GetAsciiSpec(This->uri, aAsciiSpec);
01831 
01832     TRACE("returning error\n");
01833     return NS_ERROR_NOT_IMPLEMENTED;
01834 }
01835 
01836 static nsresult NSAPI nsURI_GetAsciiHost(nsIURL *iface, nsACString *aAsciiHost)
01837 {
01838     nsWineURI *This = NSURI_THIS(iface);
01839 
01840     TRACE("(%p)->(%p)\n", This, aAsciiHost);
01841 
01842     if(This->uri)
01843         return nsIURI_GetAsciiHost(This->uri, aAsciiHost);
01844 
01845     FIXME("default action not implemented\n");
01846     return NS_ERROR_NOT_IMPLEMENTED;
01847 }
01848 
01849 static nsresult NSAPI nsURI_GetOriginCharset(nsIURL *iface, nsACString *aOriginCharset)
01850 {
01851     nsWineURI *This = NSURI_THIS(iface);
01852 
01853     TRACE("(%p)->(%p)\n", This, aOriginCharset);
01854 
01855     if(This->uri)
01856         return nsIURI_GetOriginCharset(This->uri, aOriginCharset);
01857 
01858     FIXME("default action not implemented\n");
01859     return NS_ERROR_NOT_IMPLEMENTED;
01860 }
01861 
01862 static nsresult NSAPI nsURL_GetFilePath(nsIURL *iface, nsACString *aFilePath)
01863 {
01864     nsWineURI *This = NSURI_THIS(iface);
01865 
01866     TRACE("(%p)->(%p)\n", This, aFilePath);
01867 
01868     if(This->nsurl)
01869         return nsIURL_GetFilePath(This->nsurl, aFilePath);
01870 
01871     FIXME("default action not implemented\n");
01872     return NS_ERROR_NOT_IMPLEMENTED;
01873 }
01874 
01875 static nsresult NSAPI nsURL_SetFilePath(nsIURL *iface, const nsACString *aFilePath)
01876 {
01877     nsWineURI *This = NSURI_THIS(iface);
01878 
01879     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFilePath));
01880 
01881     if(This->nsurl)
01882         return nsIURL_SetFilePath(This->nsurl, aFilePath);
01883 
01884     FIXME("default action not implemented\n");
01885     return NS_ERROR_NOT_IMPLEMENTED;
01886 }
01887 
01888 static nsresult NSAPI nsURL_GetParam(nsIURL *iface, nsACString *aParam)
01889 {
01890     nsWineURI *This = NSURI_THIS(iface);
01891 
01892     TRACE("(%p)->(%p)\n", This, aParam);
01893 
01894     if(This->nsurl)
01895         return nsIURL_GetParam(This->nsurl, aParam);
01896 
01897     FIXME("default action not implemented\n");
01898     return NS_ERROR_NOT_IMPLEMENTED;
01899 }
01900 
01901 static nsresult NSAPI nsURL_SetParam(nsIURL *iface, const nsACString *aParam)
01902 {
01903     nsWineURI *This = NSURI_THIS(iface);
01904 
01905     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aParam));
01906 
01907     if(This->nsurl)
01908         return nsIURL_SetParam(This->nsurl, aParam);
01909 
01910     FIXME("default action not implemented\n");
01911     return NS_ERROR_NOT_IMPLEMENTED;
01912 }
01913 
01914 static nsresult NSAPI nsURL_GetQuery(nsIURL *iface, nsACString *aQuery)
01915 {
01916     nsWineURI *This = NSURI_THIS(iface);
01917 
01918     TRACE("(%p)->(%p)\n", This, aQuery);
01919 
01920     if(This->nsurl)
01921         return nsIURL_GetQuery(This->nsurl, aQuery);
01922 
01923     FIXME("default action not implemented\n");
01924     return NS_ERROR_NOT_IMPLEMENTED;
01925 }
01926 
01927 static nsresult NSAPI nsURL_SetQuery(nsIURL *iface, const nsACString *aQuery)
01928 {
01929     nsWineURI *This = NSURI_THIS(iface);
01930     const WCHAR *ptr1, *ptr2;
01931     const char *query;
01932     WCHAR *new_url, *ptr;
01933     DWORD len, size;
01934 
01935     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aQuery));
01936 
01937     if(This->nsurl)
01938         nsIURL_SetQuery(This->nsurl, aQuery);
01939 
01940     if(!This->wine_url)
01941         return NS_OK;
01942 
01943     nsACString_GetData(aQuery, &query);
01944     size = len = MultiByteToWideChar(CP_ACP, 0, query, -1, NULL, 0);
01945     ptr1 = strchrW(This->wine_url, '?');
01946     if(ptr1) {
01947         size += ptr1-This->wine_url;
01948         ptr2 = strchrW(ptr1, '#');
01949         if(ptr2)
01950             size += strlenW(ptr2);
01951     }else {
01952         ptr1 = This->wine_url + strlenW(This->wine_url);
01953         ptr2 = NULL;
01954         size += strlenW(This->wine_url);
01955     }
01956 
01957     if(*query)
01958         size++;
01959 
01960     new_url = heap_alloc(size*sizeof(WCHAR));
01961     memcpy(new_url, This->wine_url, (ptr1-This->wine_url)*sizeof(WCHAR));
01962     ptr = new_url + (ptr1-This->wine_url);
01963     if(*query) {
01964         *ptr++ = '?';
01965         MultiByteToWideChar(CP_ACP, 0, query, -1, ptr, len);
01966         ptr += len-1;
01967     }
01968     if(ptr2)
01969         strcpyW(ptr, ptr2);
01970     else
01971         *ptr = 0;
01972 
01973     TRACE("setting %s\n", debugstr_w(new_url));
01974 
01975     heap_free(This->wine_url);
01976     This->wine_url = new_url;
01977     return NS_OK;
01978 }
01979 
01980 static nsresult NSAPI nsURL_GetRef(nsIURL *iface, nsACString *aRef)
01981 {
01982     nsWineURI *This = NSURI_THIS(iface);
01983 
01984     TRACE("(%p)->(%p)\n", This, aRef);
01985 
01986     if(This->nsurl)
01987         return nsIURL_GetRef(This->nsurl, aRef);
01988 
01989     FIXME("default action not implemented\n");
01990     return NS_ERROR_NOT_IMPLEMENTED;
01991 }
01992 
01993 static nsresult NSAPI nsURL_SetRef(nsIURL *iface, const nsACString *aRef)
01994 {
01995     nsWineURI *This = NSURI_THIS(iface);
01996     const char *refa;
01997 
01998     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
01999 
02000     if(This->nsurl)
02001         return nsIURL_SetRef(This->nsurl, aRef);
02002 
02003     nsACString_GetData(aRef, &refa);
02004     if(!*refa)
02005         return NS_OK;
02006 
02007     FIXME("default action not implemented\n");
02008     return NS_ERROR_NOT_IMPLEMENTED;
02009 }
02010 
02011 static nsresult NSAPI nsURL_GetDirectory(nsIURL *iface, nsACString *aDirectory)
02012 {
02013     nsWineURI *This = NSURI_THIS(iface);
02014 
02015     TRACE("(%p)->(%p)\n", This, aDirectory);
02016 
02017     if(This->nsurl)
02018         return nsIURL_GetDirectory(This->nsurl, aDirectory);
02019 
02020     FIXME("default action not implemented\n");
02021     return NS_ERROR_NOT_IMPLEMENTED;
02022 }
02023 
02024 static nsresult NSAPI nsURL_SetDirectory(nsIURL *iface, const nsACString *aDirectory)
02025 {
02026     nsWineURI *This = NSURI_THIS(iface);
02027 
02028     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aDirectory));
02029 
02030     if(This->nsurl)
02031         return nsIURL_SetDirectory(This->nsurl, aDirectory);
02032 
02033     FIXME("default action not implemented\n");
02034     return NS_ERROR_NOT_IMPLEMENTED;
02035 }
02036 
02037 static nsresult NSAPI nsURL_GetFileName(nsIURL *iface, nsACString *aFileName)
02038 {
02039     nsWineURI *This = NSURI_THIS(iface);
02040 
02041     TRACE("(%p)->(%p)\n", This, aFileName);
02042 
02043     if(This->nsurl)
02044         return nsIURL_GetFileName(This->nsurl, aFileName);
02045 
02046     FIXME("default action not implemented\n");
02047     return NS_ERROR_NOT_IMPLEMENTED;
02048 }
02049 
02050 static nsresult NSAPI nsURL_SetFileName(nsIURL *iface, const nsACString *aFileName)
02051 {
02052     nsWineURI *This = NSURI_THIS(iface);
02053 
02054     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileName));
02055 
02056     if(This->nsurl)
02057         return nsIURL_SetFileName(This->nsurl, aFileName);
02058 
02059     FIXME("default action not implemented\n");
02060     return NS_ERROR_NOT_IMPLEMENTED;
02061 }
02062 
02063 static nsresult NSAPI nsURL_GetFileBaseName(nsIURL *iface, nsACString *aFileBaseName)
02064 {
02065     nsWineURI *This = NSURI_THIS(iface);
02066 
02067     TRACE("(%p)->(%p)\n", This, aFileBaseName);
02068 
02069     if(This->nsurl)
02070         return nsIURL_GetFileBaseName(This->nsurl, aFileBaseName);
02071 
02072     FIXME("default action not implemented\n");
02073     return NS_ERROR_NOT_IMPLEMENTED;
02074 }
02075 
02076 static nsresult NSAPI nsURL_SetFileBaseName(nsIURL *iface, const nsACString *aFileBaseName)
02077 {
02078     nsWineURI *This = NSURI_THIS(iface);
02079 
02080     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileBaseName));
02081 
02082     if(This->nsurl)
02083         return nsIURL_SetFileBaseName(This->nsurl, aFileBaseName);
02084 
02085     FIXME("default action not implemented\n");
02086     return NS_ERROR_NOT_IMPLEMENTED;
02087 }
02088 
02089 static nsresult NSAPI nsURL_GetFileExtension(nsIURL *iface, nsACString *aFileExtension)
02090 {
02091     nsWineURI *This = NSURI_THIS(iface);
02092 
02093     TRACE("(%p)->(%p)\n", This, aFileExtension);
02094 
02095     if(This->nsurl)
02096         return nsIURL_GetFileExtension(This->nsurl, aFileExtension);
02097 
02098     FIXME("default action not implemented\n");
02099     return NS_ERROR_NOT_IMPLEMENTED;
02100 }
02101 
02102 static nsresult NSAPI nsURL_SetFileExtension(nsIURL *iface, const nsACString *aFileExtension)
02103 {
02104     nsWineURI *This = NSURI_THIS(iface);
02105 
02106     TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aFileExtension));
02107 
02108     if(This->nsurl)
02109         return nsIURL_SetFileExtension(This->nsurl, aFileExtension);
02110 
02111     FIXME("default action not implemented\n");
02112     return NS_ERROR_NOT_IMPLEMENTED;
02113 }
02114 
02115 static nsresult NSAPI nsURL_GetCommonBaseSpec(nsIURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
02116 {
02117     nsWineURI *This = NSURI_THIS(iface);
02118 
02119     TRACE("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
02120 
02121     if(This->nsurl)
02122         return nsIURL_GetCommonBaseSpec(This->nsurl, aURIToCompare, _retval);
02123 
02124     FIXME("default action not implemented\n");
02125     return NS_ERROR_NOT_IMPLEMENTED;
02126 }
02127 
02128 static nsresult NSAPI nsURL_GetRelativeSpec(nsIURL *iface, nsIURI *aURIToCompare, nsACString *_retval)
02129 {
02130     nsWineURI *This = NSURI_THIS(iface);
02131 
02132     TRACE("(%p)->(%p %p)\n", This, aURIToCompare, _retval);
02133 
02134     if(This->nsurl)
02135         return nsIURL_GetRelativeSpec(This->nsurl, aURIToCompare, _retval);
02136 
02137     FIXME("default action not implemented\n");
02138     return NS_ERROR_NOT_IMPLEMENTED;
02139 }
02140 
02141 #undef NSURI_THIS
02142 
02143 static const nsIURLVtbl nsURLVtbl = {
02144     nsURI_QueryInterface,
02145     nsURI_AddRef,
02146     nsURI_Release,
02147     nsURI_GetSpec,
02148     nsURI_SetSpec,
02149     nsURI_GetPrePath,
02150     nsURI_GetScheme,
02151     nsURI_SetScheme,
02152     nsURI_GetUserPass,
02153     nsURI_SetUserPass,
02154     nsURI_GetUsername,
02155     nsURI_SetUsername,
02156     nsURI_GetPassword,
02157     nsURI_SetPassword,
02158     nsURI_GetHostPort,
02159     nsURI_SetHostPort,
02160     nsURI_GetHost,
02161     nsURI_SetHost,
02162     nsURI_GetPort,
02163     nsURI_SetPort,
02164     nsURI_GetPath,
02165     nsURI_SetPath,
02166     nsURI_Equals,
02167     nsURI_SchemeIs,
02168     nsURI_Clone,
02169     nsURI_Resolve,
02170     nsURI_GetAsciiSpec,
02171     nsURI_GetAsciiHost,
02172     nsURI_GetOriginCharset,
02173     nsURL_GetFilePath,
02174     nsURL_SetFilePath,
02175     nsURL_GetParam,
02176     nsURL_SetParam,
02177     nsURL_GetQuery,
02178     nsURL_SetQuery,
02179     nsURL_GetRef,
02180     nsURL_SetRef,
02181     nsURL_GetDirectory,
02182     nsURL_SetDirectory,
02183     nsURL_GetFileName,
02184     nsURL_SetFileName,
02185     nsURL_GetFileBaseName,
02186     nsURL_SetFileBaseName,
02187     nsURL_GetFileExtension,
02188     nsURL_SetFileExtension,
02189     nsURL_GetCommonBaseSpec,
02190     nsURL_GetRelativeSpec
02191 };
02192 
02193 static nsresult create_uri(nsIURI *uri, HTMLWindow *window, NSContainer *container, nsWineURI **_retval)
02194 {
02195     nsWineURI *ret = heap_alloc_zero(sizeof(nsWineURI));
02196 
02197     ret->lpIURLVtbl = &nsURLVtbl;
02198     ret->ref = 1;
02199     ret->uri = uri;
02200 
02201     set_uri_nscontainer(ret, container);
02202     set_uri_window(ret, window);
02203 
02204     if(uri)
02205         nsIURI_QueryInterface(uri, &IID_nsIURL, (void**)&ret->nsurl);
02206 
02207     TRACE("retval=%p\n", ret);
02208     *_retval = ret;
02209     return NS_OK;
02210 }
02211 
02212 HRESULT create_doc_uri(HTMLWindow *window, WCHAR *url, nsWineURI **ret)
02213 {
02214     nsWineURI *uri;
02215     nsresult nsres;
02216 
02217     nsres = create_uri(NULL, window, window->doc_obj->nscontainer, &uri);
02218     if(NS_FAILED(nsres))
02219         return E_FAIL;
02220 
02221     set_wine_url(uri, url);
02222     uri->is_doc_uri = TRUE;
02223 
02224     *ret = uri;
02225     return S_OK;
02226 }
02227 
02228 typedef struct {
02229     const nsIProtocolHandlerVtbl  *lpProtocolHandlerVtbl;
02230 
02231     LONG ref;
02232 
02233     nsIProtocolHandler *nshandler;
02234 } nsProtocolHandler;
02235 
02236 #define NSPROTHANDLER(x)  ((nsIProtocolHandler*)  &(x)->lpProtocolHandlerVtbl)
02237 
02238 #define NSPROTHANDLER_THIS(iface) DEFINE_THIS(nsProtocolHandler, ProtocolHandler, iface)
02239 
02240 static nsresult NSAPI nsProtocolHandler_QueryInterface(nsIProtocolHandler *iface, nsIIDRef riid,
02241         nsQIResult result)
02242 {
02243     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02244 
02245     *result = NULL;
02246 
02247     if(IsEqualGUID(&IID_nsISupports, riid)) {
02248         TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
02249         *result = NSPROTHANDLER(This);
02250     }else if(IsEqualGUID(&IID_nsIProtocolHandler, riid)) {
02251         TRACE("(%p)->(IID_nsIProtocolHandler %p)\n", This, result);
02252         *result = NSPROTHANDLER(This);
02253     }else if(IsEqualGUID(&IID_nsIExternalProtocolHandler, riid)) {
02254         TRACE("(%p)->(IID_nsIExternalProtocolHandler %p), returning NULL\n", This, result);
02255         return NS_NOINTERFACE;
02256     }
02257 
02258     if(*result) {
02259         nsISupports_AddRef((nsISupports*)*result);
02260         return NS_OK;
02261     }
02262 
02263     WARN("(%s %p)\n", debugstr_guid(riid), result);
02264     return NS_NOINTERFACE;
02265 }
02266 
02267 static nsrefcnt NSAPI nsProtocolHandler_AddRef(nsIProtocolHandler *iface)
02268 {
02269     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02270     LONG ref = InterlockedIncrement(&This->ref);
02271 
02272     TRACE("(%p) ref=%d\n", This, ref);
02273 
02274     return ref;
02275 }
02276 
02277 static nsrefcnt NSAPI nsProtocolHandler_Release(nsIProtocolHandler *iface)
02278 {
02279     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02280     LONG ref = InterlockedDecrement(&This->ref);
02281 
02282     TRACE("(%p) ref=%d\n", This, ref);
02283 
02284     if(!ref) {
02285         if(This->nshandler)
02286             nsIProtocolHandler_Release(This->nshandler);
02287         heap_free(This);
02288     }
02289 
02290     return ref;
02291 }
02292 
02293 static nsresult NSAPI nsProtocolHandler_GetScheme(nsIProtocolHandler *iface, nsACString *aScheme)
02294 {
02295     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02296 
02297     TRACE("(%p)->(%p)\n", This, aScheme);
02298 
02299     if(This->nshandler)
02300         return nsIProtocolHandler_GetScheme(This->nshandler, aScheme);
02301     return NS_ERROR_NOT_IMPLEMENTED;
02302 }
02303 
02304 static nsresult NSAPI nsProtocolHandler_GetDefaultPort(nsIProtocolHandler *iface,
02305         PRInt32 *aDefaultPort)
02306 {
02307     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02308 
02309     TRACE("(%p)->(%p)\n", This, aDefaultPort);
02310 
02311     if(This->nshandler)
02312         return nsIProtocolHandler_GetDefaultPort(This->nshandler, aDefaultPort);
02313     return NS_ERROR_NOT_IMPLEMENTED;
02314 }
02315 
02316 static nsresult NSAPI nsProtocolHandler_GetProtocolFlags(nsIProtocolHandler *iface,
02317                                                          PRUint32 *aProtocolFlags)
02318 {
02319     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02320 
02321     TRACE("(%p)->(%p)\n", This, aProtocolFlags);
02322 
02323     if(This->nshandler)
02324         return nsIProtocolHandler_GetProtocolFlags(This->nshandler, aProtocolFlags);
02325     return NS_ERROR_NOT_IMPLEMENTED;
02326 }
02327 
02328 static nsresult NSAPI nsProtocolHandler_NewURI(nsIProtocolHandler *iface,
02329         const nsACString *aSpec, const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
02330 {
02331     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02332 
02333     TRACE("((%p)->%p %s %p %p)\n", This, aSpec, debugstr_a(aOriginCharset), aBaseURI, _retval);
02334 
02335     if(This->nshandler)
02336         return nsIProtocolHandler_NewURI(This->nshandler, aSpec, aOriginCharset, aBaseURI, _retval);
02337     return NS_ERROR_NOT_IMPLEMENTED;
02338 }
02339 
02340 static nsresult NSAPI nsProtocolHandler_NewChannel(nsIProtocolHandler *iface,
02341         nsIURI *aURI, nsIChannel **_retval)
02342 {
02343     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02344 
02345     TRACE("(%p)->(%p %p)\n", This, aURI, _retval);
02346 
02347     if(This->nshandler)
02348         return nsIProtocolHandler_NewChannel(This->nshandler, aURI, _retval);
02349     return NS_ERROR_NOT_IMPLEMENTED;
02350 }
02351 
02352 static nsresult NSAPI nsProtocolHandler_AllowPort(nsIProtocolHandler *iface,
02353         PRInt32 port, const char *scheme, PRBool *_retval)
02354 {
02355     nsProtocolHandler *This = NSPROTHANDLER_THIS(iface);
02356 
02357     TRACE("(%p)->(%d %s %p)\n", This, port, debugstr_a(scheme), _retval);
02358 
02359     if(This->nshandler)
02360         return nsIProtocolHandler_AllowPort(This->nshandler, port, scheme, _retval);
02361     return NS_ERROR_NOT_IMPLEMENTED;
02362 }
02363 
02364 #undef NSPROTHANDLER_THIS
02365 
02366 static const nsIProtocolHandlerVtbl nsProtocolHandlerVtbl = {
02367     nsProtocolHandler_QueryInterface,
02368     nsProtocolHandler_AddRef,
02369     nsProtocolHandler_Release,
02370     nsProtocolHandler_GetScheme,
02371     nsProtocolHandler_GetDefaultPort,
02372     nsProtocolHandler_GetProtocolFlags,
02373     nsProtocolHandler_NewURI,
02374     nsProtocolHandler_NewChannel,
02375     nsProtocolHandler_AllowPort
02376 };
02377 
02378 static nsIProtocolHandler *create_protocol_handler(nsIProtocolHandler *nshandler)
02379 {
02380     nsProtocolHandler *ret = heap_alloc(sizeof(nsProtocolHandler));
02381 
02382     ret->lpProtocolHandlerVtbl = &nsProtocolHandlerVtbl;
02383     ret->ref = 1;
02384     ret->nshandler = nshandler;
02385 
02386     return NSPROTHANDLER(ret);
02387 }
02388 
02389 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService*,nsIIDRef,nsQIResult);
02390 
02391 static nsrefcnt NSAPI nsIOService_AddRef(nsIIOService *iface)
02392 {
02393     return 2;
02394 }
02395 
02396 static nsrefcnt NSAPI nsIOService_Release(nsIIOService *iface)
02397 {
02398     return 1;
02399 }
02400 
02401 static nsresult NSAPI nsIOService_GetProtocolHandler(nsIIOService *iface, const char *aScheme,
02402                                                      nsIProtocolHandler **_retval)
02403 {
02404     nsIExternalProtocolHandler *nsexthandler;
02405     nsIProtocolHandler *nshandler;
02406     nsresult nsres;
02407 
02408     TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
02409 
02410     nsres = nsIIOService_GetProtocolHandler(nsio, aScheme, &nshandler);
02411     if(NS_FAILED(nsres)) {
02412         WARN("GetProtocolHandler failed: %08x\n", nsres);
02413         return nsres;
02414     }
02415 
02416     nsres = nsIProtocolHandler_QueryInterface(nshandler, &IID_nsIExternalProtocolHandler,
02417                                               (void**)&nsexthandler);
02418     if(NS_FAILED(nsres)) {
02419         *_retval = nshandler;
02420         return NS_OK;
02421     }
02422 
02423     nsIExternalProtocolHandler_Release(nsexthandler);
02424     *_retval = create_protocol_handler(nshandler);
02425     TRACE("return %p\n", *_retval);
02426     return NS_OK;
02427 }
02428 
02429 static nsresult NSAPI nsIOService_GetProtocolFlags(nsIIOService *iface, const char *aScheme,
02430                                                     PRUint32 *_retval)
02431 {
02432     TRACE("(%s %p)\n", debugstr_a(aScheme), _retval);
02433     return nsIIOService_GetProtocolFlags(nsio, aScheme, _retval);
02434 }
02435 
02436 static BOOL is_gecko_special_uri(const char *spec)
02437 {
02438     static const char *special_schemes[] = {"chrome:", "jar:", "resource:", "javascript:", "wyciwyg:"};
02439     int i;
02440 
02441     for(i=0; i < sizeof(special_schemes)/sizeof(*special_schemes); i++) {
02442         if(!strncasecmp(spec, special_schemes[i], strlen(special_schemes[i])))
02443             return TRUE;
02444     }
02445 
02446     return FALSE;
02447 }
02448 
02449 static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *aSpec,
02450         const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
02451 {
02452     nsWineURI *wine_uri, *base_wine_uri = NULL;
02453     const char *spec = NULL;
02454     HTMLWindow *window = NULL;
02455     nsIURI *uri = NULL;
02456     LPCWSTR base_wine_url = NULL;
02457     nsACString spec_str;
02458     nsresult nsres;
02459 
02460     nsACString_GetData(aSpec, &spec);
02461 
02462     TRACE("(%p(%s) %s %p %p)\n", aSpec, debugstr_a(spec), debugstr_a(aOriginCharset),
02463           aBaseURI, _retval);
02464 
02465     if(is_gecko_special_uri(spec))
02466         return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
02467 
02468     if(!strncmp(spec, "wine:", 5))
02469         spec += 5;
02470 
02471     if(aBaseURI) {
02472         PARSEDURLA parsed_url = {sizeof(PARSEDURLA)};
02473 
02474         nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsWineURI, (void**)&base_wine_uri);
02475         if(NS_SUCCEEDED(nsres)) {
02476             base_wine_url = base_wine_uri->wine_url;
02477             if(base_wine_uri->window_ref && base_wine_uri->window_ref->window) {
02478                 window = base_wine_uri->window_ref->window;
02479                 IHTMLWindow2_AddRef(HTMLWINDOW2(window));
02480             }
02481             TRACE("base url: %s window: %p\n", debugstr_w(base_wine_url), window);
02482         }else if(FAILED(ParseURLA(spec, &parsed_url))) {
02483             TRACE("not wraping\n");
02484             return nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
02485         }else {
02486             WARN("Could not get base nsWineURI: %08x\n", nsres);
02487         }
02488     }
02489 
02490     nsACString_InitDepend(&spec_str, spec);
02491     nsres = nsIIOService_NewURI(nsio, aSpec, aOriginCharset, aBaseURI, &uri);
02492     nsACString_Finish(&spec_str);
02493     if(NS_FAILED(nsres))
02494         TRACE("NewURI failed: %08x\n", nsres);
02495 
02496     nsres = create_uri(uri, window, NULL, &wine_uri);
02497     *_retval = (nsIURI*)wine_uri;
02498 
02499     if(window)
02500         IHTMLWindow2_Release(HTMLWINDOW2(window));
02501 
02502     if(base_wine_url) {
02503         WCHAR url[INTERNET_MAX_URL_LENGTH], rel_url[INTERNET_MAX_URL_LENGTH];
02504         DWORD len;
02505         HRESULT hres;
02506 
02507         MultiByteToWideChar(CP_ACP, 0, spec, -1, rel_url, sizeof(rel_url)/sizeof(WCHAR));
02508 
02509         hres = CoInternetCombineUrl(base_wine_url, rel_url,
02510                                     URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
02511                                     url, sizeof(url)/sizeof(WCHAR), &len, 0);
02512         if(SUCCEEDED(hres))
02513             set_wine_url(wine_uri, url);
02514         else
02515              WARN("CoCombineUrl failed: %08x\n", hres);
02516     }else {
02517         WCHAR url[INTERNET_MAX_URL_LENGTH];
02518 
02519         MultiByteToWideChar(CP_ACP, 0, spec, -1, url, sizeof(url)/sizeof(WCHAR));
02520         set_wine_url(wine_uri, url);
02521     }
02522 
02523     if(base_wine_uri)
02524         nsIURI_Release(NSURI(base_wine_uri));
02525 
02526     return nsres;
02527 }
02528 
02529 static nsresult NSAPI nsIOService_NewFileURI(nsIIOService *iface, nsIFile *aFile,
02530                                              nsIURI **_retval)
02531 {
02532     TRACE("(%p %p)\n", aFile, _retval);
02533     return nsIIOService_NewFileURI(nsio, aFile, _retval);
02534 }
02535 
02536 static nsresult NSAPI nsIOService_NewChannelFromURI(nsIIOService *iface, nsIURI *aURI,
02537                                                      nsIChannel **_retval)
02538 {
02539     PARSEDURLW parsed_url = {sizeof(PARSEDURLW)};
02540     nsChannel *ret;
02541     nsWineURI *wine_uri;
02542     nsresult nsres;
02543 
02544     TRACE("(%p %p)\n", aURI, _retval);
02545 
02546     nsres = nsIURI_QueryInterface(aURI, &IID_nsWineURI, (void**)&wine_uri);
02547     if(NS_FAILED(nsres)) {
02548         TRACE("Could not get nsWineURI: %08x\n", nsres);
02549         return nsIIOService_NewChannelFromURI(nsio, aURI, _retval);
02550     }
02551 
02552     ret = heap_alloc_zero(sizeof(nsChannel));
02553 
02554     ret->lpHttpChannelVtbl = &nsChannelVtbl;
02555     ret->lpUploadChannelVtbl = &nsUploadChannelVtbl;
02556     ret->lpIHttpChannelInternalVtbl = &nsHttpChannelInternalVtbl;
02557     ret->ref = 1;
02558     ret->uri = wine_uri;
02559     list_init(&ret->response_headers);
02560 
02561     nsIURI_AddRef(aURI);
02562     ret->original_uri = aURI;
02563     ret->url_scheme = wine_uri->wine_url && SUCCEEDED(ParseURLW(wine_uri->wine_url, &parsed_url))
02564         ? parsed_url.nScheme : URL_SCHEME_UNKNOWN;
02565 
02566     *_retval = NSCHANNEL(ret);
02567     return NS_OK;
02568 }
02569 
02570 static nsresult NSAPI nsIOService_NewChannel(nsIIOService *iface, const nsACString *aSpec,
02571         const char *aOriginCharset, nsIURI *aBaseURI, nsIChannel **_retval)
02572 {
02573     TRACE("(%p %s %p %p)\n", aSpec, debugstr_a(aOriginCharset), aBaseURI, _retval);
02574     return nsIIOService_NewChannel(nsio, aSpec, aOriginCharset, aBaseURI, _retval);
02575 }
02576 
02577 static nsresult NSAPI nsIOService_GetOffline(nsIIOService *iface, PRBool *aOffline)
02578 {
02579     TRACE("(%p)\n", aOffline);
02580     return nsIIOService_GetOffline(nsio, aOffline);
02581 }
02582 
02583 static nsresult NSAPI nsIOService_SetOffline(nsIIOService *iface, PRBool aOffline)
02584 {
02585     TRACE("(%x)\n", aOffline);
02586     return nsIIOService_SetOffline(nsio, aOffline);
02587 }
02588 
02589 static nsresult NSAPI nsIOService_AllowPort(nsIIOService *iface, PRInt32 aPort,
02590                                              const char *aScheme, PRBool *_retval)
02591 {
02592     TRACE("(%d %s %p)\n", aPort, debugstr_a(aScheme), _retval);
02593     return nsIIOService_AllowPort(nsio, aPort, debugstr_a(aScheme), _retval);
02594 }
02595 
02596 static nsresult NSAPI nsIOService_ExtractScheme(nsIIOService *iface, const nsACString *urlString,
02597                                                  nsACString * _retval)
02598 {
02599     TRACE("(%p %p)\n", urlString, _retval);
02600     return nsIIOService_ExtractScheme(nsio, urlString, _retval);
02601 }
02602 
02603 static const nsIIOServiceVtbl nsIOServiceVtbl = {
02604     nsIOService_QueryInterface,
02605     nsIOService_AddRef,
02606     nsIOService_Release,
02607     nsIOService_GetProtocolHandler,
02608     nsIOService_GetProtocolFlags,
02609     nsIOService_NewURI,
02610     nsIOService_NewFileURI,
02611     nsIOService_NewChannelFromURI,
02612     nsIOService_NewChannel,
02613     nsIOService_GetOffline,
02614     nsIOService_SetOffline,
02615     nsIOService_AllowPort,
02616     nsIOService_ExtractScheme
02617 };
02618 
02619 static nsIIOService nsIOService = { &nsIOServiceVtbl };
02620 
02621 static nsresult NSAPI nsNetUtil_QueryInterface(nsINetUtil *iface, nsIIDRef riid,
02622                                                nsQIResult result)
02623 {
02624     return nsIIOService_QueryInterface(&nsIOService, riid, result);
02625 }
02626 
02627 static nsrefcnt NSAPI nsNetUtil_AddRef(nsINetUtil *iface)
02628 {
02629     return 2;
02630 }
02631 
02632 static nsrefcnt NSAPI nsNetUtil_Release(nsINetUtil *iface)
02633 {
02634     return 1;
02635 }
02636 
02637 static nsresult NSAPI nsNetUtil_ParseContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
02638         nsACString *aCharset, PRBool *aHadCharset, nsACString *aContentType)
02639 {
02640     TRACE("(%p %p %p %p)\n", aTypeHeader, aCharset, aHadCharset, aContentType);
02641 
02642     return nsINetUtil_ParseContentType(net_util, aTypeHeader, aCharset, aHadCharset, aContentType);
02643 }
02644 
02645 static nsresult NSAPI nsNetUtil_ProtocolHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
02646 {
02647     TRACE("()\n");
02648 
02649     return nsINetUtil_ProtocolHasFlags(net_util, aURI, aFlags, _retval);
02650 }
02651 
02652 static nsresult NSAPI nsNetUtil_URIChainHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
02653 {
02654     TRACE("(%p %08x %p)\n", aURI, aFlags, _retval);
02655 
02656     if(aFlags == (1<<11)) {
02657         *_retval = FALSE;
02658         return NS_OK;
02659     }
02660 
02661     return nsINetUtil_URIChainHasFlags(net_util, aURI, aFlags, _retval);
02662 }
02663 
02664 static nsresult NSAPI nsNetUtil_ToImmutableURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
02665 {
02666     TRACE("(%p %p)\n", aURI, _retval);
02667 
02668     return nsINetUtil_ToImmutableURI(net_util, aURI, _retval);
02669 }
02670 
02671 static nsresult NSAPI nsNetUtil_EscapeString(nsINetUtil *iface, const nsACString *aString,
02672                                              PRUint32 aEscapeType, nsACString *_retval)
02673 {
02674     TRACE("(%p %x %p)\n", aString, aEscapeType, _retval);
02675 
02676     return nsINetUtil_EscapeString(net_util, aString, aEscapeType, _retval);
02677 }
02678 
02679 static nsresult NSAPI nsNetUtil_EscapeURL(nsINetUtil *iface, const nsACString *aStr, PRUint32 aFlags,
02680                                           nsACString *_retval)
02681 {
02682     TRACE("(%p %08x %p)\n", aStr, aFlags, _retval);
02683 
02684     return nsINetUtil_EscapeURL(net_util, aStr, aFlags, _retval);
02685 }
02686 
02687 static nsresult NSAPI nsNetUtil_UnescapeString(nsINetUtil *iface, const nsACString *aStr,
02688                                                PRUint32 aFlags, nsACString *_retval)
02689 {
02690     TRACE("(%p %08x %p)\n", aStr, aFlags, _retval);
02691 
02692     return nsINetUtil_UnescapeString(net_util, aStr, aFlags, _retval);
02693 }
02694 
02695 static nsresult NSAPI nsNetUtil_ExtractCharsetFromContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
02696         nsACString *aCharset, PRInt32 *aCharsetStart, PRInt32 *aCharsetEnd, PRBool *_retval)
02697 {
02698     TRACE("(%p %p %p %p %p)\n", aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
02699 
02700     return nsINetUtil_ExtractCharsetFromContentType(net_util, aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
02701 }
02702 
02703 static const nsINetUtilVtbl nsNetUtilVtbl = {
02704     nsNetUtil_QueryInterface,
02705     nsNetUtil_AddRef,
02706     nsNetUtil_Release,
02707     nsNetUtil_ParseContentType,
02708     nsNetUtil_ProtocolHasFlags,
02709     nsNetUtil_URIChainHasFlags,
02710     nsNetUtil_ToImmutableURI,
02711     nsNetUtil_EscapeString,
02712     nsNetUtil_EscapeURL,
02713     nsNetUtil_UnescapeString,
02714     nsNetUtil_ExtractCharsetFromContentType
02715 };
02716 
02717 static nsINetUtil nsNetUtil = { &nsNetUtilVtbl };
02718 
02719 static nsresult NSAPI nsIOService_QueryInterface(nsIIOService *iface, nsIIDRef riid,
02720                                                  nsQIResult result)
02721 {
02722     *result = NULL;
02723 
02724     if(IsEqualGUID(&IID_nsISupports, riid))
02725         *result = &nsIOService;
02726     else if(IsEqualGUID(&IID_nsIIOService, riid))
02727         *result = &nsIOService;
02728     else if(IsEqualGUID(&IID_nsINetUtil, riid))
02729         *result = &nsNetUtil;
02730 
02731     if(*result) {
02732         nsISupports_AddRef((nsISupports*)*result);
02733         return NS_OK;
02734     }
02735 
02736     FIXME("(%s %p)\n", debugstr_guid(riid), result);
02737     return NS_NOINTERFACE;
02738 }
02739 
02740 static nsresult NSAPI nsIOServiceFactory_QueryInterface(nsIFactory *iface, nsIIDRef riid,
02741                                                         nsQIResult result)
02742 {
02743     *result = NULL;
02744 
02745     if(IsEqualGUID(&IID_nsISupports, riid)) {
02746         TRACE("(IID_nsISupports %p)\n", result);
02747         *result = iface;
02748     }else if(IsEqualGUID(&IID_nsIFactory, riid)) {
02749         TRACE("(IID_nsIFactory %p)\n", result);
02750         *result = iface;
02751     }
02752 
02753     if(*result) {
02754         nsIFactory_AddRef(iface);
02755         return NS_OK;
02756     }
02757 
02758     WARN("(%s %p)\n", debugstr_guid(riid), result);
02759     return NS_NOINTERFACE;
02760 }
02761 
02762 static nsrefcnt NSAPI nsIOServiceFactory_AddRef(nsIFactory *iface)
02763 {
02764     return 2;
02765 }
02766 
02767 static nsrefcnt NSAPI nsIOServiceFactory_Release(nsIFactory *iface)
02768 {
02769     return 1;
02770 }
02771 
02772 static nsresult NSAPI nsIOServiceFactory_CreateInstance(nsIFactory *iface,
02773         nsISupports *aOuter, const nsIID *iid, void **result)
02774 {
02775     return nsIIOService_QueryInterface(&nsIOService, iid, result);
02776 }
02777 
02778 static nsresult NSAPI nsIOServiceFactory_LockFactory(nsIFactory *iface, PRBool lock)
02779 {
02780     WARN("(%x)\n", lock);
02781     return NS_OK;
02782 }
02783 
02784 static const nsIFactoryVtbl nsIOServiceFactoryVtbl = {
02785     nsIOServiceFactory_QueryInterface,
02786     nsIOServiceFactory_AddRef,
02787     nsIOServiceFactory_Release,
02788     nsIOServiceFactory_CreateInstance,
02789     nsIOServiceFactory_LockFactory
02790 };
02791 
02792 static nsIFactory nsIOServiceFactory = { &nsIOServiceFactoryVtbl };
02793 
02794 void init_nsio(nsIComponentManager *component_manager, nsIComponentRegistrar *registrar)
02795 {
02796     nsIFactory *old_factory = NULL;
02797     nsresult nsres;
02798 
02799     nsres = nsIComponentManager_GetClassObject(component_manager, &NS_IOSERVICE_CID,
02800                                                &IID_nsIFactory, (void**)&old_factory);
02801     if(NS_FAILED(nsres)) {
02802         ERR("Could not get factory: %08x\n", nsres);
02803         return;
02804     }
02805 
02806     nsres = nsIFactory_CreateInstance(old_factory, NULL, &IID_nsIIOService, (void**)&nsio);
02807     if(NS_FAILED(nsres)) {
02808         ERR("Couldn not create nsIOService instance %08x\n", nsres);
02809         nsIFactory_Release(old_factory);
02810         return;
02811     }
02812 
02813     nsres = nsIIOService_QueryInterface(nsio, &IID_nsINetUtil, (void**)&net_util);
02814     if(NS_FAILED(nsres)) {
02815         WARN("Could not get nsINetUtil interface: %08x\n", nsres);
02816         nsIIOService_Release(nsio);
02817         return;
02818     }
02819 
02820     nsres = nsIComponentRegistrar_UnregisterFactory(registrar, &NS_IOSERVICE_CID, old_factory);
02821     nsIFactory_Release(old_factory);
02822     if(NS_FAILED(nsres))
02823         ERR("UnregisterFactory failed: %08x\n", nsres);
02824 
02825     nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_IOSERVICE_CID,
02826             NS_IOSERVICE_CLASSNAME, NS_IOSERVICE_CONTRACTID, &nsIOServiceFactory);
02827     if(NS_FAILED(nsres))
02828         ERR("RegisterFactory failed: %08x\n", nsres);
02829 }
02830 
02831 void release_nsio(void)
02832 {
02833     if(net_util) {
02834         nsINetUtil_Release(net_util);
02835         net_util = NULL;
02836     }
02837 
02838     if(nsio) {
02839         nsIIOService_Release(nsio);
02840         nsio = NULL;
02841     }
02842 }

Generated on Sun May 27 2012 04:25:06 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.