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 static inline HTMLLocation
*impl_from_IHTMLLocation(IHTMLLocation
*iface
)
69 return CONTAINING_RECORD(iface
, HTMLLocation
, IHTMLLocation_iface
);
72 static HRESULT WINAPI
HTMLLocation_QueryInterface(IHTMLLocation
*iface
, REFIID riid
, void **ppv
)
74 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
78 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
79 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
80 *ppv
= &This
->IHTMLLocation_iface
;
81 }else if(IsEqualGUID(&IID_IHTMLLocation
, riid
)) {
82 TRACE("(%p)->(IID_IHTMLLocation %p)\n", This
, ppv
);
83 *ppv
= &This
->IHTMLLocation_iface
;
84 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
85 return *ppv
? S_OK
: E_NOINTERFACE
;
89 IUnknown_AddRef((IUnknown
*)*ppv
);
93 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
97 static ULONG WINAPI
HTMLLocation_AddRef(IHTMLLocation
*iface
)
99 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
100 LONG ref
= InterlockedIncrement(&This
->ref
);
102 TRACE("(%p) ref=%d\n", This
, ref
);
107 static ULONG WINAPI
HTMLLocation_Release(IHTMLLocation
*iface
)
109 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
110 LONG ref
= InterlockedDecrement(&This
->ref
);
112 TRACE("(%p) ref=%d\n", This
, ref
);
116 This
->window
->location
= NULL
;
117 release_dispex(&This
->dispex
);
124 static HRESULT WINAPI
HTMLLocation_GetTypeInfoCount(IHTMLLocation
*iface
, UINT
*pctinfo
)
126 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
127 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
130 static HRESULT WINAPI
HTMLLocation_GetTypeInfo(IHTMLLocation
*iface
, UINT iTInfo
,
131 LCID lcid
, ITypeInfo
**ppTInfo
)
133 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
134 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
137 static HRESULT WINAPI
HTMLLocation_GetIDsOfNames(IHTMLLocation
*iface
, REFIID riid
,
138 LPOLESTR
*rgszNames
, UINT cNames
,
139 LCID lcid
, DISPID
*rgDispId
)
141 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
142 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
146 static HRESULT WINAPI
HTMLLocation_Invoke(IHTMLLocation
*iface
, DISPID dispIdMember
,
147 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
148 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
150 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
151 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
152 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
155 static HRESULT WINAPI
HTMLLocation_put_href(IHTMLLocation
*iface
, BSTR v
)
157 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
159 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
162 FIXME("No window available\n");
166 return navigate_url(This
->window
, v
, This
->window
->url
);
169 static HRESULT WINAPI
HTMLLocation_get_href(IHTMLLocation
*iface
, BSTR
*p
)
171 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
172 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
173 WCHAR
*buf
= NULL
, *url_path
= NULL
;
178 TRACE("(%p)->(%p)\n", This
, p
);
183 url
.dwSchemeLength
= 1;
184 url
.dwHostNameLength
= 1;
185 url
.dwUrlPathLength
= 1;
186 url
.dwExtraInfoLength
= 1;
187 hres
= get_url_components(This
, &url
);
191 switch(url
.nScheme
) {
192 case INTERNET_SCHEME_FILE
:
194 /* prepend a slash */
195 url_path
= HeapAlloc(GetProcessHeap(), 0, (url
.dwUrlPathLength
+ 1) * sizeof(WCHAR
));
197 return E_OUTOFMEMORY
;
199 memcpy(url_path
+ 1, url
.lpszUrlPath
, url
.dwUrlPathLength
* sizeof(WCHAR
));
200 url
.lpszUrlPath
= url_path
;
201 url
.dwUrlPathLength
= url
.dwUrlPathLength
+ 1;
205 case INTERNET_SCHEME_HTTP
:
206 case INTERNET_SCHEME_HTTPS
:
207 case INTERNET_SCHEME_FTP
:
208 if(!url
.dwUrlPathLength
) {
209 /* add a slash if it's blank */
210 url_path
= url
.lpszUrlPath
= HeapAlloc(GetProcessHeap(), 0, 1 * sizeof(WCHAR
));
212 return E_OUTOFMEMORY
;
213 url
.lpszUrlPath
[0] = '/';
214 url
.dwUrlPathLength
= 1;
222 /* replace \ with / */
223 for(i
= 0; i
< url
.dwUrlPathLength
; ++i
)
224 if(url
.lpszUrlPath
[i
] == '\\')
225 url
.lpszUrlPath
[i
] = '/';
227 if(InternetCreateUrlW(&url
, ICU_ESCAPE
, NULL
, &len
)) {
228 FIXME("InternetCreateUrl succeeded with NULL buffer?\n");
233 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER
) {
234 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
241 buf
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
247 if(!InternetCreateUrlW(&url
, ICU_ESCAPE
, buf
, &len
)) {
248 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
254 *p
= SysAllocStringLen(buf
, len
);
263 HeapFree(GetProcessHeap(), 0, buf
);
264 HeapFree(GetProcessHeap(), 0, url_path
);
269 static HRESULT WINAPI
HTMLLocation_put_protocol(IHTMLLocation
*iface
, BSTR v
)
271 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
272 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
276 static HRESULT WINAPI
HTMLLocation_get_protocol(IHTMLLocation
*iface
, BSTR
*p
)
278 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
279 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
282 TRACE("(%p)->(%p)\n", This
, p
);
287 url
.dwSchemeLength
= 1;
288 hres
= get_url_components(This
, &url
);
292 if(!url
.dwSchemeLength
) {
293 FIXME("Unexpected blank protocol\n");
296 WCHAR buf
[url
.dwSchemeLength
+ 1];
297 memcpy(buf
, url
.lpszScheme
, url
.dwSchemeLength
* sizeof(WCHAR
));
298 buf
[url
.dwSchemeLength
] = ':';
299 *p
= SysAllocStringLen(buf
, url
.dwSchemeLength
+ 1);
302 return E_OUTOFMEMORY
;
306 static HRESULT WINAPI
HTMLLocation_put_host(IHTMLLocation
*iface
, BSTR v
)
308 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
309 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
313 static HRESULT WINAPI
HTMLLocation_get_host(IHTMLLocation
*iface
, BSTR
*p
)
315 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
316 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
319 TRACE("(%p)->(%p)\n", This
, p
);
324 url
.dwHostNameLength
= 1;
325 hres
= get_url_components(This
, &url
);
329 if(!url
.dwHostNameLength
){
335 /* <hostname>:<port> */
336 const WCHAR format
[] = {'%','d',0};
337 DWORD len
= url
.dwHostNameLength
+ 1 + 5 + 1;
340 memcpy(buf
, url
.lpszHostName
, url
.dwHostNameLength
* sizeof(WCHAR
));
341 buf
[url
.dwHostNameLength
] = ':';
342 snprintfW(buf
+ url
.dwHostNameLength
+ 1, 6, format
, url
.nPort
);
343 *p
= SysAllocString(buf
);
345 *p
= SysAllocStringLen(url
.lpszHostName
, url
.dwHostNameLength
);
348 return E_OUTOFMEMORY
;
352 static HRESULT WINAPI
HTMLLocation_put_hostname(IHTMLLocation
*iface
, BSTR v
)
354 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
355 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
359 static HRESULT WINAPI
HTMLLocation_get_hostname(IHTMLLocation
*iface
, BSTR
*p
)
361 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
362 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
365 TRACE("(%p)->(%p)\n", This
, p
);
370 url
.dwHostNameLength
= 1;
371 hres
= get_url_components(This
, &url
);
375 if(!url
.dwHostNameLength
){
380 *p
= SysAllocStringLen(url
.lpszHostName
, url
.dwHostNameLength
);
382 return E_OUTOFMEMORY
;
386 static HRESULT WINAPI
HTMLLocation_put_port(IHTMLLocation
*iface
, BSTR v
)
388 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
389 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
393 static HRESULT WINAPI
HTMLLocation_get_port(IHTMLLocation
*iface
, BSTR
*p
)
395 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
396 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
399 TRACE("(%p)->(%p)\n", This
, p
);
404 hres
= get_url_components(This
, &url
);
409 const WCHAR format
[] = {'%','d',0};
411 snprintfW(buf
, 6, format
, url
.nPort
);
412 *p
= SysAllocString(buf
);
414 const WCHAR empty
[] = {0};
415 *p
= SysAllocString(empty
);
419 return E_OUTOFMEMORY
;
423 static HRESULT WINAPI
HTMLLocation_put_pathname(IHTMLLocation
*iface
, BSTR v
)
425 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
426 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
430 static HRESULT WINAPI
HTMLLocation_get_pathname(IHTMLLocation
*iface
, BSTR
*p
)
432 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
433 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
436 TRACE("(%p)->(%p)\n", This
, p
);
441 url
.dwUrlPathLength
= 1;
442 url
.dwExtraInfoLength
= 1;
443 hres
= get_url_components(This
, &url
);
447 if(url
.dwUrlPathLength
&& url
.lpszUrlPath
[0] == '/')
448 *p
= SysAllocStringLen(url
.lpszUrlPath
+ 1, url
.dwUrlPathLength
- 1);
450 *p
= SysAllocStringLen(url
.lpszUrlPath
, url
.dwUrlPathLength
);
453 return E_OUTOFMEMORY
;
457 static HRESULT WINAPI
HTMLLocation_put_search(IHTMLLocation
*iface
, BSTR v
)
459 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
460 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
464 static HRESULT WINAPI
HTMLLocation_get_search(IHTMLLocation
*iface
, BSTR
*p
)
466 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
467 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
469 const WCHAR hash
[] = {'#',0};
471 TRACE("(%p)->(%p)\n", This
, p
);
476 url
.dwExtraInfoLength
= 1;
477 hres
= get_url_components(This
, &url
);
481 if(!url
.dwExtraInfoLength
){
486 url
.dwExtraInfoLength
= strcspnW(url
.lpszExtraInfo
, hash
);
488 *p
= SysAllocStringLen(url
.lpszExtraInfo
, url
.dwExtraInfoLength
);
491 return E_OUTOFMEMORY
;
495 static HRESULT WINAPI
HTMLLocation_put_hash(IHTMLLocation
*iface
, BSTR v
)
497 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
498 FIXME("(%p)->(%s)\n", This
, debugstr_w(v
));
502 static HRESULT WINAPI
HTMLLocation_get_hash(IHTMLLocation
*iface
, BSTR
*p
)
504 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
505 URL_COMPONENTSW url
= {sizeof(URL_COMPONENTSW
)};
506 const WCHAR hash
[] = {'#',0};
510 TRACE("(%p)->(%p)\n", This
, p
);
515 url
.dwExtraInfoLength
= 1;
516 hres
= get_url_components(This
, &url
);
520 if(!url
.dwExtraInfoLength
){
525 hash_pos
= strcspnW(url
.lpszExtraInfo
, hash
);
526 url
.dwExtraInfoLength
-= hash_pos
;
528 *p
= SysAllocStringLen(url
.lpszExtraInfo
+ hash_pos
, url
.dwExtraInfoLength
);
531 return E_OUTOFMEMORY
;
535 static HRESULT WINAPI
HTMLLocation_reload(IHTMLLocation
*iface
, VARIANT_BOOL flag
)
537 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
538 FIXME("(%p)->(%x)\n", This
, flag
);
542 static HRESULT WINAPI
HTMLLocation_replace(IHTMLLocation
*iface
, BSTR bstr
)
544 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
546 TRACE("(%p)->(%s)\n", This
, debugstr_w(bstr
));
549 FIXME("No window available\n");
553 return navigate_url(This
->window
, bstr
, This
->window
->url
);
556 static HRESULT WINAPI
HTMLLocation_assign(IHTMLLocation
*iface
, BSTR bstr
)
558 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
559 FIXME("(%p)->(%s)\n", This
, debugstr_w(bstr
));
563 static HRESULT WINAPI
HTMLLocation_toString(IHTMLLocation
*iface
, BSTR
*String
)
565 HTMLLocation
*This
= impl_from_IHTMLLocation(iface
);
566 FIXME("(%p)->(%p)\n", This
, String
);
570 static const IHTMLLocationVtbl HTMLLocationVtbl
= {
571 HTMLLocation_QueryInterface
,
573 HTMLLocation_Release
,
574 HTMLLocation_GetTypeInfoCount
,
575 HTMLLocation_GetTypeInfo
,
576 HTMLLocation_GetIDsOfNames
,
578 HTMLLocation_put_href
,
579 HTMLLocation_get_href
,
580 HTMLLocation_put_protocol
,
581 HTMLLocation_get_protocol
,
582 HTMLLocation_put_host
,
583 HTMLLocation_get_host
,
584 HTMLLocation_put_hostname
,
585 HTMLLocation_get_hostname
,
586 HTMLLocation_put_port
,
587 HTMLLocation_get_port
,
588 HTMLLocation_put_pathname
,
589 HTMLLocation_get_pathname
,
590 HTMLLocation_put_search
,
591 HTMLLocation_get_search
,
592 HTMLLocation_put_hash
,
593 HTMLLocation_get_hash
,
595 HTMLLocation_replace
,
597 HTMLLocation_toString
600 static const tid_t HTMLLocation_iface_tids
[] = {
604 static dispex_static_data_t HTMLLocation_dispex
= {
606 DispHTMLLocation_tid
,
608 HTMLLocation_iface_tids
612 HRESULT
HTMLLocation_Create(HTMLWindow
*window
, HTMLLocation
**ret
)
614 HTMLLocation
*location
;
616 location
= heap_alloc(sizeof(*location
));
618 return E_OUTOFMEMORY
;
620 location
->IHTMLLocation_iface
.lpVtbl
= &HTMLLocationVtbl
;
622 location
->window
= window
;
624 init_dispex(&location
->dispex
, (IUnknown
*)&location
->IHTMLLocation_iface
, &HTMLLocation_dispex
);