Unicodify wineesd.
[wine] / dlls / mshtml / persist.c
1 /*
2  * Copyright 2005 Jacek Caban
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 #include "docobj.h"
31
32 #include "mshtml.h"
33 #include "mshtmhst.h"
34
35 #include "wine/debug.h"
36
37 #include "mshtml_private.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
40
41 struct BindStatusCallback {
42     const IBindStatusCallbackVtbl *lpBindStatusCallbackVtbl;
43     
44     LONG ref;
45
46     HTMLDocument *doc;
47     IBinding *binding;
48 };
49
50 #define STATUSCLB_THIS(iface) DEFINE_THIS(BindStatusCallback, BindStatusCallback, iface)
51
52 static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
53         REFIID riid, void **ppv)
54 {
55     BindStatusCallback *This = STATUSCLB_THIS(iface);
56
57     *ppv = NULL;
58     if(IsEqualGUID(&IID_IUnknown, riid)) {
59         TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
60         *ppv = STATUSCLB(This);
61     }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
62         TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv);
63         *ppv = STATUSCLB(This);
64     }
65
66     if(*ppv) {
67         IBindStatusCallback_AddRef(STATUSCLB(This));
68         return S_OK;
69     }
70
71     TRACE("Unsupported riid = %s\n", debugstr_guid(riid));
72     return E_NOINTERFACE;
73 }
74
75 static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
76 {
77     BindStatusCallback *This = STATUSCLB_THIS(iface);
78     LONG ref = InterlockedIncrement(&This->ref);
79
80     TRACE("(%p) ref = %ld\n", This, ref);
81
82     return ref;
83 }
84
85 static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
86 {
87     BindStatusCallback *This = STATUSCLB_THIS(iface);
88     LONG ref = InterlockedDecrement(&This->ref);
89
90     TRACE("(%p) ref = %ld\n", This, ref);
91
92     if(!ref) {
93         if(This->doc->status_callback == This)
94             This->doc->status_callback = NULL;
95         IHTMLDocument2_Release(HTMLDOC(This->doc));
96         HeapFree(GetProcessHeap(), 0, This);
97     }
98
99     return ref;
100 }
101
102 static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
103         DWORD dwReserved, IBinding *pbind)
104 {
105     BindStatusCallback *This = STATUSCLB_THIS(iface);
106
107     TRACE("(%p)->(%ld %p)\n", This, dwReserved, pbind);
108
109     This->binding = pbind;
110     IBinding_AddRef(pbind);
111
112     return S_OK;
113 }
114
115 static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
116 {
117     BindStatusCallback *This = STATUSCLB_THIS(iface);
118     FIXME("(%p)->(%p)\n", This, pnPriority);
119     return E_NOTIMPL;
120 }
121
122 static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
123 {
124     BindStatusCallback *This = STATUSCLB_THIS(iface);
125     FIXME("(%p)->(%ld)\n", This, reserved);
126     return E_NOTIMPL;
127 }
128
129 static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
130         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
131 {
132     BindStatusCallback *This = STATUSCLB_THIS(iface);
133     TRACE("%p)->(%lu %lu %lu %s)\n", This, ulProgress, ulProgressMax, ulStatusCode,
134             debugstr_w(szStatusText));
135     return S_OK;
136 }
137
138 static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface,
139         HRESULT hresult, LPCWSTR szError)
140 {
141     BindStatusCallback *This = STATUSCLB_THIS(iface);
142
143     TRACE("(%p)->(%08lx %s)\n", This, hresult, debugstr_w(szError));
144
145     IBinding_Release(This->binding);
146     This->binding = NULL;
147     return S_OK;
148 }
149
150 static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
151         DWORD *grfBINDF, BINDINFO *pbindinfo)
152 {
153     BindStatusCallback *This = STATUSCLB_THIS(iface);
154     DWORD size;
155
156     TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo);
157
158     *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
159     size = pbindinfo->cbSize;
160     memset(pbindinfo, 0, size);
161     pbindinfo->cbSize = size;
162
163     return S_OK;
164 }
165
166 static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface,
167         DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
168 {
169     BindStatusCallback *This = STATUSCLB_THIS(iface);
170     TRACE("(%p)->(%08lx %ld %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
171     return S_OK;
172 }
173
174 static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
175         REFIID riid, IUnknown *punk)
176 {
177     BindStatusCallback *This = STATUSCLB_THIS(iface);
178     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk);
179     return E_NOTIMPL;
180 }
181
182 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
183     BindStatusCallback_QueryInterface,
184     BindStatusCallback_AddRef,
185     BindStatusCallback_Release,
186     BindStatusCallback_OnStartBinding,
187     BindStatusCallback_GetPriority,
188     BindStatusCallback_OnLowResource,
189     BindStatusCallback_OnProgress,
190     BindStatusCallback_OnStopBinding,
191     BindStatusCallback_GetBindInfo,
192     BindStatusCallback_OnDataAvailable,
193     BindStatusCallback_OnObjectAvailable
194 };
195
196 static BindStatusCallback *BindStatusCallback_Create(HTMLDocument *doc)
197 {
198     BindStatusCallback *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(BindStatusCallback));
199     ret->lpBindStatusCallbackVtbl = &BindStatusCallbackVtbl;
200     ret->ref = 0;
201     ret->doc = doc;
202     IHTMLDocument2_AddRef(HTMLDOC(doc));
203     return ret;
204 }
205
206 /**********************************************************
207  * IPersistMoniker implementation
208  */
209
210 #define PERSISTMON_THIS(iface) DEFINE_THIS(HTMLDocument, PersistMoniker, iface)
211
212 static HRESULT WINAPI PersistMoniker_QueryInterface(IPersistMoniker *iface, REFIID riid,
213                                                             void **ppvObject)
214 {
215     HTMLDocument *This = PERSISTMON_THIS(iface);
216     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
217 }
218
219 static ULONG WINAPI PersistMoniker_AddRef(IPersistMoniker *iface)
220 {
221     HTMLDocument *This = PERSISTMON_THIS(iface);
222     return IHTMLDocument2_AddRef(HTMLDOC(This));
223 }
224
225 static ULONG WINAPI PersistMoniker_Release(IPersistMoniker *iface)
226 {
227     HTMLDocument *This = PERSISTMON_THIS(iface);
228     return IHTMLDocument2_Release(HTMLDOC(This));
229 }
230
231 static HRESULT WINAPI PersistMoniker_GetClassID(IPersistMoniker *iface, CLSID *pClassID)
232 {
233     HTMLDocument *This = PERSISTMON_THIS(iface);
234     return IPersist_GetClassID(PERSIST(This), pClassID);
235 }
236
237 static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface)
238 {
239     HTMLDocument *This = PERSISTMON_THIS(iface);
240     FIXME("(%p)\n", This);
241     return E_NOTIMPL;
242 }
243
244 static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable,
245         IMoniker *pimkName, LPBC pibc, DWORD grfMode)
246 {
247     HTMLDocument *This = PERSISTMON_THIS(iface);
248     IBindCtx *pbind;
249     BindStatusCallback *callback;
250     IStream *str;
251     LPWSTR url;
252     HRESULT hres;
253     nsresult nsres;
254
255     FIXME("(%p)->(%x %p %p %08lx)\n", This, fFullyAvailable, pimkName, pibc, grfMode);
256
257     /* FIXME:
258      * This is a HACK, we should use moniker's BindToStorage instead of Gecko's LoadURI.
259      */
260     if(This->nscontainer) {
261         hres = IMoniker_GetDisplayName(pimkName, pibc, NULL, &url);
262         if(FAILED(hres)) {
263             WARN("GetDiaplayName failed: %08lx\n", hres);
264             return hres;
265         }
266         TRACE("got url: %s\n", debugstr_w(url));
267
268         nsres = nsIWebNavigation_LoadURI(This->nscontainer->navigation, url,
269                 LOAD_FLAGS_NONE, NULL, NULL, NULL);
270         if(NS_SUCCEEDED(nsres))
271             return S_OK;
272         else
273             WARN("LoadURI failed: %08lx\n", nsres);
274     }    
275
276     /* FIXME: Use grfMode */
277
278     if(fFullyAvailable)
279         FIXME("not supported fFullyAvailable\n");
280     if(pibc)
281         FIXME("not supported pibc\n");
282
283     if(This->status_callback && This->status_callback->binding)
284         IBinding_Abort(This->status_callback->binding);
285
286     callback = This->status_callback = BindStatusCallback_Create(This);
287
288     CreateAsyncBindCtx(0, STATUSCLB(callback), NULL, &pbind);
289
290     hres = IMoniker_BindToStorage(pimkName, pbind, NULL, &IID_IStream, (void**)&str);
291     if(str)
292         IStream_Release(str);
293     if(FAILED(hres)) {
294         WARN("BindToStorage failed: %08lx\n", hres);
295         return hres;
296     }
297
298     return S_OK;
299 }
300
301 static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName,
302         LPBC pbc, BOOL fRemember)
303 {
304     HTMLDocument *This = PERSISTMON_THIS(iface);
305     FIXME("(%p)->(%p %p %x)\n", This, pimkName, pbc, fRemember);
306     return E_NOTIMPL;
307 }
308
309 static HRESULT WINAPI PersistMoniker_SaveCompleted(IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
310 {
311     HTMLDocument *This = PERSISTMON_THIS(iface);
312     FIXME("(%p)->(%p %p)\n", This, pimkName, pibc);
313     return E_NOTIMPL;
314 }
315
316 static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoniker **ppimkName)
317 {
318     HTMLDocument *This = PERSISTMON_THIS(iface);
319     FIXME("(%p)->(%p)\n", This, ppimkName);
320     return E_NOTIMPL;
321 }
322
323 static const IPersistMonikerVtbl PersistMonikerVtbl = {
324     PersistMoniker_QueryInterface,
325     PersistMoniker_AddRef,
326     PersistMoniker_Release,
327     PersistMoniker_GetClassID,
328     PersistMoniker_IsDirty,
329     PersistMoniker_Load,
330     PersistMoniker_Save,
331     PersistMoniker_SaveCompleted,
332     PersistMoniker_GetCurMoniker
333 };
334
335 /**********************************************************
336  * IMonikerProp implementation
337  */
338
339 #define MONPROP_THIS(iface) DEFINE_THIS(HTMLDocument, MonikerProp, iface)
340
341 static HRESULT WINAPI MonikerProp_QueryInterface(IMonikerProp *iface, REFIID riid, void **ppvObject)
342 {
343     HTMLDocument *This = MONPROP_THIS(iface);
344     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
345 }
346
347 static ULONG WINAPI MonikerProp_AddRef(IMonikerProp *iface)
348 {
349     HTMLDocument *This = MONPROP_THIS(iface);
350     return IHTMLDocument2_AddRef(HTMLDOC(This));
351 }
352
353 static ULONG WINAPI MonikerProp_Release(IMonikerProp *iface)
354 {
355     HTMLDocument *This = MONPROP_THIS(iface);
356     return IHTMLDocument_Release(HTMLDOC(This));
357 }
358
359 static HRESULT WINAPI MonikerProp_PutProperty(IMonikerProp *iface, MONIKERPROPERTY mkp, LPCWSTR val)
360 {
361     HTMLDocument *This = MONPROP_THIS(iface);
362     FIXME("(%p)->(%d %s)\n", This, mkp, debugstr_w(val));
363     return E_NOTIMPL;
364 }
365
366 static const IMonikerPropVtbl MonikerPropVtbl = {
367     MonikerProp_QueryInterface,
368     MonikerProp_AddRef,
369     MonikerProp_Release,
370     MonikerProp_PutProperty
371 };
372
373 /**********************************************************
374  * IPersistFile implementation
375  */
376
377 #define PERSISTFILE_THIS(iface) DEFINE_THIS(HTMLDocument, PersistFile, iface)
378
379 static HRESULT WINAPI PersistFile_QueryInterface(IPersistFile *iface, REFIID riid, void **ppvObject)
380 {
381     HTMLDocument *This = PERSISTFILE_THIS(iface);
382     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppvObject);
383 }
384
385 static ULONG WINAPI PersistFile_AddRef(IPersistFile *iface)
386 {
387     HTMLDocument *This = PERSISTFILE_THIS(iface);
388     return IHTMLDocument2_AddRef(HTMLDOC(This));
389 }
390
391 static ULONG WINAPI PersistFile_Release(IPersistFile *iface)
392 {
393     HTMLDocument *This = PERSISTFILE_THIS(iface);
394     return IHTMLDocument2_Release(HTMLDOC(This));
395 }
396
397 static HRESULT WINAPI PersistFile_GetClassID(IPersistFile *iface, CLSID *pClassID)
398 {
399     HTMLDocument *This = PERSISTFILE_THIS(iface);
400
401     TRACE("(%p)->(%p)\n", This, pClassID);
402
403     if(!pClassID)
404         return E_INVALIDARG;
405
406     memcpy(pClassID, &CLSID_HTMLDocument, sizeof(CLSID));
407     return S_OK;
408 }
409
410 static HRESULT WINAPI PersistFile_IsDirty(IPersistFile *iface)
411 {
412     HTMLDocument *This = PERSISTFILE_THIS(iface);
413     FIXME("(%p)\n", This);
414     return E_NOTIMPL;
415 }
416
417 static HRESULT WINAPI PersistFile_Load(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
418 {
419     HTMLDocument *This = PERSISTFILE_THIS(iface);
420     FIXME("(%p)->(%s %08lx)\n", This, debugstr_w(pszFileName), dwMode);
421     return E_NOTIMPL;
422 }
423
424 static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileName, BOOL fRemember)
425 {
426     HTMLDocument *This = PERSISTFILE_THIS(iface);
427     FIXME("(%p)->(%s %x)\n", This, debugstr_w(pszFileName), fRemember);
428     return E_NOTIMPL;
429 }
430
431 static HRESULT WINAPI PersistFile_SaveCompleted(IPersistFile *iface, LPCOLESTR pszFileName)
432 {
433     HTMLDocument *This = PERSISTFILE_THIS(iface);
434     FIXME("(%p)->(%s)\n", This, debugstr_w(pszFileName));
435     return E_NOTIMPL;
436 }
437
438 static HRESULT WINAPI PersistFile_GetCurFile(IPersistFile *iface, LPOLESTR *pszFileName)
439 {
440     HTMLDocument *This = PERSISTFILE_THIS(iface);
441     FIXME("(%p)->(%p)\n", This, pszFileName);
442     return E_NOTIMPL;
443 }
444
445 static const IPersistFileVtbl PersistFileVtbl = {
446     PersistFile_QueryInterface,
447     PersistFile_AddRef,
448     PersistFile_Release,
449     PersistFile_GetClassID,
450     PersistFile_IsDirty,
451     PersistFile_Load,
452     PersistFile_Save,
453     PersistFile_SaveCompleted,
454     PersistFile_GetCurFile
455 };
456
457 void HTMLDocument_Persist_Init(HTMLDocument *This)
458 {
459     This->lpPersistMonikerVtbl = &PersistMonikerVtbl;
460     This->lpPersistFileVtbl = &PersistFileVtbl;
461     This->lpMonikerPropVtbl = &MonikerPropVtbl;
462
463     This->status_callback = NULL;
464 }