comctl32/tooltips: Remove redundant code, let handlers deal with A<->W conversions.
[wine] / dlls / mshtml / htmllocation.c
1 /*
2  * Copyright 2008 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 <stdarg.h>
20
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "winreg.h"
27 #include "ole2.h"
28 #include "wininet.h"
29 #include "shlwapi.h"
30
31 #include "wine/debug.h"
32
33 #include "mshtml_private.h"
34 #include "resource.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 static HRESULT get_url(HTMLLocation *This, const WCHAR **ret)
39 {
40     if(!This->window || !This->window->doc_obj || !This->window->doc_obj->url) {
41         FIXME("No current URL\n");
42         return E_NOTIMPL;
43     }
44
45     *ret = This->window->doc_obj->url;
46     return S_OK;
47 }
48
49 static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url)
50 {
51     const WCHAR *doc_url;
52     HRESULT hres;
53
54     hres = get_url(This, &doc_url);
55     if(FAILED(hres))
56         return hres;
57
58     if(!InternetCrackUrlW(doc_url, 0, 0, url)) {
59         FIXME("InternetCrackUrlW failed: 0x%08x\n", GetLastError());
60         SetLastError(0);
61         return E_FAIL;
62     }
63
64     return S_OK;
65 }
66
67 #define HTMLLOCATION_THIS(iface) DEFINE_THIS(HTMLLocation, HTMLLocation, iface)
68
69 static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID riid, void **ppv)
70 {
71     HTMLLocation *This = HTMLLOCATION_THIS(iface);
72
73     *ppv = NULL;
74
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;
83     }
84
85     if(*ppv) {
86         IUnknown_AddRef((IUnknown*)*ppv);
87         return S_OK;
88     }
89
90     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
91     return E_NOINTERFACE;
92 }
93
94 static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface)
95 {
96     HTMLLocation *This = HTMLLOCATION_THIS(iface);
97     LONG ref = InterlockedIncrement(&This->ref);
98
99     TRACE("(%p) ref=%d\n", This, ref);
100
101     return ref;
102 }
103
104 static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface)
105 {
106     HTMLLocation *This = HTMLLOCATION_THIS(iface);
107     LONG ref = InterlockedDecrement(&This->ref);
108
109     TRACE("(%p) ref=%d\n", This, ref);
110
111     if(!ref) {
112         if(This->window)
113             This->window->location = NULL;
114         release_dispex(&This->dispex);
115         heap_free(This);
116     }
117
118     return ref;
119 }
120
121 static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo)
122 {
123     HTMLLocation *This = HTMLLOCATION_THIS(iface);
124     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
125 }
126
127 static HRESULT WINAPI HTMLLocation_GetTypeInfo(IHTMLLocation *iface, UINT iTInfo,
128                                               LCID lcid, ITypeInfo **ppTInfo)
129 {
130     HTMLLocation *This = HTMLLOCATION_THIS(iface);
131     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
132 }
133
134 static HRESULT WINAPI HTMLLocation_GetIDsOfNames(IHTMLLocation *iface, REFIID riid,
135                                                 LPOLESTR *rgszNames, UINT cNames,
136                                                 LCID lcid, DISPID *rgDispId)
137 {
138     HTMLLocation *This = HTMLLOCATION_THIS(iface);
139     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
140 }
141
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)
145 {
146     HTMLLocation *This = HTMLLOCATION_THIS(iface);
147     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid,
148             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
149 }
150
151 static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
152 {
153     HTMLLocation *This = HTMLLOCATION_THIS(iface);
154
155     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
156
157     if(!This->window || !This->window->doc) {
158         FIXME("No document available\n");
159         return E_FAIL;
160     }
161
162     return navigate_url(This->window->doc, v);
163 }
164
165 static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
166 {
167     HTMLLocation *This = HTMLLOCATION_THIS(iface);
168     const WCHAR *url;
169     HRESULT hres;
170
171     TRACE("(%p)->(%p)\n", This, p);
172
173     if(!p)
174         return E_POINTER;
175
176     hres = get_url(This, &url);
177     if(FAILED(hres))
178         return hres;
179
180     *p = SysAllocString(url);
181     return *p ? S_OK : E_OUTOFMEMORY;
182 }
183
184 static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v)
185 {
186     HTMLLocation *This = HTMLLOCATION_THIS(iface);
187     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
188     return E_NOTIMPL;
189 }
190
191 static HRESULT WINAPI HTMLLocation_get_protocol(IHTMLLocation *iface, BSTR *p)
192 {
193     HTMLLocation *This = HTMLLOCATION_THIS(iface);
194     FIXME("(%p)->(%p)\n", This, p);
195
196     if(!p)
197         return E_POINTER;
198
199     return E_NOTIMPL;
200 }
201
202 static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v)
203 {
204     HTMLLocation *This = HTMLLOCATION_THIS(iface);
205     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
206     return E_NOTIMPL;
207 }
208
209 static HRESULT WINAPI HTMLLocation_get_host(IHTMLLocation *iface, BSTR *p)
210 {
211     HTMLLocation *This = HTMLLOCATION_THIS(iface);
212     FIXME("(%p)->(%p)\n", This, p);
213
214     if(!p)
215         return E_POINTER;
216
217     return E_NOTIMPL;
218 }
219
220 static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v)
221 {
222     HTMLLocation *This = HTMLLOCATION_THIS(iface);
223     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
224     return E_NOTIMPL;
225 }
226
227 static HRESULT WINAPI HTMLLocation_get_hostname(IHTMLLocation *iface, BSTR *p)
228 {
229     HTMLLocation *This = HTMLLOCATION_THIS(iface);
230     FIXME("(%p)->(%p)\n", This, p);
231
232     if(!p)
233         return E_POINTER;
234
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v)
239 {
240     HTMLLocation *This = HTMLLOCATION_THIS(iface);
241     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
242     return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI HTMLLocation_get_port(IHTMLLocation *iface, BSTR *p)
246 {
247     HTMLLocation *This = HTMLLOCATION_THIS(iface);
248     URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
249     HRESULT hres;
250
251     TRACE("(%p)->(%p)\n", This, p);
252
253     if(!p)
254         return E_POINTER;
255
256     hres = get_url_components(This, &url);
257     if(FAILED(hres))
258         return hres;
259
260     if(url.nPort) {
261         const WCHAR format[] = {'%','d',0};
262         WCHAR buf[6];
263         snprintfW(buf, 6, format, url.nPort);
264         *p = SysAllocString(buf);
265     }else {
266         const WCHAR empty[] = {0};
267         *p = SysAllocString(empty);
268     }
269
270     if(!*p)
271         return E_OUTOFMEMORY;
272     return S_OK;
273 }
274
275 static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v)
276 {
277     HTMLLocation *This = HTMLLOCATION_THIS(iface);
278     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
279     return E_NOTIMPL;
280 }
281
282 static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p)
283 {
284     HTMLLocation *This = HTMLLOCATION_THIS(iface);
285     WCHAR buf[INTERNET_MAX_PATH_LENGTH];
286     URL_COMPONENTSW url = {sizeof(url)};
287     const WCHAR *doc_url;
288     DWORD size = 0;
289     HRESULT hres;
290
291     TRACE("(%p)->(%p)\n", This, p);
292
293     if(!p)
294         return E_POINTER;
295
296     hres = get_url(This, &doc_url);
297     if(FAILED(hres))
298         return hres;
299
300     hres = CoInternetParseUrl(doc_url, PARSE_PATH_FROM_URL, 0, buf, sizeof(buf), &size, 0);
301     if(SUCCEEDED(hres)) {
302         *p = SysAllocString(buf);
303         if(!*p)
304             return E_OUTOFMEMORY;
305         return S_OK;
306     }
307
308     url.dwUrlPathLength = 1;
309     hres = get_url_components(This, &url);
310     if(FAILED(hres))
311         return hres;
312
313     if(!url.dwUrlPathLength) {
314         *p = NULL;
315         return S_OK;
316     }
317
318     *p = SysAllocStringLen(url.lpszUrlPath, url.dwUrlPathLength);
319     if(!*p)
320         return E_OUTOFMEMORY;
321     return S_OK;
322 }
323
324 static HRESULT WINAPI HTMLLocation_put_search(IHTMLLocation *iface, BSTR v)
325 {
326     HTMLLocation *This = HTMLLOCATION_THIS(iface);
327     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
328     return E_NOTIMPL;
329 }
330
331 static HRESULT WINAPI HTMLLocation_get_search(IHTMLLocation *iface, BSTR *p)
332 {
333     HTMLLocation *This = HTMLLOCATION_THIS(iface);
334     FIXME("(%p)->(%p)\n", This, p);
335
336     if(!p)
337         return E_POINTER;
338
339     return E_NOTIMPL;
340 }
341
342 static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
343 {
344     HTMLLocation *This = HTMLLOCATION_THIS(iface);
345     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
346     return E_NOTIMPL;
347 }
348
349 static HRESULT WINAPI HTMLLocation_get_hash(IHTMLLocation *iface, BSTR *p)
350 {
351     HTMLLocation *This = HTMLLOCATION_THIS(iface);
352     FIXME("(%p)->(%p)\n", This, p);
353
354     if(!p)
355         return E_POINTER;
356
357     return E_NOTIMPL;
358 }
359
360 static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL flag)
361 {
362     HTMLLocation *This = HTMLLOCATION_THIS(iface);
363     FIXME("(%p)->(%x)\n", This, flag);
364     return E_NOTIMPL;
365 }
366
367 static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
368 {
369     HTMLLocation *This = HTMLLOCATION_THIS(iface);
370     FIXME("(%p)->(%s)\n", This, debugstr_w(bstr));
371     return E_NOTIMPL;
372 }
373
374 static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr)
375 {
376     HTMLLocation *This = HTMLLOCATION_THIS(iface);
377     FIXME("(%p)->(%s)\n", This, debugstr_w(bstr));
378     return E_NOTIMPL;
379 }
380
381 static HRESULT WINAPI HTMLLocation_toString(IHTMLLocation *iface, BSTR *String)
382 {
383     HTMLLocation *This = HTMLLOCATION_THIS(iface);
384     FIXME("(%p)->(%p)\n", This, String);
385     return E_NOTIMPL;
386 }
387
388 #undef HTMLLOCATION_THIS
389
390 static const IHTMLLocationVtbl HTMLLocationVtbl = {
391     HTMLLocation_QueryInterface,
392     HTMLLocation_AddRef,
393     HTMLLocation_Release,
394     HTMLLocation_GetTypeInfoCount,
395     HTMLLocation_GetTypeInfo,
396     HTMLLocation_GetIDsOfNames,
397     HTMLLocation_Invoke,
398     HTMLLocation_put_href,
399     HTMLLocation_get_href,
400     HTMLLocation_put_protocol,
401     HTMLLocation_get_protocol,
402     HTMLLocation_put_host,
403     HTMLLocation_get_host,
404     HTMLLocation_put_hostname,
405     HTMLLocation_get_hostname,
406     HTMLLocation_put_port,
407     HTMLLocation_get_port,
408     HTMLLocation_put_pathname,
409     HTMLLocation_get_pathname,
410     HTMLLocation_put_search,
411     HTMLLocation_get_search,
412     HTMLLocation_put_hash,
413     HTMLLocation_get_hash,
414     HTMLLocation_reload,
415     HTMLLocation_replace,
416     HTMLLocation_assign,
417     HTMLLocation_toString
418 };
419
420 static const tid_t HTMLLocation_iface_tids[] = {
421     IHTMLLocation_tid,
422     0
423 };
424 static dispex_static_data_t HTMLLocation_dispex = {
425     NULL,
426     DispHTMLLocation_tid,
427     NULL,
428     HTMLLocation_iface_tids
429 };
430
431
432 HRESULT HTMLLocation_Create(HTMLWindow *window, HTMLLocation **ret)
433 {
434     HTMLLocation *location;
435
436     location = heap_alloc(sizeof(*location));
437     if(!location)
438         return E_OUTOFMEMORY;
439
440     location->lpHTMLLocationVtbl = &HTMLLocationVtbl;
441     location->ref = 1;
442     location->window = window;
443
444     init_dispex(&location->dispex, (IUnknown*)HTMLLOCATION(location),  &HTMLLocation_dispex);
445
446     *ret = location;
447     return S_OK;
448 }