kernel32: Make some functions hookable.
[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
50 #define HTMLLOCATION_THIS(iface) DEFINE_THIS(HTMLLocation, HTMLLocation, iface)
51
52 static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID riid, void **ppv)
53 {
54     HTMLLocation *This = HTMLLOCATION_THIS(iface);
55
56     *ppv = NULL;
57
58     if(IsEqualGUID(&IID_IUnknown, riid)) {
59         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
60         *ppv = HTMLLOCATION(This);
61     }else if(IsEqualGUID(&IID_IHTMLLocation, riid)) {
62         TRACE("(%p)->(IID_IHTMLLocation %p)\n", This, ppv);
63         *ppv = HTMLLOCATION(This);
64     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
65         return *ppv ? S_OK : E_NOINTERFACE;
66     }
67
68     if(*ppv) {
69         IUnknown_AddRef((IUnknown*)*ppv);
70         return S_OK;
71     }
72
73     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
74     return E_NOINTERFACE;
75 }
76
77 static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface)
78 {
79     HTMLLocation *This = HTMLLOCATION_THIS(iface);
80     LONG ref = InterlockedIncrement(&This->ref);
81
82     TRACE("(%p) ref=%d\n", This, ref);
83
84     return ref;
85 }
86
87 static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface)
88 {
89     HTMLLocation *This = HTMLLOCATION_THIS(iface);
90     LONG ref = InterlockedDecrement(&This->ref);
91
92     TRACE("(%p) ref=%d\n", This, ref);
93
94     if(!ref) {
95         if(This->window)
96             This->window->location = NULL;
97         release_dispex(&This->dispex);
98         heap_free(This);
99     }
100
101     return ref;
102 }
103
104 static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo)
105 {
106     HTMLLocation *This = HTMLLOCATION_THIS(iface);
107     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
108 }
109
110 static HRESULT WINAPI HTMLLocation_GetTypeInfo(IHTMLLocation *iface, UINT iTInfo,
111                                               LCID lcid, ITypeInfo **ppTInfo)
112 {
113     HTMLLocation *This = HTMLLOCATION_THIS(iface);
114     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
115 }
116
117 static HRESULT WINAPI HTMLLocation_GetIDsOfNames(IHTMLLocation *iface, REFIID riid,
118                                                 LPOLESTR *rgszNames, UINT cNames,
119                                                 LCID lcid, DISPID *rgDispId)
120 {
121     HTMLLocation *This = HTMLLOCATION_THIS(iface);
122     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
123 }
124
125 static HRESULT WINAPI HTMLLocation_Invoke(IHTMLLocation *iface, DISPID dispIdMember,
126                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
127                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
128 {
129     HTMLLocation *This = HTMLLOCATION_THIS(iface);
130     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid,
131             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
132 }
133
134 static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
135 {
136     HTMLLocation *This = HTMLLOCATION_THIS(iface);
137
138     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
139
140     if(!This->window || !This->window->doc) {
141         FIXME("No document available\n");
142         return E_FAIL;
143     }
144
145     return navigate_url(This->window->doc, v);
146 }
147
148 static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
149 {
150     HTMLLocation *This = HTMLLOCATION_THIS(iface);
151     const WCHAR *url;
152     HRESULT hres;
153
154     TRACE("(%p)->(%p)\n", This, p);
155
156     if(!p)
157         return E_POINTER;
158
159     hres = get_url(This, &url);
160     if(FAILED(hres))
161         return hres;
162
163     *p = SysAllocString(url);
164     return *p ? S_OK : E_OUTOFMEMORY;
165 }
166
167 static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v)
168 {
169     HTMLLocation *This = HTMLLOCATION_THIS(iface);
170     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
171     return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI HTMLLocation_get_protocol(IHTMLLocation *iface, BSTR *p)
175 {
176     HTMLLocation *This = HTMLLOCATION_THIS(iface);
177     FIXME("(%p)->(%p)\n", This, p);
178
179     if(!p)
180         return E_POINTER;
181
182     return E_NOTIMPL;
183 }
184
185 static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v)
186 {
187     HTMLLocation *This = HTMLLOCATION_THIS(iface);
188     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
189     return E_NOTIMPL;
190 }
191
192 static HRESULT WINAPI HTMLLocation_get_host(IHTMLLocation *iface, BSTR *p)
193 {
194     HTMLLocation *This = HTMLLOCATION_THIS(iface);
195     FIXME("(%p)->(%p)\n", This, p);
196
197     if(!p)
198         return E_POINTER;
199
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v)
204 {
205     HTMLLocation *This = HTMLLOCATION_THIS(iface);
206     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
207     return E_NOTIMPL;
208 }
209
210 static HRESULT WINAPI HTMLLocation_get_hostname(IHTMLLocation *iface, BSTR *p)
211 {
212     HTMLLocation *This = HTMLLOCATION_THIS(iface);
213     FIXME("(%p)->(%p)\n", This, p);
214
215     if(!p)
216         return E_POINTER;
217
218     return E_NOTIMPL;
219 }
220
221 static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v)
222 {
223     HTMLLocation *This = HTMLLOCATION_THIS(iface);
224     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
225     return E_NOTIMPL;
226 }
227
228 static HRESULT WINAPI HTMLLocation_get_port(IHTMLLocation *iface, BSTR *p)
229 {
230     HTMLLocation *This = HTMLLOCATION_THIS(iface);
231     FIXME("(%p)->(%p)\n", This, p);
232
233     if(!p)
234         return E_POINTER;
235
236     return E_NOTIMPL;
237 }
238
239 static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v)
240 {
241     HTMLLocation *This = HTMLLOCATION_THIS(iface);
242     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
243     return E_NOTIMPL;
244 }
245
246 static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p)
247 {
248     HTMLLocation *This = HTMLLOCATION_THIS(iface);
249     WCHAR buf[INTERNET_MAX_PATH_LENGTH];
250     URL_COMPONENTSW url = {sizeof(url)};
251     const WCHAR *doc_url;
252     DWORD size = 0;
253     HRESULT hres;
254
255     TRACE("(%p)->(%p)\n", This, p);
256
257     if(!p)
258         return E_POINTER;
259
260     hres = get_url(This, &doc_url);
261     if(FAILED(hres))
262         return hres;
263
264     hres = CoInternetParseUrl(doc_url, PARSE_PATH_FROM_URL, 0, buf, sizeof(buf), &size, 0);
265     if(SUCCEEDED(hres)) {
266         *p = SysAllocString(buf);
267         if(!*p)
268             return E_OUTOFMEMORY;
269         return S_OK;
270     }
271
272     url.dwUrlPathLength = 1;
273     if(!InternetCrackUrlW(doc_url, 0, 0, &url)) {
274         FIXME("InternetCrackUrl failed\n");
275         return E_FAIL;
276     }
277
278     if(!url.dwUrlPathLength) {
279         *p = NULL;
280         return S_OK;
281     }
282
283     *p = SysAllocStringLen(url.lpszUrlPath, url.dwUrlPathLength);
284     if(!*p)
285         return E_OUTOFMEMORY;
286     return S_OK;
287 }
288
289 static HRESULT WINAPI HTMLLocation_put_search(IHTMLLocation *iface, BSTR v)
290 {
291     HTMLLocation *This = HTMLLOCATION_THIS(iface);
292     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
293     return E_NOTIMPL;
294 }
295
296 static HRESULT WINAPI HTMLLocation_get_search(IHTMLLocation *iface, BSTR *p)
297 {
298     HTMLLocation *This = HTMLLOCATION_THIS(iface);
299     FIXME("(%p)->(%p)\n", This, p);
300
301     if(!p)
302         return E_POINTER;
303
304     return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
308 {
309     HTMLLocation *This = HTMLLOCATION_THIS(iface);
310     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI HTMLLocation_get_hash(IHTMLLocation *iface, BSTR *p)
315 {
316     HTMLLocation *This = HTMLLOCATION_THIS(iface);
317     FIXME("(%p)->(%p)\n", This, p);
318
319     if(!p)
320         return E_POINTER;
321
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL flag)
326 {
327     HTMLLocation *This = HTMLLOCATION_THIS(iface);
328     FIXME("(%p)->(%x)\n", This, flag);
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
333 {
334     HTMLLocation *This = HTMLLOCATION_THIS(iface);
335     FIXME("(%p)->(%s)\n", This, debugstr_w(bstr));
336     return E_NOTIMPL;
337 }
338
339 static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr)
340 {
341     HTMLLocation *This = HTMLLOCATION_THIS(iface);
342     FIXME("(%p)->(%s)\n", This, debugstr_w(bstr));
343     return E_NOTIMPL;
344 }
345
346 static HRESULT WINAPI HTMLLocation_toString(IHTMLLocation *iface, BSTR *String)
347 {
348     HTMLLocation *This = HTMLLOCATION_THIS(iface);
349     FIXME("(%p)->(%p)\n", This, String);
350     return E_NOTIMPL;
351 }
352
353 #undef HTMLLOCATION_THIS
354
355 static const IHTMLLocationVtbl HTMLLocationVtbl = {
356     HTMLLocation_QueryInterface,
357     HTMLLocation_AddRef,
358     HTMLLocation_Release,
359     HTMLLocation_GetTypeInfoCount,
360     HTMLLocation_GetTypeInfo,
361     HTMLLocation_GetIDsOfNames,
362     HTMLLocation_Invoke,
363     HTMLLocation_put_href,
364     HTMLLocation_get_href,
365     HTMLLocation_put_protocol,
366     HTMLLocation_get_protocol,
367     HTMLLocation_put_host,
368     HTMLLocation_get_host,
369     HTMLLocation_put_hostname,
370     HTMLLocation_get_hostname,
371     HTMLLocation_put_port,
372     HTMLLocation_get_port,
373     HTMLLocation_put_pathname,
374     HTMLLocation_get_pathname,
375     HTMLLocation_put_search,
376     HTMLLocation_get_search,
377     HTMLLocation_put_hash,
378     HTMLLocation_get_hash,
379     HTMLLocation_reload,
380     HTMLLocation_replace,
381     HTMLLocation_assign,
382     HTMLLocation_toString
383 };
384
385 static const tid_t HTMLLocation_iface_tids[] = {
386     IHTMLLocation_tid,
387     0
388 };
389 static dispex_static_data_t HTMLLocation_dispex = {
390     NULL,
391     DispHTMLLocation_tid,
392     NULL,
393     HTMLLocation_iface_tids
394 };
395
396
397 HRESULT HTMLLocation_Create(HTMLWindow *window, HTMLLocation **ret)
398 {
399     HTMLLocation *location;
400
401     location = heap_alloc(sizeof(*location));
402     if(!location)
403         return E_OUTOFMEMORY;
404
405     location->lpHTMLLocationVtbl = &HTMLLocationVtbl;
406     location->ref = 1;
407     location->window = window;
408
409     init_dispex(&location->dispex, (IUnknown*)HTMLLOCATION(location),  &HTMLLocation_dispex);
410
411     *ret = location;
412     return S_OK;
413 }