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