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"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
38 static HRESULT
get_url(HTMLLocation
*This
, const WCHAR
**ret
)
40 if(!This
->window
|| !This
->window
->url
) {
41 FIXME("No current URL\n");
45 *ret
= This
->window
->url
;
49 static HRESULT
get_url_components(HTMLLocation
*This
, URL_COMPONENTSW
*url
)
54 hres
= get_url(This
, &doc_url
);
58 if(!InternetCrackUrlW(doc_url
, 0, 0, url
)) {
59 FIXME("InternetCrackUrlW failed: 0x%08x\n", GetLastError());
67 #define HTMLLOCATION_THIS(iface) DEFINE_THIS(HTMLLocation, HTMLLocation, iface)
69 static HRESULT WINAPI
HTMLLocation_QueryInterface(IHTMLLocation
*iface
, REFIID riid
, void **ppv
)
71 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
75 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
76 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
77 *ppv
= HTMLLOCATION(This
);
78 }else if(IsEqualGUID(&IID_IHTMLLocation
, riid
)) {
79 TRACE("(%p)->(IID_IHTMLLocation %p)\n", This
, ppv
);
80 *ppv
= HTMLLOCATION(This
);
81 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
82 return *ppv
? S_OK
: E_NOINTERFACE
;
86 IUnknown_AddRef((IUnknown
*)*ppv
);
90 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
94 static ULONG WINAPI
HTMLLocation_AddRef(IHTMLLocation
*iface
)
96 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
97 LONG ref
= InterlockedIncrement(&This
->ref
);
99 TRACE("(%p) ref=%d\n", This
, ref
);
104 static ULONG WINAPI
HTMLLocation_Release(IHTMLLocation
*iface
)
106 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
107 LONG ref
= InterlockedDecrement(&This
->ref
);
109 TRACE("(%p) ref=%d\n", This
, ref
);
113 This
->window
->location
= NULL
;
114 release_dispex(&This
->dispex
);
121 static HRESULT WINAPI
HTMLLocation_GetTypeInfoCount(IHTMLLocation
*iface
, UINT
*pctinfo
)
123 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
124 return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This
->dispex
), pctinfo
);
127 static HRESULT WINAPI
HTMLLocation_GetTypeInfo(IHTMLLocation
*iface
, UINT iTInfo
,
128 LCID lcid
, ITypeInfo
**ppTInfo
)
130 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
131 return IDispatchEx_GetTypeInfo(DISPATCHEX(&This
->dispex
), iTInfo
, lcid
, ppTInfo
);
134 static HRESULT WINAPI
HTMLLocation_GetIDsOfNames(IHTMLLocation
*iface
, REFIID riid
,
135 LPOLESTR
*rgszNames
, UINT cNames
,
136 LCID lcid
, DISPID
*rgDispId
)
138 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
139 return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This
->dispex
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
142 static HRESULT WINAPI
HTMLLocation_Invoke(IHTMLLocation
*iface
, DISPID dispIdMember
,
143 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
144 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
146 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
147 return IDispatchEx_Invoke(DISPATCHEX(&This
->dispex
), dispIdMember
, riid
, lcid
,
148 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
151 static HRESULT WINAPI
HTMLLocation_put_href(IHTMLLocation
*iface
, BSTR v
)
153 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
155 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
158 FIXME("No window available\n");
162 return navigate_url(This
->window
, v
, This
->window
->url
);
165 static HRESULT WINAPI
HTMLLocation_get_href(IHTMLLocation
*iface
, BSTR
*p
)
167 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
168 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
169 WCHAR
*buf
= NULL
, *url_path
= NULL
;
174 TRACE("(%p)->(%p)\n", This
, p
);
179 url
.dwSchemeLength
= 1;
180 url
.dwHostNameLength
= 1;
181 url
.dwUrlPathLength
= 1;
182 url
.dwExtraInfoLength
= 1;
183 hres
= get_url_components(This
, &url
);
187 switch(url
.nScheme
) {
188 case INTERNET_SCHEME_FILE
:
190 /* prepend a slash */
191 url_path
= HeapAlloc(GetProcessHeap(), 0, (url
.dwUrlPathLength
+ 1) * sizeof(WCHAR
));
193 return E_OUTOFMEMORY
;
195 memcpy(url_path
+ 1, url
.lpszUrlPath
, url
.dwUrlPathLength
* sizeof(WCHAR
));
196 url
.lpszUrlPath
= url_path
;
197 url
.dwUrlPathLength
= url
.dwUrlPathLength
+ 1;
201 case INTERNET_SCHEME_HTTP
:
202 case INTERNET_SCHEME_HTTPS
:
203 case INTERNET_SCHEME_FTP
:
204 if(!url
.dwUrlPathLength
) {
205 /* add a slash if it's blank */
206 url_path
= url
.lpszUrlPath
= HeapAlloc(GetProcessHeap(), 0, 1 * sizeof(WCHAR
));
208 return E_OUTOFMEMORY
;
209 url
.lpszUrlPath
[0] = '/';
210 url
.dwUrlPathLength
= 1;
218 /* replace \ with / */
219 for(i
= 0; i
< url
.dwUrlPathLength
; ++i
)
220 if(url
.lpszUrlPath
[i
] == '\\')
221 url
.lpszUrlPath
[i
] = '/';
223 if(InternetCreateUrlW(&url
, ICU_ESCAPE
, NULL
, &len
)) {
224 FIXME("InternetCreateUrl succeeded with NULL buffer?\n");
229 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
230 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
237 buf
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
243 if(!InternetCreateUrlW(&url
, ICU_ESCAPE
, buf
, &len
)) {
244 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
250 *p
= SysAllocStringLen(buf
, len
);
259 HeapFree(GetProcessHeap(), 0, buf
);
260 HeapFree(GetProcessHeap(), 0, url_path
);
265 static HRESULT WINAPI
HTMLLocation_put_protocol(IHTMLLocation
*iface
, BSTR v
)
267 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
268 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
272 static HRESULT WINAPI
HTMLLocation_get_protocol(IHTMLLocation
*iface
, BSTR
*p
)
274 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
275 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
278 TRACE("(%p)->(%p)\n", This
, p
);
283 url
.dwSchemeLength
= 1;
284 hres
= get_url_components(This
, &url
);
288 if(!url
.dwSchemeLength
) {
289 FIXME("Unexpected blank protocol\n");
292 WCHAR buf
[url
.dwSchemeLength
+ 1];
293 memcpy(buf
, url
.lpszScheme
, url
.dwSchemeLength
* sizeof(WCHAR
));
294 buf
[url
.dwSchemeLength
] = ':';
295 *p
= SysAllocStringLen(buf
, url
.dwSchemeLength
+ 1);
298 return E_OUTOFMEMORY
;
302 static HRESULT WINAPI
HTMLLocation_put_host(IHTMLLocation
*iface
, BSTR v
)
304 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
305 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
309 static HRESULT WINAPI
HTMLLocation_get_host(IHTMLLocation
*iface
, BSTR
*p
)
311 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
312 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
315 TRACE("(%p)->(%p)\n", This
, p
);
320 url
.dwHostNameLength
= 1;
321 hres
= get_url_components(This
, &url
);
325 if(!url
.dwHostNameLength
){
331 /* <hostname>:<port> */
332 const WCHAR format
[] = {'%','d',0};
333 DWORD len
= url
.dwHostNameLength
+ 1 + 5 + 1;
336 memcpy(buf
, url
.lpszHostName
, url
.dwHostNameLength
* sizeof(WCHAR
));
337 buf
[url
.dwHostNameLength
] = ':';
338 snprintfW(buf
+ url
.dwHostNameLength
+ 1, 6, format
, url
.nPort
);
339 *p
= SysAllocString(buf
);
341 *p
= SysAllocStringLen(url
.lpszHostName
, url
.dwHostNameLength
);
344 return E_OUTOFMEMORY
;
348 static HRESULT WINAPI
HTMLLocation_put_hostname(IHTMLLocation
*iface
, BSTR v
)
350 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
351 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
355 static HRESULT WINAPI
HTMLLocation_get_hostname(IHTMLLocation
*iface
, BSTR
*p
)
357 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
358 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
361 TRACE("(%p)->(%p)\n", This
, p
);
366 url
.dwHostNameLength
= 1;
367 hres
= get_url_components(This
, &url
);
371 if(!url
.dwHostNameLength
){
376 *p
= SysAllocStringLen(url
.lpszHostName
, url
.dwHostNameLength
);
378 return E_OUTOFMEMORY
;
382 static HRESULT WINAPI
HTMLLocation_put_port(IHTMLLocation
*iface
, BSTR v
)
384 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
385 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
389 static HRESULT WINAPI
HTMLLocation_get_port(IHTMLLocation
*iface
, BSTR
*p
)
391 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
392 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
395 TRACE("(%p)->(%p)\n", This
, p
);
400 hres
= get_url_components(This
, &url
);
405 const WCHAR format
[] = {'%','d',0};
407 snprintfW(buf
, 6, format
, url
.nPort
);
408 *p
= SysAllocString(buf
);
410 const WCHAR empty
[] = {0};
411 *p
= SysAllocString(empty
);
415 return E_OUTOFMEMORY
;
419 static HRESULT WINAPI
HTMLLocation_put_pathname(IHTMLLocation
*iface
, BSTR v
)
421 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
422 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
426 static HRESULT WINAPI
HTMLLocation_get_pathname(IHTMLLocation
*iface
, BSTR
*p
)
428 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
429 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
432 TRACE("(%p)->(%p)\n", This
, p
);
437 url
.dwUrlPathLength
= 1;
438 url
.dwExtraInfoLength
= 1;
439 hres
= get_url_components(This
, &url
);
443 if(url
.dwUrlPathLength
&& url
.lpszUrlPath
[0] == '/')
444 *p
= SysAllocStringLen(url
.lpszUrlPath
+ 1, url
.dwUrlPathLength
- 1);
446 *p
= SysAllocStringLen(url
.lpszUrlPath
, url
.dwUrlPathLength
);
449 return E_OUTOFMEMORY
;
453 static HRESULT WINAPI
HTMLLocation_put_search(IHTMLLocation
*iface
, BSTR v
)
455 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
456 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
460 static HRESULT WINAPI
HTMLLocation_get_search(IHTMLLocation
*iface
, BSTR
*p
)
462 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
463 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
465 const WCHAR hash
[] = {'#',0};
467 TRACE("(%p)->(%p)\n", This
, p
);
472 url
.dwExtraInfoLength
= 1;
473 hres
= get_url_components(This
, &url
);
477 if(!url
.dwExtraInfoLength
){
482 url
.dwExtraInfoLength
= strcspnW(url
.lpszExtraInfo
, hash
);
484 *p
= SysAllocStringLen(url
.lpszExtraInfo
, url
.dwExtraInfoLength
);
487 return E_OUTOFMEMORY
;
491 static HRESULT WINAPI
HTMLLocation_put_hash(IHTMLLocation
*iface
, BSTR v
)
493 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
494 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
498 static HRESULT WINAPI
HTMLLocation_get_hash(IHTMLLocation
*iface
, BSTR
*p
)
500 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
501 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
502 const WCHAR hash
[] = {'#',0};
506 TRACE("(%p)->(%p)\n", This
, p
);
511 url
.dwExtraInfoLength
= 1;
512 hres
= get_url_components(This
, &url
);
516 if(!url
.dwExtraInfoLength
){
521 hash_pos
= strcspnW(url
.lpszExtraInfo
, hash
);
522 url
.dwExtraInfoLength
-= hash_pos
;
524 *p
= SysAllocStringLen(url
.lpszExtraInfo
+ hash_pos
, url
.dwExtraInfoLength
);
527 return E_OUTOFMEMORY
;
531 static HRESULT WINAPI
HTMLLocation_reload(IHTMLLocation
*iface
, VARIANT_BOOL flag
)
533 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
534 FIXME("(%p)->(%x)\n", This
, flag
);
538 static HRESULT WINAPI
HTMLLocation_replace(IHTMLLocation
*iface
, BSTR bstr
)
540 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
541 FIXME("(%p)->(%s)\n", This
, debugstr_w(bstr
));
545 static HRESULT WINAPI
HTMLLocation_assign(IHTMLLocation
*iface
, BSTR bstr
)
547 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
548 FIXME("(%p)->(%s)\n", This
, debugstr_w(bstr
));
552 static HRESULT WINAPI
HTMLLocation_toString(IHTMLLocation
*iface
, BSTR
*String
)
554 HTMLLocation
*This
= HTMLLOCATION_THIS(iface
);
555 FIXME("(%p)->(%p)\n", This
, String
);
559 #undef HTMLLOCATION_THIS
561 static const IHTMLLocationVtbl HTMLLocationVtbl
= {
562 HTMLLocation_QueryInterface
,
564 HTMLLocation_Release
,
565 HTMLLocation_GetTypeInfoCount
,
566 HTMLLocation_GetTypeInfo
,
567 HTMLLocation_GetIDsOfNames
,
569 HTMLLocation_put_href
,
570 HTMLLocation_get_href
,
571 HTMLLocation_put_protocol
,
572 HTMLLocation_get_protocol
,
573 HTMLLocation_put_host
,
574 HTMLLocation_get_host
,
575 HTMLLocation_put_hostname
,
576 HTMLLocation_get_hostname
,
577 HTMLLocation_put_port
,
578 HTMLLocation_get_port
,
579 HTMLLocation_put_pathname
,
580 HTMLLocation_get_pathname
,
581 HTMLLocation_put_search
,
582 HTMLLocation_get_search
,
583 HTMLLocation_put_hash
,
584 HTMLLocation_get_hash
,
586 HTMLLocation_replace
,
588 HTMLLocation_toString
591 static const tid_t HTMLLocation_iface_tids
[] = {
595 static dispex_static_data_t HTMLLocation_dispex
= {
597 DispHTMLLocation_tid
,
599 HTMLLocation_iface_tids
603 HRESULT
HTMLLocation_Create(HTMLWindow
*window
, HTMLLocation
**ret
)
605 HTMLLocation
*location
;
607 location
= heap_alloc(sizeof(*location
));
609 return E_OUTOFMEMORY
;
611 location
->lpHTMLLocationVtbl
= &HTMLLocationVtbl
;
613 location
->window
= window
;
615 init_dispex(&location
->dispex
, (IUnknown
*)HTMLLOCATION(location
), &HTMLLocation_dispex
);