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