mshtml: Fixed AsyncOpen implementation for channels without associated document.
[wine] / dlls / mshtml / hlink.c
1 /*
2  * Copyright 2005-2006 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 "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
33
34 #include "mshtml_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 /**********************************************************
39  * IHlinkTarget implementation
40  */
41
42 #define HLINKTRG_THIS(iface) DEFINE_THIS(HTMLDocument, HlinkTarget, iface)
43
44 static HRESULT WINAPI HlinkTarget_QueryInterface(IHlinkTarget *iface, REFIID riid, void **ppv)
45 {
46     HTMLDocument *This = HLINKTRG_THIS(iface);
47     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
48 }
49
50 static ULONG WINAPI HlinkTarget_AddRef(IHlinkTarget *iface)
51 {
52     HTMLDocument *This = HLINKTRG_THIS(iface);
53     return IHTMLDocument2_AddRef(HTMLDOC(This));
54 }
55
56 static ULONG WINAPI HlinkTarget_Release(IHlinkTarget *iface)
57 {
58     HTMLDocument *This = HLINKTRG_THIS(iface);
59     return IHTMLDocument2_Release(HTMLDOC(This));
60 }
61
62 static HRESULT WINAPI HlinkTarget_SetBrowseContext(IHlinkTarget *iface, IHlinkBrowseContext *pihlbc)
63 {
64     HTMLDocument *This = HLINKTRG_THIS(iface);
65     FIXME("(%p)->(%p)\n", This, pihlbc);
66     return E_NOTIMPL;
67 }
68
69 static HRESULT WINAPI HlinkTarget_GetBrowseContext(IHlinkTarget *iface, IHlinkBrowseContext **ppihlbc)
70 {
71     HTMLDocument *This = HLINKTRG_THIS(iface);
72     FIXME("(%p)->(%p)\n", This, ppihlbc);
73     return E_NOTIMPL;
74 }
75
76 static HRESULT WINAPI HlinkTarget_Navigate(IHlinkTarget *iface, DWORD grfHLNF, LPCWSTR pwzJumpLocation)
77 {
78     HTMLDocument *This = HLINKTRG_THIS(iface);
79
80     TRACE("(%p)->(%08x %s)\n", This, grfHLNF, debugstr_w(pwzJumpLocation));
81
82     if(grfHLNF)
83         FIXME("Unsupported grfHLNF=%08x\n", grfHLNF);
84     if(pwzJumpLocation)
85         FIXME("JumpLocation not supported\n");
86
87     return IOleObject_DoVerb(OLEOBJ(This), OLEIVERB_SHOW, NULL, NULL, -1, NULL, NULL);
88 }
89
90 static HRESULT WINAPI HlinkTarget_GetMoniker(IHlinkTarget *iface, LPCWSTR pwzLocation, DWORD dwAssign,
91         IMoniker **ppimkLocation)
92 {
93     HTMLDocument *This = HLINKTRG_THIS(iface);
94     FIXME("(%p)->(%s %08x %p)\n", This, debugstr_w(pwzLocation), dwAssign, ppimkLocation);
95     return E_NOTIMPL;
96 }
97
98 static HRESULT WINAPI HlinkTarget_GetFriendlyName(IHlinkTarget *iface, LPCWSTR pwzLocation,
99         LPWSTR *ppwzFriendlyName)
100 {
101     HTMLDocument *This = HLINKTRG_THIS(iface);
102     FIXME("(%p)->(%s %p)\n", This, debugstr_w(pwzLocation), ppwzFriendlyName);
103     return E_NOTIMPL;
104 }
105
106 static const IHlinkTargetVtbl HlinkTargetVtbl = {
107     HlinkTarget_QueryInterface,
108     HlinkTarget_AddRef,
109     HlinkTarget_Release,
110     HlinkTarget_SetBrowseContext,
111     HlinkTarget_GetBrowseContext,
112     HlinkTarget_Navigate,
113     HlinkTarget_GetMoniker,
114     HlinkTarget_GetFriendlyName
115 };
116
117 void HTMLDocument_Hlink_Init(HTMLDocument *This)
118 {
119     This->lpHlinkTargetVtbl = &HlinkTargetVtbl;
120 }
121
122 typedef struct {
123     const IHlinkVtbl  *lpHlinkVtbl;
124
125     LONG ref;
126
127     IMoniker *mon;
128     LPWSTR location;
129 } Hlink;
130
131 #define HLINK(x)  ((IHlink*)  &(x)->lpHlinkVtbl)
132
133 #define HLINK_THIS(iface) DEFINE_THIS(Hlink, Hlink, iface)
134
135 static HRESULT WINAPI Hlink_QueryInterface(IHlink *iface, REFIID riid, void **ppv)
136 {
137     Hlink *This = HLINK_THIS(iface);
138
139     *ppv = NULL;
140
141     if(IsEqualGUID(&IID_IUnknown, riid)) {
142         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
143         *ppv = HLINK(This);
144     }else if(IsEqualGUID(&IID_IHlink, riid)) {
145         TRACE("(%p)->(IID_IHlink %p)\n", This, ppv);
146         *ppv = HLINK(This);
147     }
148
149     if(*ppv) {
150         IHlink_AddRef(HLINK(This));
151         return S_OK;
152     }
153
154     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
155     return E_NOINTERFACE;
156 }
157
158 static ULONG WINAPI Hlink_AddRef(IHlink *iface)
159 {
160     Hlink *This = HLINK_THIS(iface);
161     LONG ref = InterlockedIncrement(&This->ref);
162
163     TRACE("(%p) ref=%d\n", This, ref);
164
165     return ref;
166 }
167
168 static ULONG WINAPI Hlink_Release(IHlink *iface)
169 {
170     Hlink *This = HLINK_THIS(iface);
171     LONG ref = InterlockedDecrement(&This->ref);
172
173     TRACE("(%p) ref=%d\n", This, ref);
174
175     if(!ref) {
176         if(This->mon)
177             IMoniker_Release(This->mon);
178         mshtml_free(This->location);
179         mshtml_free(This);
180     }
181
182     return ref;
183 }
184
185 static HRESULT WINAPI Hlink_SetHlinkSite(IHlink *iface, IHlinkSite *pihlSite, DWORD dwSiteData)
186 {
187     Hlink *This = HLINK_THIS(iface);
188     FIXME("(%p)->(%p %d)\n", This, pihlSite, dwSiteData);
189     return E_NOTIMPL;
190 }
191
192 static HRESULT WINAPI Hlink_GetHlinkSite(IHlink *iface, IHlinkSite **ppihlSite,
193                                          DWORD *pdwSiteData)
194 {
195     Hlink *This = HLINK_THIS(iface);
196
197     TRACE("(%p)->(%p %p)\n", This, ppihlSite, pdwSiteData);
198
199     *ppihlSite = NULL;
200     return S_OK;
201 }
202
203 static HRESULT WINAPI Hlink_SetMonikerReference(IHlink *iface, DWORD grfHLSETF,
204                                                 IMoniker *pimkTarget, LPCWSTR pwzLocation)
205 {
206     Hlink *This = HLINK_THIS(iface);
207
208     TRACE("(%p)->(%08x %p %s)\n", This, grfHLSETF, pimkTarget, debugstr_w(pwzLocation));
209
210     if(grfHLSETF)
211         FIXME("unsupported grfHLSETF=%08x\n", grfHLSETF);
212
213     if(This->mon)
214         IMoniker_Release(This->mon);
215     mshtml_free(This->location);
216
217     if(pimkTarget)
218         IMoniker_AddRef(pimkTarget);
219     This->mon = pimkTarget;
220
221     if(pwzLocation) {
222         DWORD len = strlenW(pwzLocation)+1;
223
224         This->location = mshtml_alloc(len*sizeof(WCHAR));
225         memcpy(This->location, pwzLocation, len*sizeof(WCHAR));
226     }else {
227         This->location = NULL;
228     }
229
230     return S_OK;
231 }
232
233 static HRESULT WINAPI Hlink_GetMonikerReference(IHlink *iface, DWORD dwWhichRef,
234                                                 IMoniker **ppimkTarget, LPWSTR *ppwzLocation)
235 {
236     Hlink *This = HLINK_THIS(iface);
237
238     TRACE("(%p)->(%d %p %p)\n", This, dwWhichRef, ppimkTarget, ppwzLocation);
239
240     if(dwWhichRef != 1)
241         FIXME("upsupported dwWhichRef = %d\n", dwWhichRef);
242
243     if(This->mon)
244         IMoniker_AddRef(This->mon);
245     *ppimkTarget = This->mon;
246
247     if(This->location) {
248         DWORD len = strlenW(This->location)+1;
249
250         *ppwzLocation = CoTaskMemAlloc(len*sizeof(WCHAR));
251         memcpy(*ppwzLocation, This->location, len*sizeof(WCHAR));
252     }else {
253         *ppwzLocation = NULL;
254     }
255
256     return S_OK;
257 }
258
259 static HRESULT WINAPI Hlink_SetStringReference(IHlink *iface, DWORD grfHLSETF,
260                                                LPCWSTR pwzTarget, LPCWSTR pwzLocation)
261 {
262     Hlink *This = HLINK_THIS(iface);
263     FIXME("(%p)->(%08x %s %s)\n", This, grfHLSETF, debugstr_w(pwzTarget),
264           debugstr_w(pwzLocation));
265     return E_NOTIMPL;
266 }
267
268 static HRESULT WINAPI Hlink_GetStringReference(IHlink *iface, DWORD dwWhichRef,
269                                                LPWSTR *ppwzTarget, LPWSTR *ppwzLocation)
270 {
271     Hlink *This = HLINK_THIS(iface);
272     FIXME("(%p)->(%d %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation);
273     return E_NOTIMPL;
274 }
275
276 static HRESULT WINAPI Hlink_SetFriendlyName(IHlink *iface, LPCWSTR pwzFriendlyName)
277 {
278     Hlink *This = HLINK_THIS(iface);
279     FIXME("(%p)->(%s)\n", This, debugstr_w(pwzFriendlyName));
280     return E_NOTIMPL;
281 }
282
283 static HRESULT WINAPI Hlink_GetFriendlyName(IHlink *iface, DWORD grfHLNAMEF,
284                                             LPWSTR *ppwzFriendlyName)
285 {
286     Hlink *This = HLINK_THIS(iface);
287
288     TRACE("(%p)->(%08x %p)\n", This, grfHLNAMEF, ppwzFriendlyName);
289
290     *ppwzFriendlyName = NULL;
291     return S_FALSE;
292 }
293
294 static HRESULT WINAPI Hlink_SetTargetFrameName(IHlink *iface, LPCWSTR pwzTargetFrameName)
295 {
296     Hlink *This = HLINK_THIS(iface);
297     FIXME("(%p)->(%s)\n", This, debugstr_w(pwzTargetFrameName));
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI Hlink_GetTargetFrameName(IHlink *iface, LPWSTR *ppwzTargetFrameName)
302 {
303     Hlink *This = HLINK_THIS(iface);
304
305     TRACE("(%p)->(%p)\n", This, ppwzTargetFrameName);
306
307     *ppwzTargetFrameName = NULL;
308     return S_FALSE;
309 }
310
311 static HRESULT WINAPI Hlink_GetMiscStatus(IHlink *iface, DWORD *pdwStatus)
312 {
313     Hlink *This = HLINK_THIS(iface);
314     FIXME("(%p)->(%p)\n", This, pdwStatus);
315     return E_NOTIMPL;
316 }
317
318 static HRESULT WINAPI Hlink_Navigate(IHlink *iface, DWORD grfHLNF, LPBC pibc,
319         IBindStatusCallback *pibsc, IHlinkBrowseContext *pihlbc)
320 {
321     Hlink *This = HLINK_THIS(iface);
322     FIXME("(%p)->(%08x %p %p %p)\n", This, grfHLNF, pibc, pibsc, pihlbc);
323     return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI Hlink_SetAdditionalParams(IHlink *iface, LPCWSTR pwzAdditionalParams)
327 {
328     Hlink *This = HLINK_THIS(iface);
329     FIXME("(%p)->(%s)\n", This, debugstr_w(pwzAdditionalParams));
330     return E_NOTIMPL;
331 }
332
333 static HRESULT WINAPI Hlink_GetAdditionalParams(IHlink *iface, LPWSTR *ppwzAdditionalParams)
334 {
335     Hlink *This = HLINK_THIS(iface);
336     FIXME("(%p)->(%p)\n", This, ppwzAdditionalParams);
337     return E_NOTIMPL;
338 }
339
340 #undef HLINK_THIS
341
342 static const IHlinkVtbl HlinkVtbl = {
343     Hlink_QueryInterface,
344     Hlink_AddRef,
345     Hlink_Release,
346     Hlink_SetHlinkSite,
347     Hlink_GetHlinkSite,
348     Hlink_SetMonikerReference,
349     Hlink_GetMonikerReference,
350     Hlink_SetStringReference,
351     Hlink_GetStringReference,
352     Hlink_SetFriendlyName,
353     Hlink_GetFriendlyName,
354     Hlink_SetTargetFrameName,
355     Hlink_GetTargetFrameName,
356     Hlink_GetMiscStatus,
357     Hlink_Navigate,
358     Hlink_SetAdditionalParams,
359     Hlink_GetAdditionalParams
360 };
361
362 IHlink *Hlink_Create(void)
363 {
364     Hlink *ret = mshtml_alloc(sizeof(Hlink));
365
366     ret->lpHlinkVtbl = &HlinkVtbl;
367     ret->ref = 1;
368     ret->mon = NULL;
369     ret->location = NULL;
370
371     return HLINK(ret);
372 }