2 * Copyright 2008 Jacek Caban for CodeWeavers
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.
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.
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
31 #include "wine/debug.h"
33 #include "mshtml_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 static HRESULT
get_url(HTMLLocation
*This
, const WCHAR
**ret
)
41 if(!This
->window
|| !This
->window
->base
.outer_window
|| !This
->window
->base
.outer_window
->url
) {
42 FIXME("No current URL\n");
46 *ret
= This
->window
->base
.outer_window
->url
;
50 static IUri
*get_uri(HTMLLocation
*This
)
52 if(!This
->window
|| !This
->window
->base
.outer_window
)
54 return This
->window
->base
.outer_window
->uri
;
57 static HRESULT
get_url_components(HTMLLocation
*This
, URL_COMPONENTSW
*url
)
62 hres
= get_url(This
, &doc_url
);
66 if(!InternetCrackUrlW(doc_url
, 0, 0, url
)) {
67 FIXME("InternetCrackUrlW failed: 0x%08x\n", GetLastError());
75 static inline HTMLLocation
*impl_from_IHTMLLocation(IHTMLLocation
*iface
)
77 return CONTAINING_RECORD(iface
, HTMLLocation
, IHTMLLocation_iface
);
80 static HRESULT WINAPI
HTMLLocation_QueryInterface(IHTMLLocation
*iface
, REFIID riid
, void **ppv
)
82 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
84 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
86 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
87 *ppv
= &This
->IHTMLLocation_iface
;
88 }else if(IsEqualGUID(&IID_IHTMLLocation
, riid
)) {
89 *ppv
= &This
->IHTMLLocation_iface
;
90 }else if(IsEqualGUID(&IID_IMarshal
, riid
)) {
92 FIXME("(%p)->(IID_IMarshal %p)\n", This
, ppv
);
94 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
95 return *ppv
? S_OK
: E_NOINTERFACE
;
98 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
102 IUnknown_AddRef((IUnknown
*)*ppv
);
106 static ULONG WINAPI
HTMLLocation_AddRef(IHTMLLocation
*iface
)
108 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
109 LONG ref
= InterlockedIncrement(&This
->ref
);
111 TRACE("(%p) ref=%d\n", This
, ref
);
116 static ULONG WINAPI
HTMLLocation_Release(IHTMLLocation
*iface
)
118 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
119 LONG ref
= InterlockedDecrement(&This
->ref
);
121 TRACE("(%p) ref=%d\n", This
, ref
);
125 This
->window
->location
= NULL
;
126 release_dispex(&This
->dispex
);
133 static HRESULT WINAPI
HTMLLocation_GetTypeInfoCount(IHTMLLocation
*iface
, UINT
*pctinfo
)
135 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
136 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
139 static HRESULT WINAPI
HTMLLocation_GetTypeInfo(IHTMLLocation
*iface
, UINT iTInfo
,
140 LCID lcid
, ITypeInfo
**ppTInfo
)
142 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
143 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
146 static HRESULT WINAPI
HTMLLocation_GetIDsOfNames(IHTMLLocation
*iface
, REFIID riid
,
147 LPOLESTR
*rgszNames
, UINT cNames
,
148 LCID lcid
, DISPID
*rgDispId
)
150 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
151 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
155 static HRESULT WINAPI
HTMLLocation_Invoke(IHTMLLocation
*iface
, DISPID dispIdMember
,
156 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
157 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
159 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
160 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
161 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
164 static HRESULT WINAPI
HTMLLocation_put_href(IHTMLLocation
*iface
, BSTR v
)
166 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
168 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
170 if(!This
->window
|| !This
->window
->base
.outer_window
) {
171 FIXME("No window available\n");
175 return navigate_url(This
->window
->base
.outer_window
, v
, This
->window
->base
.outer_window
->uri
, BINDING_NAVIGATED
);
178 static HRESULT WINAPI
HTMLLocation_get_href(IHTMLLocation
*iface
, BSTR
*p
)
180 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
181 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
182 WCHAR
*buf
= NULL
, *url_path
= NULL
;
187 TRACE("(%p)->(%p)\n", This
, p
);
192 url
.dwSchemeLength
= 1;
193 url
.dwHostNameLength
= 1;
194 url
.dwUrlPathLength
= 1;
195 url
.dwExtraInfoLength
= 1;
196 hres
= get_url_components(This
, &url
);
200 switch(url
.nScheme
) {
201 case INTERNET_SCHEME_FILE
:
203 /* prepend a slash */
204 url_path
= HeapAlloc(GetProcessHeap(), 0, (url
.dwUrlPathLength
+ 1) * sizeof(WCHAR
));
206 return E_OUTOFMEMORY
;
208 memcpy(url_path
+ 1, url
.lpszUrlPath
, url
.dwUrlPathLength
* sizeof(WCHAR
));
209 url
.lpszUrlPath
= url_path
;
210 url
.dwUrlPathLength
= url
.dwUrlPathLength
+ 1;
214 case INTERNET_SCHEME_HTTP
:
215 case INTERNET_SCHEME_HTTPS
:
216 case INTERNET_SCHEME_FTP
:
217 if(!url
.dwUrlPathLength
) {
218 /* add a slash if it's blank */
219 url_path
= url
.lpszUrlPath
= HeapAlloc(GetProcessHeap(), 0, 1 * sizeof(WCHAR
));
221 return E_OUTOFMEMORY
;
222 url
.lpszUrlPath
[0] = '/';
223 url
.dwUrlPathLength
= 1;
231 /* replace \ with / */
232 for(i
= 0; i
< url
.dwUrlPathLength
; ++i
)
233 if(url
.lpszUrlPath
[i
] == '\\')
234 url
.lpszUrlPath
[i
] = '/';
236 if(InternetCreateUrlW(&url
, ICU_ESCAPE
, NULL
, &len
)) {
237 FIXME("InternetCreateUrl succeeded with NULL buffer?\n");
242 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
243 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
250 buf
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
256 if(!InternetCreateUrlW(&url
, ICU_ESCAPE
, buf
, &len
)) {
257 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
263 *p
= SysAllocStringLen(buf
, len
);
272 HeapFree(GetProcessHeap(), 0, buf
);
273 HeapFree(GetProcessHeap(), 0, url_path
);
278 static HRESULT WINAPI
HTMLLocation_put_protocol(IHTMLLocation
*iface
, BSTR v
)
280 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
281 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
285 static HRESULT WINAPI
HTMLLocation_get_protocol(IHTMLLocation
*iface
, BSTR
*p
)
287 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
293 TRACE("(%p)->(%p)\n", This
, p
);
298 if(!(uri
= get_uri(This
))) {
299 FIXME("No current URI\n");
303 hres
= IUri_GetSchemeName(uri
, &protocol
);
306 if(hres
== S_FALSE
) {
307 SysFreeString(protocol
);
312 len
= SysStringLen(protocol
);
313 ret
= SysAllocStringLen(protocol
, len
+1);
314 SysFreeString(protocol
);
316 return E_OUTOFMEMORY
;
323 static HRESULT WINAPI
HTMLLocation_put_host(IHTMLLocation
*iface
, BSTR v
)
325 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
326 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
330 static HRESULT WINAPI
HTMLLocation_get_host(IHTMLLocation
*iface
, BSTR
*p
)
332 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
333 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
336 TRACE("(%p)->(%p)\n", This
, p
);
341 url
.dwHostNameLength
= 1;
342 hres
= get_url_components(This
, &url
);
346 if(!url
.dwHostNameLength
){
352 /* <hostname>:<port> */
357 port_len
= swprintf(portW
, ARRAY_SIZE(portW
), L
"%u", url
.nPort
);
358 len
= url
.dwHostNameLength
+ 1 /* ':' */ + port_len
;
359 buf
= *p
= SysAllocStringLen(NULL
, len
);
360 memcpy(buf
, url
.lpszHostName
, url
.dwHostNameLength
* sizeof(WCHAR
));
361 buf
[url
.dwHostNameLength
] = ':';
362 memcpy(buf
+ url
.dwHostNameLength
+ 1, portW
, port_len
* sizeof(WCHAR
));
364 *p
= SysAllocStringLen(url
.lpszHostName
, url
.dwHostNameLength
);
367 return E_OUTOFMEMORY
;
371 static HRESULT WINAPI
HTMLLocation_put_hostname(IHTMLLocation
*iface
, BSTR v
)
373 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
374 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
378 static HRESULT WINAPI
HTMLLocation_get_hostname(IHTMLLocation
*iface
, BSTR
*p
)
380 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
385 TRACE("(%p)->(%p)\n", This
, p
);
390 if(!(uri
= get_uri(This
))) {
391 FIXME("No current URI\n");
395 hres
= IUri_GetHost(uri
, &hostname
);
398 }else if(hres
== S_FALSE
) {
399 SysFreeString(hostname
);
408 static HRESULT WINAPI
HTMLLocation_put_port(IHTMLLocation
*iface
, BSTR v
)
410 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
411 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
415 static HRESULT WINAPI
HTMLLocation_get_port(IHTMLLocation
*iface
, BSTR
*p
)
417 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
422 TRACE("(%p)->(%p)\n", This
, p
);
427 if(!(uri
= get_uri(This
))) {
428 FIXME("No current URI\n");
432 hres
= IUri_GetPort(uri
, &port
);
439 swprintf(buf
, ARRAY_SIZE(buf
), L
"%u", port
);
440 *p
= SysAllocString(buf
);
442 *p
= SysAllocStringLen(NULL
, 0);
446 return E_OUTOFMEMORY
;
450 static HRESULT WINAPI
HTMLLocation_put_pathname(IHTMLLocation
*iface
, BSTR v
)
452 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
453 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
457 static HRESULT WINAPI
HTMLLocation_get_pathname(IHTMLLocation
*iface
, BSTR
*p
)
459 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
464 TRACE("(%p)->(%p)\n", This
, p
);
469 if(!(uri
= get_uri(This
))) {
470 FIXME("No current URI\n");
474 hres
= IUri_GetPath(uri
, &path
);
478 if(hres
== S_FALSE
) {
487 static HRESULT WINAPI
HTMLLocation_put_search(IHTMLLocation
*iface
, BSTR v
)
489 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
490 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
494 static HRESULT WINAPI
HTMLLocation_get_search(IHTMLLocation
*iface
, BSTR
*p
)
496 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
501 TRACE("(%p)->(%p)\n", This
, p
);
506 if(!(uri
= get_uri(This
))) {
507 FIXME("No current URI\n");
511 hres
= IUri_GetQuery(uri
, &query
);
514 }else if(hres
== S_FALSE
) {
515 SysFreeString(query
);
524 static HRESULT WINAPI
HTMLLocation_put_hash(IHTMLLocation
*iface
, BSTR v
)
526 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
527 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
531 static HRESULT WINAPI
HTMLLocation_get_hash(IHTMLLocation
*iface
, BSTR
*p
)
533 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
538 TRACE("(%p)->(%p)\n", This
, p
);
543 if(!(uri
= get_uri(This
))) {
544 FIXME("No current URI\n");
548 hres
= IUri_GetFragment(uri
, &hash
);
551 }else if(hres
== S_FALSE
) {
561 static HRESULT WINAPI
HTMLLocation_reload(IHTMLLocation
*iface
, VARIANT_BOOL flag
)
563 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
564 FIXME("(%p)->(%x)\n", This
, flag
);
568 static HRESULT WINAPI
HTMLLocation_replace(IHTMLLocation
*iface
, BSTR bstr
)
570 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
572 TRACE("(%p)->(%s)\n", This
, debugstr_w(bstr
));
574 if(!This
->window
|| !This
->window
->base
.outer_window
) {
575 FIXME("No window available\n");
579 return navigate_url(This
->window
->base
.outer_window
, bstr
, This
->window
->base
.outer_window
->uri
,
580 BINDING_NAVIGATED
|BINDING_REPLACE
);
583 static HRESULT WINAPI
HTMLLocation_assign(IHTMLLocation
*iface
, BSTR bstr
)
585 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
586 TRACE("(%p)->(%s)\n", This
, debugstr_w(bstr
));
587 return IHTMLLocation_put_href(iface
, bstr
);
590 static HRESULT WINAPI
HTMLLocation_toString(IHTMLLocation
*iface
, BSTR
*String
)
592 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
594 TRACE("(%p)->(%p)\n", This
, String
);
596 return IHTMLLocation_get_href(&This
->IHTMLLocation_iface
, String
);
599 static const IHTMLLocationVtbl HTMLLocationVtbl
= {
600 HTMLLocation_QueryInterface
,
602 HTMLLocation_Release
,
603 HTMLLocation_GetTypeInfoCount
,
604 HTMLLocation_GetTypeInfo
,
605 HTMLLocation_GetIDsOfNames
,
607 HTMLLocation_put_href
,
608 HTMLLocation_get_href
,
609 HTMLLocation_put_protocol
,
610 HTMLLocation_get_protocol
,
611 HTMLLocation_put_host
,
612 HTMLLocation_get_host
,
613 HTMLLocation_put_hostname
,
614 HTMLLocation_get_hostname
,
615 HTMLLocation_put_port
,
616 HTMLLocation_get_port
,
617 HTMLLocation_put_pathname
,
618 HTMLLocation_get_pathname
,
619 HTMLLocation_put_search
,
620 HTMLLocation_get_search
,
621 HTMLLocation_put_hash
,
622 HTMLLocation_get_hash
,
624 HTMLLocation_replace
,
626 HTMLLocation_toString
629 static const tid_t HTMLLocation_iface_tids
[] = {
633 static dispex_static_data_t HTMLLocation_dispex
= {
635 DispHTMLLocation_tid
,
636 HTMLLocation_iface_tids
640 HRESULT
HTMLLocation_Create(HTMLInnerWindow
*window
, HTMLLocation
**ret
)
642 HTMLLocation
*location
;
644 location
= heap_alloc(sizeof(*location
));
646 return E_OUTOFMEMORY
;
648 location
->IHTMLLocation_iface
.lpVtbl
= &HTMLLocationVtbl
;
650 location
->window
= window
;
652 init_dispatch(&location
->dispex
, (IUnknown
*)&location
->IHTMLLocation_iface
, &HTMLLocation_dispex
,
653 dispex_compat_mode(&window
->event_target
.dispex
));